【问题标题】:Load Balancing akka-http负载均衡 akka-http
【发布时间】:2016-07-08 14:45:38
【问题描述】:


我正在使用 akka-http,我的 build.sbt 配置是:

scalaVersion := "2.11.7"
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.11" % "2.4.2"
libraryDependencies += "com.typesafe.akka" % "akka-http-experimental_2.11" % "2.4.2"
libraryDependencies += "com.typesafe.akka" % "akka-http-spray-json-experimental_2.11" % "2.4.2"
libraryDependencies += "com.typesafe.akka" % "akka-slf4j_2.11" % "2.4.2"

我正在公开一个只有一个 GET url 的简单 REST api
foo 是一个返回 Future 的函数

implicit val actorSystem = ActorSystem("system", config)
implicit val actorMaterializer = ActorMaterializer()

val route: Route = {
  get {
    path("foo") {
      complete { foo }
    }
  }
}

web-service 预计会有很多调用,我想让服务在失败的情况下冗余,所以我想让两个实例同时运行来处理所有请求.

1) 让两个 web 服务实例同时处理请求的最佳方式是什么?使用外部负载均衡器或在 akka/akka- 中使用一些魔法(我不知道) http ?

2) 为了提高性能,我必须调整哪些主要参数?

【问题讨论】:

    标签: scala akka akka-stream akka-http


    【解决方案1】:

    this question 的答案演示了如何从 Route 中进行 Actor 调用。

    如果您将该技术与 Akka 中的 clustering 功能相结合,您应该能够完成工作。

    让您的 Route 向 Router 发送消息,该消息会将消息发送到 N 个 remotely deployed Actors 中的 1 个(从您的问题看来,round robin 路由器就是您想要的)。

    class HttpResponseActor extends Actor {
    
      def foo : HttpResponse = ??? // Not specified in question
    
      override def receive = {
        case _ : HttpRequest => foo 
      }
    }
    
    import akka.actor.{ Address, AddressFromURIString }
    import akka.remote.routing.RemoteRouterConfig
    
    val addresses = Seq(Address("akka.tcp", "remotesys", "otherhost", 1234),
                        AddressFromURIString("akka.tcp://othersys@anotherhost:1234"))
    
    val routerRemote = 
      system.actorOf(RemoteRouterConfig(RoundRobinPool(5), addresses).props(Props[HttpResponseActor]))
    

    远程 Actor 使用 HttpResponse 进行响应。这个回复可以go through the Router or directly back to the Route

    Route 将答案粘贴在 complete 指令中以返回给客户端。

    val route = 
      get {
        path("foo") {
          onComplete((routerRemote ? request).mapTo[HttpResponse]) {
            case Success(response) => complete(response)
            case Failure(ex) => complete((InternalServerError, s"Actor not playing nice: ${ex.getMessage}"))
          }
        }
      }
    

    【讨论】:

    • 嗨@Ramon,谢谢你的回答!!!,我可以再问你两个问题吗? 1)如果我使用演员,我会失去流提供给我的背压控制? 2)我必须在哪里调用我的 foo 函数?
    • @GeorgeC,欢迎您回答。 1)我不认为你会失去背压,但我不是 100% 确定。我不知道路由调用onComplete 的影响,这可以转换为mapAsyncmapAsyncAwait。 2)我已修改我的答案以保留您原来的 foo 功能。快乐的黑客攻击。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 2021-12-07
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    相关资源
    最近更新 更多