喷射Scala构建非阻塞Servlet

3

我使用Spray和Akka Actor构建了一个Scala应用程序。

我的问题是请求是同步的,服务器无法同时处理多个请求。

这是正常行为吗?我该如何避免这种情况发生?

以下是我的启动代码:

object Boot extends App with Configuration {

  // create an actor system for application
  implicit val system = ActorSystem("my-service")
//context.actorOf(RoundRobinPool(5).props(Props[TestActor]), "router")
  // create and start property service actor
  val RESTService = system.actorOf(Props[RESTServiceActor], "my-endpoint")

  // start HTTP server with property service actor as a handler
  IO(Http) ! Http.Bind(RESTService, serviceHost, servicePort)
}

演员代码:
class RESTServiceActor extends Actor 
                            with RESTService  {
  implicit def actorRefFactory = context

  def receive = runRoute(rest)
}



trait RESTService extends HttpService  with SLF4JLogging{
  val myDAO = new MyDAO



  val AccessControlAllowAll = HttpHeaders.RawHeader(
    "Access-Control-Allow-Origin", "*"
  )
  val AccessControlAllowHeadersAll = HttpHeaders.RawHeader(
    "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"
  )
  val rest =  respondWithHeaders(AccessControlAllowAll, AccessControlAllowHeadersAll) { 
    respondWithMediaType(MediaTypes.`application/json`){
      options {
            complete {
              ""
            }
          } ~
      path("some"/"path"){
         get {
            parameter('parameter){ (parameter) => 
              ctx: RequestContext =>
                    handleRequest(ctx) {
                      myDAO.getResult(parmeter)
                    }
            }
          }
        } 
    }
  }

    /**
   * Handles an incoming request and create valid response for it.
   *
   * @param ctx         request context
   * @param successCode HTTP Status code for success
   * @param action      action to perform
   */
  protected def handleRequest(ctx: RequestContext, successCode: StatusCode = StatusCodes.OK)(action: => Either[Failure, _]) {
    action match {
      case Right(result: Object) =>
        println(result)
        ctx.complete(successCode,result.toString())
      case Left(error: Failure) =>
      case _ =>
        ctx.complete(StatusCodes.InternalServerError)
    }
  }
}

我看到了这样一段话:

Akka Mist非常适合在Scala中构建RESTful Web服务,因为它将良好的可扩展性(通过异步、非阻塞特性实现)与轻量级结合在了一起。

这是我需要的吗?spray是否默认使用它或者我需要添加它,该怎么做呢?

我有点困惑。任何帮助都将不胜感激。

2个回答

1
而不是将结果发送到complete方法中:
ctx.complete(successCode,result.toString())

我使用了future method:
import concurrent.Future
import concurrent.ExecutionContext.Implicits.global

ctx.complete(successCode,Future(Option(result.toString())))

大多数人会在他们的原始帖子中添加一个“更新”部分,以便当贡献者将其引导到那里时,他们会对“不接受”感到惊讶。 - Brian Topping

1
如果您从零开始,我建议使用Akka HTTP,文档位于http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0-M4/scala/http/。它是Spray的一个端口,但使用Akka Streams,这对于以后的开发非常重要。
至于使您的代码完全异步,关键模式是返回一个Future到您的结果,而不是实际数据本身。换句话说,RESTServiceActor应该返回一个Future来返回数据,而不是实际数据。这将允许Spray / Akka HTTP接受其他连接,并且服务actor的异步完成将在完成时返回结果。

你能展示一下如何根据我的服务actor代码返回一个Future吗?(问题中包含) - griffon vulture
在这段代码中,myDAO.getResult(parmeter)是实际执行工作的部分。假设您正在使用类似于spray-json的东西来序列化结果,您将需要使用Future { myDAO.getResult(parmeter) }调用ctx.complete()。您需要处理错误,例如使用http://www.superloopy.io/articles/2013/spray-routing-error-handling.html中显示的模式。 - Brian Topping
1
Akka HTTP没有被标记为生产就绪,因此可能不是最佳选择。 - Przemek
@Przemek:任何应用完成使用它时,它都将准备就绪。API是最终版本,这才是重要的。 - Brian Topping

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接