在我的后端应用程序中,我的负载平衡器使用轮询来分配流量。因此,我的主机名有两条A记录:
- x.x.x.x myapp.com
- y.y.y.y myapp.com
如果其中任何一个已关闭,则返回503 Service Unavailable。
现在,在我的Android应用程序中,我使用OkHttp 4。进行网络操作,DNS解析结果缓存在设备上。因此,如果缓存的IP发生故障,它就不会尝试到达另一个IP,请求就会失败。我尝试了多种方法来使它工作,但直到现在还没有成功。我尝试过的事情:
- 添加一个网络拦截器,并设置
Retry-After: 0
头强制它重试请求 - 添加一个count变量并再次发送请求,直到count变为0
- 设置Connection Pool为
.connectionPool(new ConnectionPool(0, 1, TimeUnit.MILLISECONDS))
,避免缓存连接,重新请求 - 根据文档,它说它应该在连接失败时自动重试,但状态码503没有。我在分析器中验证了这一点,我可以看到只有一个请求正在进行。
为了确保两个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 ?
这是任何应用程序都无法做到的,除非你可以访问你的DNS服务器源,让他选择在哪个ip地址发送请求。
如果DNS记录可以通过任何方式编辑,例如使用hosts文件来确定域名指向哪个IP,那么您可以动态更改该文件,并且工作完成。但是Android OS/IOS不允许你这样做,即使有一个hosts文件。
你不能选择将请求发送到某个ip,除非你知道一种神奇的方式将域名传递到标头中的请求,特别是如果它有SSL。
如果另一台服务器宕机,故障转移到其中一台服务器的唯一方法是,在基础设施中放置一个主管,它将知道两台服务器中哪一台是启动并运行的,并将请求路由到该服务器。