如果服务器出现故障,如何使 finagle 客户端自动尝试重新连接?

How to make a finagle client automatic try to reconnect if the server goes down?

我正在测试 finagle 并克服了目前的情况:

服务器:

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

class Server(name: String, port: Int) {
  val service = new Service[http.Request, http.Response] {
    def apply(req: http.Request): Future[http.Response] = {
      println(s"Request on server $name")
      Future.value(
        http.Response(req.version, http.Status.Ok)
      )
    }
  }

  val server = Http.serve(s":$port", service)
}

object Server1 extends App {
  val server = new Server("1", 9001).server
  Await.ready(server)
}

object Server2 extends App {
  val server = new Server("2", 9002).server
  Await.ready(server)
}

客户:

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

object Client extends App {

  val client: Service[http.Request, http.Response] =
    Http.client
      .methodBuilder("localhost:9001,localhost:9002")
      .newService("client")

  while(true) {
    val request = http.Request(http.Method.Get, "/")
    request.host = "www.scala-lang.org"
    val response: Future[http.Response] = client(request)
    println(Await.result(response))
    Thread.sleep(50)
  }
}

Finagle 版本:

libraryDependencies ++= Seq(
  "com.twitter" %% "finagle-core" % "20.4.1",
  "com.twitter" %% "finagle-http" % "20.4.1",
  "com.twitter" %% "finagle-serversets" % "20.4.1"
)

我找不到让客户端在这种情况下不死机并在服务器再次启动时尝试重新连接的方法

不确定这是否完全符合要求,按照文档 2 配置似乎适用。通过添加 RetryBudget 和 FailureAccrualPolicy 应该使其接近您的要求。希望下面的代码能提供思路。

val budget = RetryBudget(
  ttl = 10.seconds,
  minRetriesPerSec = 5,
  percentCanRetry = 0.1
)

val client: Service[http.Request, http.Response] = Http.client
    .methodBuilder("localhost:9001,localhost:9002")
    .withRetryBudget(budget)
    .withRetryBackoff(Backoff.exponentialJittered(2.seconds, 32.seconds))
    .configured(Param(() => FailureAccrualPolicy.successRate(
      requiredSuccessRate = 0.95,
      window = 100,
      markDeadFor = Backoff.const(10.seconds))))
    .newService("client")