Chromium内核浏览器访问localhost时的初始连接(initial connection)高延迟问题

HearyHTTPd代码里设置为监听的host为127.0.0.1时,在Chrome中用 http://localhost:8080 会有较大initial connection lantency从而变得较慢,而用 http://127.0.0.1:8080 访问则很快。

Chromium内核浏览器访问localhost时的初始连接(initial connection)高延迟问题

1 问题描述

在开发基于NIO的HearyHTTPd服务器的时候,发现使用 http://localhost:8080 访问时,存在高初始连接(initial connection)延迟的问题,影响达数百毫秒。

经过对比和排查,发现问题仅限于基于Chromium内核的浏览器,而Firefox浏览器表现出了稳定且高速的性能。

2 实验结果

通过netstat -an发现,不论输入的监听host为localhost,还是127.0.0.1,在计算机上监听的都是127.0.0.1:8080,没有监听IPv6的[::1]:8080

2.1 Chromium内核浏览器

测试的Chromium内核浏览器:

  • Google Chrome 83.0.4103.106(正式版本) (64 位)
  • Microsoft Edge 83.0.478.54 (官方内部版本) (64 位)

两款浏览器差异不大,数值范围几乎一致。

测试结果:

hhttpd host request localhost:8080 127.0.0.1:8080 [::1]:8080
localhost 首个文件(index.html) 3~10 ms 3~10 ms ERR_CONNECTION_REFUSED
后续资源(js/css/fonts...) 250~700 ms 3~20 ms ERR_CONNECTION_REFUSED
127.0.0.1 首个文件(index.html) 3~10 ms 3~10 ms ERR_CONNECTION_REFUSED
后续资源(js/css/fonts...) 250~700 ms 3~20 ms ERR_CONNECTION_REFUSED
[::1] 首个文件(index.html) 3~10 ms ERR_CONNECTION_REFUSED 3~10 ms
后续资源(js/css/fonts...) 3~20 ms ERR_CONNECTION_REFUSED 3~20 ms

2.2 Firefox浏览器

测试的Firefox浏览器:

  • Firefox 77.0.1 (64 位)

测试结果:

hhttpd host request localhost:8080 127.0.0.1:8080 [::1]:8080
localhost 首个文件(index.html) 2~4 ms 1~2 ms ERR_CONNECTION_REFUSED
后续资源(js/css/fonts...) 2~15 ms 2~10 ms ERR_CONNECTION_REFUSED
127.0.0.1 首个文件(index.html) 2~4 ms 1~2 ms ERR_CONNECTION_REFUSED
后续资源(js/css/fonts...) 2~15 ms 2~10 ms ERR_CONNECTION_REFUSED
[::1] 首个文件(index.html) 2~4 ms ERR_CONNECTION_REFUSED 1~2 ms
后续资源(js/css/fonts...) 2~15 ms ERR_CONNECTION_REFUSED 2~10 ms

2.3 实验总结

从结果上来看,通过localhost访问hhttpd的高初始连接(initial connection)延迟问题仅出现在基于Chromium内核的浏览器上。

从分布来看,直接使用IP地址访问监听的IP地址(不论IPv4还是IPv6)都是最快的。

总体而言,Firefox表现出的性能最好。

3 原因分析

暂时还没有找出造成该问题的准确原因。

推测可能与Chromium遇到localhost时,优先访问IPV6的本地环回地址[::1]有关。

4 解决方案

推荐直接使用IP地址访问监听的IP地址(不论IPv4还是IPv6)。

5 参考资料

stalled和Initial connection偶尔请求时间长

Why is the initial connection time for a HTTP request so long?