gen_tcp接收占用极高的CPU

9
抱歉,我是一名Erlang新手,可能会问一些愚蠢的问题。但请帮助我解决这个问题。
我已经编写了一个Erlang服务器来替换我使用的Node.js服务器,它吞噬了我的所有内存,我希望Erlang可以成为一种出路。该服务器在单元测试和内部测试下运行正常,但在压力测试中遇到了高CPU使用率的问题。
经过精简,我发现CPU飙升是由于接收来自客户端的TCP引起的。
receiveClientPacket(Sock) ->
  inet:setopts(Sock, [{active, once}, {buffer, ?CLIENTHEARTBEATSIZE}]),
  receive
    {tcp, Sock, Data} ->
      {ok, Data};
    {tcp_closed, Sock} ->
      {error, closed}
    after ?CLIENTRECCEIVETIMEOUT ->
      {error, timeout}
  end.

我在函数开始时让进程休眠了10小时(以防止它调用接收),CPU根本没有突发。因此,我得出结论,CPU的突发是由于TCP接收引起的。(如果我犯了任何错误,请纠正我)
以下是有关我的压力测试的信息:
1. 使用以下命令启动Erlang服务器:erl +zdbbl 2097151 -K true +A 128 +P 2. 连接5000000个客户端到Erlang服务器,每个客户端连接5000个 3. 客户端在完成所有连接后每分钟向服务器发送2个字节的数据(即每分钟只执行2个字节的数据),CPU从“top”中突然增加到约30%sy
我正在使用Amazon Linux AMI(大型实例,64位)作为Erlang服务器。这种突发是由Linux引起的吗?因为我不知道系统将如何使用CPU。还是我的代码有问题?(我相信是...)
在实际情况下,我们的服务器不仅接收ping pong,还接收消息,这会增加更多负载...这只是第一步...
感谢能够帮助我的人。
Anita〜*
大型实例的信息(供参考):
- 7.5 GB内存 - 4个EC2计算单元(2个虚拟核心,每个核心有2个EC2计算单元) - 850 GB实例存储 - 64位平台 - I/O性能:高

1
上述代码是否只有一个单一的进程在运行? - Tilman
将最大进程数设置为5000000个进程(+P 5000000)在您的情况下是不必要的,它会增加进程大小但不会影响CPU。 - rvirding
这意味着您每秒接收约85个2字节消息,这并不多。除了调用receiveClientPacket/1之外,您在循环代码中还做了其他事情吗? - rvirding
我在想这是否是操作系统的问题? - Anita
也许队列中还有其他不匹配的消息?接收进程队列的大小是多少?难道这不是选择性接收的问题吗? - Wacław Borowiec
显示剩余4条评论
1个回答

2

我刚刚尝试在文章中的程序上运行压力测试,然而CPU也突然飙升到了100%。我认为这可能是操作系统或配置问题... - Anita

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接