`
coderplay
  • 浏览: 571706 次
  • 性别: Icon_minigender_1
  • 来自: 广州杭州
社区版块
存档分类
最新评论

erlang网络编程的几个性能调优和注意点

阅读更多
前些天给echo_server写了个非常简单的连接压力测试程序,
代码
 
  1. -module(stress_test).  
  2.   
  3. -export([start/0, tests/1]).  
  4.   
  5. start() ->  
  6.     tests(12345).  
  7.   
  8. tests(Port) ->  
  9.     io:format("starting~n"),  
  10.     spawn(fun() -> test(Port) end),  
  11.     spawn(fun() -> test(Port) end),  
  12.     spawn(fun() -> test(Port) end),  
  13.     spawn(fun() -> test(Port) end).  
  14.   
  15. test(Port) ->  
  16.      case gen_tcp:connect("192.168.0.217", Port, [binary,{packet, 0}]) of  
  17.     {ok, _} ->  
  18.             test(Port);  
  19.     _ ->  
  20.         test(Port)  
  21.     end.  
一开始我的这个stress_test客户端运行在windows上面, echo_server服务器端运行在linux上面。 结果接受了1016个连接就停止了. 于是我用ulimit -n 改了服务器端的文件描述符数量为10240. 接着还是如此,折腾了几天,最终还是没有搞明白。

于是就求助于公司的linux编程牛人,结果让我一倒...  客户端没有修改文件描述符个数. windows上得在注册表里面改.
牛人开始对这东西的性能感兴趣了,刚好我摸了一阵子erlang的文档,于是我俩就走向了erlang网络连接的性能调优之旅啦~~过程真是让人兴奋。 我们很快通过了1024这一关~~到了4999个连接,很兴奋.

但为什么4999个连接呢, 检查一下代码终于发现echo_server.erl定义了一个宏, 最大连接数为5000. 我又倒~~
修改编译之后, 连接数跑到101xx多了, 太哈皮了!
再测102400个连接时,到32767个连接数erl挂了~说是进程开得太多了. 好在记得这个erl的参数+P,可以定义erlang能生成的进程数. 默认是32768. 改了!

后面不知怎么着,在81231个连接停止了. 新的性能瓶颈又卡了我们.  好在牛人对linux熟, 用strace(这东西会莫名地退出), stap查出一些苗头.   我也想到在otp文档好像提过另一个limit,那就是端口数...在此同时我们发现erlang在linux上是用的传统poll模型. 但查erlang的源代码发现是支持epoll的. 在网上搜了半天,终于搜到了个maillist的帖子.

代码
  1. $./configure --enable-kernel-poll  

由于我们的测试服务器是双核的,我们在配置的时候也打开了smp支持.  欢快的make  & make install之后....
把 /proc/sys/net/ipv4/ip_local_port_range 的内容改成了1024到65535.  最多也也能改成65535 :)

代码
  1. $echo 1024 65535 > ip_local_port_range  

另外再添加一个erl的环境变量
代码
  1. $export ERL_MAX_PORTS=102400  

于是开始跑了,不过这次跑不一样了
echo_server
 
  1. $erl -noshell  +P 102400 +K true +S 2 -smp -s echo_server start  
   
stress_test
 
  1. $erl -noshell  +P 102400 +K true +S 2 -smp -s stress_test start  
这里的+K true,表示使用内核poll,+S 2 表示两个核. 这样可欢快啦~~~ 10w大关过咯! 而且比刚才没用epoll的速度快暴多~~
于是我们又开始了204800个连接发测试了~~~

用top一看cpu占用率极低,服务器只在5%左右。 内存也不是很大~~
分享到:
评论
8 楼 laputa73 2013-09-24  
chuqingq 写道
有个疑问,端口数最多不超过65536个,为什么测试结果能达到20万连接?

因为libevent,允许一个端口同时支持多个连接挂起
7 楼 chuqingq 2012-11-04  
有个疑问,端口数最多不超过65536个,为什么测试结果能达到20万连接?
6 楼 laputa73 2012-08-15  
oyscal 写道
引用
客户端没有修改文件描述符个数. windows上得在注册表里面改

请问是怎么改的?

同问,搜了半天,没找到。停在1019了
5 楼 oyscal 2007-11-16  
引用
客户端没有修改文件描述符个数. windows上得在注册表里面改

请问是怎么改的?
4 楼 mryufeng 2007-10-22  
+A +a 来多开几个线程来协助加快inet_tcp driver的速度估计也有帮助。

http://mryufeng.iteye.com
3 楼 qiezi 2007-07-12  
谢谢。erl不接受--help,没想到epmd接受这个。epmd的端口可以修改了。

关于节点的端口范围,刚刚搜到一个:
http://avindev.iteye.com/blog/98212
2 楼 coderplay 2007-07-10  
usage: epmd [-d|-debug] [DbgExtra...] [-port No] [-daemon]
            [-d|-debug] [-port No] [-names|-kill]

See the Erlang epmd manual page for info about the usage.
The -port and DbgExtra options are

    -port No
        Let epmd listen to another port than default 4369
    -d
    -debug
        Enable debugging. This will give a log to
        the standard error stream. It will shorten
        the number of saved used node names to 5.

        If you give more than one debug flag you may
        get more debugging information.

    -packet_timout Seconds
        Set the number of seconds a connection can be
        inactive before epmd times out and closes the
        connection (default 60).

    -delay_accept Seconds
        To simulate a busy server you can insert a
        delay between epmd gets notified about that
        a new connection is requested and when the
        connections gets accepted.

    -delay_write Seconds
        Also a simulation of a busy server. Inserts
        a delay before a reply is sent.
看上面的帮助
1 楼 qiezi 2007-07-08  
问个小问题:
有没有办法指定epmd监听的端口?有没有办法指定节点(node)监听的端口范围?

相关推荐

Global site tag (gtag.js) - Google Analytics