Akka-Http Rest针对.NET Web API实现的服务性能

时间:2018-02-02 14:02:32

标签: akka akka-http

因此,我们在我们的环境中托管了一个在.NET Web API中实现的REST API。 我目前正致力于在Akka Http中实现PoC的一些部分,以展示我们从反应范式中获得的一些性能优势,而不是当前的WEB API安装。

我已经实现了一个带有几个接口和一些数据库集成(CRUD)的短POC。

我想弄清楚我应该展示什么东西,以便清楚地显示性能上的差异。

说每个请求处理的Akka HTTP是一个actor是否正确,而不是ASP.NET Web API或Spring等传统框架的每个请求的线程?

更新:

这就是我的服务器代码,

implicit val blockingDispatcher = system.dispatchers.lookup("my-blocking-
dispatcher")
    val agentRoute1 = get {
        pathPrefix("agentStream" / Segment) {
          applicationName =>

            val futuredataListbyStream: Future[Try[Source[Any,NotUsed]]] = Future {
                                 DatabaseProcedure.getDataAsStream(paramName)                                                                                             
}
             onComplete(futuredataListbyStream) {
                                                       case Success(triedResultsSet) =>
                                                         triedResultsSet match{
                                                           case Success(srcStream) =>  
                                                             srcStream.map(x => System.out.println(x.asInstanceOf[String]))

                                                             complete(StatusCodes.OK, "Gotten the data . Return is " + srcStream)
                                                           case Failure(ex) => complete(StatusCodes.InternalServerError, "Something went wrong here in the rseultset" + ex.getMessage)
                                                         }
                                                         case Failure(ex)    => complete(StatusCodes.InternalServerError, "Something went wrong in procedure execution" + ex.getMessage)
        }
       }
      }

数据库调用代码如下所示,

def getdataAsStream(paramName: String):Try[Source[Any,NotUsed]] = {
    entityManager.getTransaction().begin()
    System.out.println("In blocking db call"+paramName)

    val query: StoredProcedureQuery = entityManager.createStoredProcedureQuery("procedure_name")
      .registerStoredProcedureParameter(1, classOf[String],
        ParameterMode.IN)
      .registerStoredProcedureParameter(2, classOf[String],
        ParameterMode.IN)
      .registerStoredProcedureParameter(3, classOf[Class[_]],
        ParameterMode.REF_CURSOR)
      .setParameter(1,"test")
      .setParameter(2,paramName)

    entityManager.close()


    return Try {
      query.execute
      val list = query.getResultList.asScala.toList
      Source.apply(list)
    }
  }

1 个答案:

答案 0 :(得分:1)

为了获得最佳性能,我发现了一些“技巧”是必要的:

  1. 块大小:如果您在HttpEntity.Chunked中使用ResponseEntity作为HttpResponse,则调整块的大小。太多的小块可能会降低性能。如果您知道响应实体总是相对较小,那么您可能希望默认使用Strict响应实体。
  2. 异步边界:如果您为传入请求提供服务的操作不会从多个参与者那里获益,例如:很多IO等待,那么你可能想要坚持1个异步边界而不是多个。因此,请使用Flow[HttpRequest].map(...).map(...)代替Flow[HttpRequest].via(Flow...).via(Flow...)
  3. 根据请求回答关于Actors的问题:

    如果你根据我的建议使用1个异步边界,那么是的,你将每个请求使用~1个actor而不是1个线程。

    回答关于展示的问题:

    我认为使用akka作为Web服务的最佳部分之一是,如果您一直使用反应流,那么每个请求的内存使用量&每个连接可以保持不变。因此,如果您使用流来从数据库集成中获取数据,那么返回无限行数的客户端查询将仅消耗服务中的恒定内存量。这对于有效利用每个请求的内存非常有用。

    总是可以调整Web框架,使其更具性能,但在反应流之外很难让您的客户发送他们想要的任何请求,而不必担心内存不足异常。