0

我正在尝试优雅地处理 Couchbase 引导失败,而不是让应用程序启动失败。这个想法是使用“Couchbase 即服务”,这样如果我无法连接到它,我应该仍然能够返回降级的响应。通过使用 Couchbase 异步 API,我已经能够在一定程度上实现这一点;RxJava FTW。

问题是,当服务器关闭时,Couchbase Java 客户端会发疯并不断尝试连接到服务器;据我所知,这样做的课程ConfigEndpoint在放弃之前尝试了多少次是没有限制的。这会使日志充满java.net.ConnectException: Connection refused错误。我想要的是让它尝试几次,然后停止。

有什么可以提供帮助的想法吗?

编辑

这是一个示例应用程序

重现问题的步骤:

  1. svn export https://github.com/asarkar/spring/trunk/beer-demo.
  2. beer-demo目录中,运行./gradlew bootRun. 等待应用程序启动。
  3. 从另一个控制台,运行curl -H "Accept: application/json" "http://localhost:8080/beers". 由于无法连接到 Couchbase,客户端请求将超时,但 Couchbase 客户端将持续淹没控制台。
4

2 回答 2

1

我们选择让客户端继续连接的原因是 Couchbase 通常部署在高可用性集群情况下。大多数运行我们的 SDK 的人都希望它继续努力工作。我认为,我们这样做非常聪明,因为我们进行了指数退避并具有可调整性,因此开箱即用是合理的,并且可以根据您的环境进行调整。

至于您要做什么,其中一个可调参数与重试有关。通过调整超时值和重试,您可以让应用程序引用客户端,如果它不能为请求提供服务,则简单地快速失败。

另一种选择是,我们确实有办法让您的应用程序知道哪个节点将处理请求(如果引导尚未完成,则为 null),您可以使用它来实现类似断路器的功能。对于未来的版本,我们希望将断路器直接添加到 SDK。

综上所述,这些都不是正常的路径,因为其目的是您的 Couchbase 集群大部分时间都已启动、运行和可访问。故障通过自动故障转移触发故障转移,使事情恢复可用性。根据设计,Couchbase 牺牲了一些可用性来获得被访问数据的一致性,从异常处理程序中读取副本和其他有意过时的读取供您在需要时购买

希望对您有所帮助,并很高兴收到有关您认为我们应该采取不同做法的任何反馈。

于 2017-09-01T05:05:26.470 回答
0

自己解决了这个问题。我设计的客户端处理以下用例:

  1. 客户端启动必须能够抵御 CB 故障/可用性。
  2. 如果 CB 不可用,客户端不得使请求失败,而是返回降级响应。
  3. 如果发生 CB 故障转移,客户端必须重新连接。

我在这里创建了一篇博文。我知道最好复制粘贴而不是链接到外部 URL,但是内容太大而无法回答。

于 2017-10-27T05:26:11.140 回答