如何计算Akka HTTP完成HTTP请求所需的时间

时间:2017-11-07 12:37:59

标签: scala akka akka-stream akka-http

我构建了一个流,它接受一个case类(Event)并将其发送到HTTP端点并将其返回。它是这样实现的:

Flow[Event]
    .mapAsync(16)(eventToHttpRequest)
    .via(connection)
    .map(handleResponse)

供参考,这是handleResponse方法:

def handleResponse(endpoint: String)(responseTuple: (Try[HttpResponse], Event))(implicit actorSystem: ActorSystem, mat: ActorMaterializer) = {
    responseTuple match {
      case (Success(response), event) =>
        response.status.intValue() match {
          case code if code >= 500 =>
            val message = s"Server side error sending event with id ${event.id} to ingestion gateway, status : ${response.status}"
            LOG.error(message)
            response.discardEntityBytes()
            throw new UnexpectedException(message)
          case code if (code >= 400) && (code < 500) =>           
            val message = s"Bad request sending  event with id ${event.id} to ingestion gateway, status : ${response.status}"
            LOG.error(message)
            throw new UnexpectedException(message)
          case _ =>
            LOG.debug(s"Sent event with id ${event.id}, status : ${response.status}")
            response.discardEntityBytes()
            event
        }
      case (Failure(ex), justDataEvent) =>
        LOG.error(s"Could not connect to $endpoint")
        throw ex
    }
  }

我想监控HTTP请求需要多长时间。 &#34;请求需要多长时间&#34;可以被认为是:

  1. 我们返回初始标头和状态代码
  2. 的时间
  3. 我们将整个身体留在记忆中多久
  4. 在这种情况下,它们非常相似,因为响应很小,但知道如何计算两者都会很好。

1 个答案:

答案 0 :(得分:1)

对于请求响应周期,可以使用中间流来实现,该流程为http请求和事件添加开始时间:

type EventAndTime = Tuple2[Event, Long]

val addQueryTime : Tuple2[HttpRequest, Event] => Tuple2[HttpRequest, EventAndTime] = 
  (tup) => (tup._1, (tup._2, java.lang.System.currentTimeMillis()))

val addQueryTimeFlow : Flow[(HttpRequest, Event), (HttpRequest, EventAndTime),_] = 
  Flow[(HttpRequest, Event)] map addQueryTime

现在handleRequest将在完成Event之后收到conn和系统时间:

Flow[Event]
  .mapAsync(16)(eventToHttpRequest)
  .via(addQueryTimeFlow)
  .via(connection)
  .map(handleResponse)

handleRequest可以再次询问系统时间并进行差异化。

你可以用response.entity做一个类似的技巧来计算需要多长时间:

val timeout : FiniteDuration = ???

case class EntityAndTime(strict : Strict, startTime : Long, endTime : Long)

val entity = response.entity

val entityAndTime : Future[EntityAndTime] = 
  Future(System.currentTimeMillis())
  .flatMap { startTime => 
    entity
      .toStrict(timeout)
      .map { strict =>
        EntityAndTime(strict, startTime, System.currentTimeMillis())
      }
  }