【发布时间】:2023-03-06 01:44:01
【问题描述】:
首先我必须提到,我运行在经过调整以支持 100 万个连接的 CentOS 7 上。我用一个简单的 C 服务器和客户端进行了测试,我连接了 512000 个客户端。我可以连接更多,但我没有足够的 RAM 来生成更多的 linux 客户端机器,因为我可以从一台机器打开 65536 个连接; 8 台机器 * 每台 64000 个连接 = 512000。
我制作了一个简单的 Erlang 服务器,我想使用相同的 C 客户端连接 100 万或 50 万个客户端。我现在遇到的问题与内存有关。对于每个成功的gen_tcp:accept 调用,我都会生成一个进程。大约 50000 个打开的连接在服务器上花费了 3.7 GB RAM,同时使用 C 服务器我可以使用 1.9 GB RAM 打开 512000 个连接。确实,在 C 服务器上,我没有在接受后创建进程来处理东西,我只是在 while 循环中再次调用了接受,但即便如此......网上的人用更少的内存做了这个 erlang 的事情(ejabberd riak)
我认为我传递给 erlang VM 的标志应该可以解决问题。根据我在文档和网络上阅读的内容,这就是我所拥有的:erl +K true +Q 64200 +P 134217727 -env ERL_MAX_PORTS 40960000 -env ERTS_MAX_PORTS 40960000 +a 16 +hms 1024 +hmbs 1024
这是服务器代码,我通过调用start(1, 5001)打开了1个监听5001端口的监听器。
start(Num,LPort) ->
case gen_tcp:listen(LPort,[{reuseaddr, true},{backlog,9000000000}]) of
{ok, ListenSock} ->
start_servers(Num,ListenSock),
{ok, Port} = inet:port(ListenSock),
Port;
{error,Reason} ->
{error,Reason}
end.
start_servers(0,_) ->
ok;
start_servers(Num,LS) ->
spawn(?MODULE,server,[LS,0]),
start_servers(Num-1,LS).
server(LS, Nr) ->
io:format("before accept ~w~n",[Nr]),
case gen_tcp:accept(LS) of
{ok,S} ->
io:format("after accept ~w~n",[Nr]),
spawn(ex,server,[LS,Nr+1]),
proc_lib:hibernate(?MODULE, loop, [S]);
Other ->
io:format("accept returned ~w - goodbye!~n",[Other]),
ok
end.
loop(S) ->
ok = inet:setopts(S,[{active,once}]),
receive
{tcp,S, _Data} ->
Answer = 1, % Not implemented in this example
gen_tcp:send(S,Answer),
proc_lib:hibernate(?MODULE, loop, [S]);
{tcp_closed,S} ->
io:format("Socket ~w closed [~w]~n",[S,self()]),
ok
end.
【问题讨论】:
标签: memory process erlang server