Android Studio中启用IPv6的域名通过OkHttp连接极慢问题
IPv6域名在蜂窝数据下请求耗时过长(OkHttp 5.0.0-alpha.11)
我有两个指向同一服务器的域名,其中一个启用了IPv6,另一个未启用。测试了四种请求场景,结果如下:
- 启用IPv6域名 + WiFi:响应耗时约4秒
- 启用IPv6域名 + 蜂窝数据:响应耗时约36秒
- 未启用IPv6域名 + WiFi:响应耗时约4秒
- 未启用IPv6域名 + 蜂窝数据:响应耗时约6秒
核心问题是启用IPv6的域名在蜂窝数据网络下请求耗时异常高,使用的是OkHttp 5.0.0-alpha.11版本,且设备确认支持IPv6。以下是我的请求代码:
protected int executePost(String _url, byte[] _data) { OkHttpClient bootstrapClient = new OkHttpClient.Builder() .callTimeout(20, TimeUnit.SECONDS) .cache(new Cache(new File("/local/cacheDirectory"), 10 * 1024 * 1024)) .retryOnConnectionFailure(false) .followRedirects(false) .followSslRedirects(false) .build(); Dns dns = new DnsOverHttps.Builder().client(bootstrapClient) .url(HttpUrl.get("https://cloudflare-dns.com/dns-query")) .bootstrapDnsHosts(getByIp("1.1.1.1"), getByIp("1.0.0.1")) .includeIPv6(true) .post(true) .build(); OkHttpClient client = bootstrapClient.newBuilder().dns(dns).build(); final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); RequestBody postBody = RequestBody.create(_data, JSON); Request post = new Request.Builder() .url(_url) .post(postBody) .addHeader("Content-Type", "application/json") .build(); try (Response response = client.newCall(post).execute()) { m_httpStatus = response.code(); m_httpBody = response.body().string(); } catch(Exception e) { m_httpStatus = -1; m_httpError = e.getCause().toString(); } return m_httpStatus; }
可能的解决方向
- 调整IPv6优先策略
OkHttp默认优先尝试IPv6地址,但部分蜂窝网络的IPv6链路可能存在连通性或延迟问题。可以自定义DNS解析逻辑,让IPv4地址优先尝试:
Dns customDns = new Dns() { @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException { List<InetAddress> addresses = Dns.SYSTEM.lookup(hostname); List<InetAddress> ipv4 = new ArrayList<>(); List<InetAddress> ipv6 = new ArrayList<>(); for (InetAddress addr : addresses) { if (addr instanceof Inet4Address) { ipv4.add(addr); } else { ipv6.add(addr); } } ipv4.addAll(ipv6); // 让IPv4地址排在前面 return ipv4; } }; OkHttpClient client = bootstrapClient.newBuilder().dns(customDns).build();
- 优化DoH在蜂窝网络下的解析性能
当前使用Cloudflare的DoH服务,可添加IPv6的bootstrap节点,让DoH在IPv6网络下也能高效解析:
Dns dns = new DnsOverHttps.Builder().client(bootstrapClient) .url(HttpUrl.get("https://cloudflare-dns.com/dns-query")) .bootstrapDnsHosts( getByIp("1.1.1.1"), getByIp("1.0.0.1"), getByIp("2606:4700:4700::1111"), // Cloudflare IPv6节点 getByIp("2606:4700:4700::1001") ) .includeIPv6(true) .post(true) .build();
- 细化超时参数
缩短连接和套接字超时,避免不必要的等待:
OkHttpClient bootstrapClient = new OkHttpClient.Builder() .callTimeout(20, TimeUnit.SECONDS) .connectTimeout(5, TimeUnit.SECONDS) .socketTimeout(10, TimeUnit.SECONDS) .cache(new Cache(new File("/local/cacheDirectory"), 10 * 1024 * 1024)) .retryOnConnectionFailure(false) .followRedirects(false) .followSslRedirects(false) .build();
- 排查蜂窝IPv6连通性
手动测试该域名IPv6地址在蜂窝网络下的延迟(如ping6命令),确认是网络链路问题还是代码逻辑问题。
内容的提问来源于stack exchange,提问作者ramen87x
相关产品推荐
相关产品推荐

