前言
erlang的httpc是官方自带的http请求工具, 是一个体感上很好用的工具(其实是我没用过其他工具),前不久,一位大佬离职的时候就告诫过,使用一个工具,一定不能直接使用默认的参数,这不,问题就出现了。
(httpc文档)
问题
有一个服务,提供了多个接口,其中,有部分接口涉及到轮询,因此响应时间有可能非常非常长。而另一方面,其他正常接口的反应时间是很快的。然而实际使用的时候,却观察到,本应很快返回的接口会有一定的延时,在pinpoint的监控下可以看到,服务有时候会等待一定的时间,最长等待了二十多秒。
定位
问题的出现就在于httpc中。我使用了httpc访问了上文描述的接口,配置都使用的是默认的。而httpc的options里有一个参数,max_keep_alive_length
MaxKeepAlive = integer()
Maximum number of outstanding requests on the same connection to a host. Default is 5.
这个参数的含义是, 根据 HTTP/1.1的协议, 我们会复用连接(减少握手消耗), 在这样一条连接上,最多同时支持五条请求。然而这五条请求只能按照次序返回,如果前面的请求花费了很多时间, 那么后面的请求就必须等待,直到前面的完成。这就是这个现象出现的原因。
解决方案
在服务启动的地方,设置下这个参数
httpc:set_options([{max_keep_alive_length, 0}])
其他
另外还有一些参数, 比如说 max_sessions, 释义是对单个host允许的最大连接数,但是即使为0, 连接仍然会被复用,这个参数只是一个软性的限制,100和0的差距并不大。