前言
之前有提到过高并发情况下对程序性能进行测试。事实证明,日志虽然影响很大,但是httpc请求的影响更大。一旦使用一次httpc请求,性能里面降低到空跑的1/10不到,两次则再降低一半左右,到最后性能真是一个大写的惨。
解决方案
开始我没找到httpc模块的瓶颈在哪,在指导下手写了使用gen_tcp进行的整个http请求过程。后续,我偶尔翻到一篇文章 https://www.jianshu.com/p/e325d6f2efd6,然后在其中的方法指导下进行了优化(毕竟人家的方法肯定比我的坑少)。
首先是启动模块 _app.erl 里,添加下面的语句
lists:foreach(fun(X) ->
httpc_profile_sup:start_child([{profile, X}]) end,
[http1, http2, http3, http4, http5, http6, http7, http8, http9])
这样写可以添加9个 Profile,用 lists:foreach 写的原因是一次只能添加一个,后续的会被省略,所以就添加9次。
添加完成的使用方式
Profile = lists:nth(rand:uniform(9),
[http1, http2, http3, http4, http5, http6, http7, http8, http9]),
httpc:request(
post,
{Url, Headers, ContentType, Body},
[],
[{body_format, binary}],
Profile)
这里是简便地实现了下profile的选取方法。我们肯定是希望多个profile能够处理相同数量的请求,但不是绝对严格的相等。实际上,只要每个profile处理的请求差不多,就能较大程度上避免瓶颈的诞生。可能会有更好的方法,如erlang公平调度原则使用的方法,这个我暂时就不考虑了。
在这个处理下,性能较不处理的时候提升了三倍左右,勉强可用。如果更多的增加profile的数量,优化效果比较有限,增长约几个百分点。