【问题标题】:OkHttp retry connection on another IP if 503如果 503,OkHttp 在另一个 IP 上重试连接
【发布时间】:2021-04-25 03:59:17
【问题描述】:

在我的后端应用程序中,我的负载均衡器使用循环来分配流量。所以,我的主机名有两条 A 记录:

- x.x.x.x myapp.com
- y.y.y.y myapp.com

如果其中任何一个出现故障,它会返回 503 Service Unavailable。

现在,在我的 Android 应用程序中,我使用 OkHttp 4.x 进行网络操作,并且 DNS 解析缓存在设备上。因此,如果缓存 IP 出现故障,它不会尝试访问其他 IP,并且请求会失败。我尝试了多种方法来使其工作,但直到现在还没有诅咒。我尝试过的事情:

  • 添加网络拦截器并设置Retry-After: 0 标头以强制它重试请求。
  • 添加count变量,再次发送请求,直到count变为0
  • 将连接池设置为.connectionPool(new ConnectionPool(0, 1, TimeUnit.MILLISECONDS)),以避免缓存连接并重试请求
  • 根据docs,它说它应该在连接失败时自动重试,但它不适用于状态代码 503。我在分析器中验证了这一点,我只能看到 1 个请求。

为确保两个 IP 均已解析,我添加了以下代码:

OkHttpClient client = new OkHttpClient.Builder().build();

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try  {
            List<InetAddress> addr = client.dns().lookup("myapp.com");

            for ( InetAddress a : addr ) {
                Log.d(TAG, a.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

thread.start();

我得到了日志中的两个条目:

myapp.com/x.x.x.x
myapp.com/y.y.y.y

那么,有没有办法让 OkHttp 客户端尝试其他 IP 以防万一失败?

【问题讨论】:

  • 如何使用拦截器并检查503? stackoverflow.com/a/31733634/2830850
  • 我也试过了。在 503 上,我尝试执行 Call.clone(),但它再次命中相同的 IP。
  • 如何在 url 中添加虚拟查询参数?
  • @Tch 发布的内容绝对正确,您无法更改 IP,这应该在 nginx 后面进行负载平衡,当一台服务器关闭时应该尝试另一台服务器

标签: android networking okhttp


【解决方案1】:

这不能由任何应用程序完成,除非您有权访问您的 DNS 服务器源以让他选择发送请求的 ip。

如果 DNS 记录可以通过任何方式编辑,例如使用主机文件来确定域指向的 IP,那么您可以动态更改该文件并完成工作。但即使有 hosts 文件,Android OS/IOS 也不会让你这样做。

您不能选择将请求发送到某个 ip,除非您知道在标头中将域名传递给该请求的神奇方法,特别是如果它上面有 SSL。

如果另一台服务器出现故障,故障转移到一台服务器的唯一方法是在基础架构中放置一个控制器,该控制器将知道两台服务器中的哪台已启动并正在运行并将请求路由到那台。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 2012-10-06
    • 1970-01-01
    • 2016-11-07
    • 2021-02-18
    • 2021-10-11
    • 2015-01-18
    相关资源
    最近更新 更多