一次简单的 HTTP 调用,为什么时延这么大?抓个包分析下
副问题[/!--empirenews.page--]
1.最近项目测试碰着个稀疏的征象,在测试情形通过 Apache HttpClient 挪用后端的 HTTP 处事,均匀耗时居然靠近 39.2ms。也许你乍一看认为这不是很正常吗,有什么好稀疏的?着实否则,我再来说下一些根基信息,该后端的 HTTP 处事并没有什么营业逻辑,只是将一段字符串转成大写然后返回,字符串长度也仅只有 100 字符,其它收集 ping 延时只有 1.9ms 阁下。因此,理论上该挪用耗时应该在 2-3ms 阁下,但为什么均匀耗时 39.2ms 呢? ![]() ![]() 因为事变缘故起因,挪用耗时的题目,对我来说,已经见责不怪了,常常会帮营业办理内部 RPC 框架挪用超时的相干题目,可是 HTTP 挪用耗时第一次碰着。不外,排盘查题的套路是一样的。首要要领论无外乎由外而内、至上而劣等排查要领。我们先来看看外围的一些指标,看可否发明蛛丝马迹。 2. 外围指标 2.1 体系指标 首要看外围的一些体系指标(留意:挪用与被挪用的呆板都要看)。譬喻负载、CPU。只需一个 top 呼吁就能尽收眼底。 因此,确认了下 CPU 和负载都很空闲。因为其时没有截图,这里就不放图了。 2.2 历程指标 Java 措施历程指标首要看 GC、线程仓库环境(留意:挪用与被挪用的呆板都要看)。 Young GC 都很是少,并且耗时也在 10ms 以内,因此没有长时刻的 STW。 由于均匀挪用时刻 39.2ms,较量大,假如耗时是代码导致,线程仓库应该能发明点啥。看了之后一无所得,处事的相干线程仓库首要示意是线程池的线程在等使命,这就意味着线程并不忙。 是不是感受黔驴之技了,接下来该怎么办呢? 3. 当地复现 假如当地(当地是 MAC 体系)能复现,对排盘查题也是极好的。 因此在当地行使 Apache HttpClient 写了个简朴 Test 措施,直接挪用后端的 HTTP 处事,发明均匀耗时在 55ms 阁下。咦,怎么跟测试情形 39.2ms 的功效有点区别。首要是当地与测试情形的后端的 HTTP 处事呆板跨地域了,ping 时延在 26ms 阁下,以是延时增大了。不外当地确实也是存在题目的,由于ping 时延是 26ms,后端 HTTP 处事逻辑简朴,险些不耗时,因此当地挪用均匀耗时应该在 26ms 阁下,为什么是 55ms? 是不是越来越疑惑,一头雾水,不知怎样动手? 时代猜疑过 Apache HttpClient 是不是有什么处所行使的差池,因此行使 JDK 自带的 HttpURLConnection 写了简朴的措施,做了测试,功效一样。 4. 诊断 4.1 定位 着实从外围的体系指标、历程指标,以及当地复现来看,大抵可以或许断定不是措施上的缘故起因。那 TCP 协议层面呢? 有收集编程履历的同窗必然知道 TCP 什么参数会引起这个征象。对,你猜的没错,就是 TCP_NODELAY。 那挪用方和被挪用方哪边的措施没有配置呢? 挪用方行使的是 Apache HttpClient ,tcpNoDelay 默认配置的就是 true。我们再来看看被挪用方,也就是我们的后端 HTTP 处事,这个 HTTP 处事用的是 JDK自带的 HttpServer。
居然没看到直接配置 tcpNoDelay 接口,翻了下源码。哦,原本在这里,在 ServerConfig 的类中有这段静态块,用来获取启动参数,默认 ServerConfig.noDelay 为 false。
4.2 验证 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |