可观察与未来表现

时间:2015-03-20 09:18:11

标签: performance scala asynchronous future rx-scala

我正在使用Vert.x 2.x(http://vertx.io),它广泛使用异步回调。对于典型的嵌套/回调地狱问题,这些很快变得难以处理。

我已经考虑了Scala Futures / Promises(我认为这将是事实上的方法)以及Reactive Extensions(RxScala)。

从我的测试中我发现了一些有趣的性能结果。

我的测试非常基本,我只是向Vert.x Verticle发出一堆HTTP请求(通过weighttp),它在Vert.x事件总线上进行异步调用,然后处理响应,然后返回HTTP 200响应。

我发现以下内容(这里的性能是根据每秒的HTTP请求来衡量的):

  • 异步回拨性能= 68,305 rps
  • Rx表现= 64,656 rps
  • 未来/承诺表现= 61,376 rps

测试条件是:

  • Mac Pro OS X Yosemite 10.10.2
  • Oracle JVM 1.8U25
  • weighttp version 0.3
  • Vert.x 2.1.5
  • Scala 2.10.4
  • RxScala 0.23.0
  • 4 x Web服务Verticle实例
  • 4 x后端服务Verticle实例

测试命令是

weighttp -n 1000000 -c 128 -7 8 -k "localhost:8888"

以上数据是五次试运行的平均值,而不是最佳和最差结果。请注意,结果在呈现的平均值附近非常一致(不超过几百rps的偏差)。

是否有任何已知原因导致上述情况发生 - 即Rx>每秒纯粹请求的期货?

我认为反应性扩展是优越的,因为他们可以做得更多,但鉴于异步回调的标准方法通常似乎在期货/承诺轨道上下降,我对性能损失感到惊讶。

编辑:这是Web服务Verticle

class WebVerticle extends Verticle {
  override def start() {
    val port = container.env().getOrElse("HTTP_PORT", "8888").toInt
    val approach = container.env().getOrElse("APPROACH", "ASYNC")
    container.logger.info("Listening on port: " + port)
    container.logger.info("Using approach: " + approach)

    vertx.createHttpServer.requestHandler { req: HttpServerRequest =>
      approach match {
        case "ASYNC" => sendAsync(req, "hello")
        case "FUTURES" => sendWithFuture("hello").onSuccess { case body => req.response.end(body) }
        case "RX" => sendWithObservable("hello").doOnNext(req.response.end(_)).subscribe()
      }
    }.listen(port)
  }

  // Async callback
  def sendAsync(req: HttpServerRequest, body: String): Unit = {
    vertx.eventBus.send("service.verticle", body, { msg: Message[String] =>
      req.response.end(msg.body())
    })
  }

  // Rx 
  def sendWithObservable(body: String) : Observable[String] = {
    val subject = ReplaySubject[String]()
    vertx.eventBus.send("service.verticle", body, { msg: Message[String] =>
      subject.onNext(msg.body())
      subject.onCompleted()
    })
    subject
  }

  // Futures    
  def sendWithFuture(body: String) : Future[String] = {
    val promise = Promise[String]()
    vertx.eventBus.send("service.verticle", body, { msg: Message[String] =>
      promise.success(msg.body())
    })
    promise.future
  }
}

编辑:这是后端Verticle

class ServiceVerticle extends Verticle {
  override def start(): Unit = {
    vertx.eventBus.registerHandler("service.verticle", { msg: Message[String] =>
      msg.reply("Hello Scala")
    })
  }
}

0 个答案:

没有答案