代码之家  ›  专栏  ›  技术社区  ›  Magnus

如何缩放使用akka的scala rest应用程序?

  •  12
  • Magnus  · 技术社区  · 15 年前

    我有一个使用AKKA的scala应用程序,它接收REST请求,对数据库进行一些操作,并用一些信息响应客户机。实际上,我的数据库操作需要很长时间,并且我的启用了REST的参与者无法同时响应新的请求,即使我可以对数据库同时运行许多操作。我正在使用javax.ws.rs注释在我的actor中休息启用方法。

    问题是:什么是使我的应用程序能够处理大量并发请求的最佳方法?

    编辑 :我将添加一些示例代码。

      import se.scalablesolutions.akka.actor._
      import javax.ws.rs._
    
      @Path("/test")
      class TestService {
    
        @GET
        def status() = 
          actorPool !! Status(session).
            getOrElse(<error>Unable to connect to service</error>)
      }
    
      class TestActor {
    
        def receive = {
          case Status() => {
            reply(SomeObject.slowDBMethod)
          }
        }
      }
    
      case class Status()
    

    编辑2 :这就是我要记录的内容。我正在尽快地从浏览器发送这三个请求,我可以切换选项卡并按F5,但是RS bean仍然等待第一个请求完成,然后再处理下一个请求。

    [INFO] [2010-08-29 16:27:03,232] [akka:event-driven:dispatcher:global-15] c.n.StatusActor: got Slow request
    [INFO] [2010-08-29 16:27:06,916] [akka:event-driven:dispatcher:global-10] c.n.StatusActor: got Slow request
    [INFO] [2010-08-29 16:27:10,589] [akka:event-driven:dispatcher:global-3] c.n.StatusActor: got Slow request
    
    4 回复  |  直到 11 年前
        1
  •  6
  •   Garrick Evans    14 年前

    虽然我意识到这个线程现在已经过时4个多月了,但是值得注意的是AKKA有一个新的HTTP模块实现,它可以有效地将请求传输到参与者。这种方法利用异步servlet API(也与Jetty Continuations一起工作)使挂起的请求能够作为消息通过系统并在任何时候恢复;例如,消除了使用的必要性!!触发演员工作并在注释的POJO中响应。同样,由于请求被挂起在容器中,并且上下文被尽可能快地翻转到参与者中,因此没有线程阻塞来处理响应或未来。

    今天可能会改写上述示例的一种幼稚方式:

    class TestEndpoint extends Actor with Endpoint {
       def hook(uri:String) = uri == "/test"
       def provide(uri:String) = actorOf[TestService].start
    
       override def preStart = {
         ActorRegister.actorsFor[classOf[RootEndpoint]).head ! Endpoint.Attach(hook, provide)
       }
    
       def receive = handleHttpRequest
    }
    
    class TestService extends Actor {
       def receive = {
    
         case get:Get => 
           get.timeout(SomeObject.TimeoutInSeconds) // for example
           get.OK(SomeObject.slowDBMethod)
    
         case other:RequestMethod =>
          other.NotAllowed("Invalid method for this endpoint")
       }
    }
    

    更多文件可在Akka网站上找到: http://doc.akkasource.org/http

        2
  •  7
  •   Viktor Klang    15 年前

    你好像用的是老版本的阿卡。

    我建议升级到0.10(将actors和rs bean分开),然后您可以使用LoadBalancer 1 (和) 2 )限制工作负载,或利用WorkstealingDispatcher 3 (和) 4 )

    这有帮助吗?

        3
  •  3
  •   Daniel C. Sobral    15 年前

    一旦您得到一个请求,您应该创建一个新的参与者来处理该请求。传递原始发件人,以便新创建的演员知道要回答谁。

        4
  •  1
  •   Hisham    14 年前

    虽然这条线是旧的,但我想加上spiffy(plug!)混合:

    https://github.com/mardambey/spiffy

    Spiffy是什么?

    斯皮菲…

    • 是用scala写的
    • 使用神奇的阿克卡图书馆和演员来进行缩放
    • 使用servlet API 3.0处理异步请求
    • 是模块化的(更换部件是直接向前的)
    • 使用DSL减少不需要的代码
    • 支持控制器周围的请求挂钩

    Pyffy是一个使用Scala、Akka(Scala Actudio实现)和Java Servlet 3 API的Web框架。它利用异步接口,旨在为Web应用程序提供一个大规模并行和可扩展的环境。Spiffy的各种组件都基于这样一个理念:它们需要独立的极简模块,可以快速完成少量工作,并将请求传递给管道中的下一个组件。最后一个组件处理完请求后,它通过“完成”请求并将其发送回客户机来向servlet容器发送信号。