問題があります: 1M の同時オープン TCP 接続を保持できる Erlang サーバーを作成したいと考えています。OS (Oracle Linux 7) を調整して、ファイル記述子を上げました。サーバー上で gen_tcp:listen を実行します
// point_1
Socket = gen_tcp:accept
spawn(handle(Socket)) //
point_1 に戻る別のスレッド
順番に接続しても問題ありません。100 秒で 100K クライアントを接続しました。しかし、私はそれ以上の忍耐がありませんでした。
それらを同時に接続したい場合、たとえば、100から約80の接続しか作成されません。
これは私がすべてを実行する方法です:
erlc *.erl
erl +Q 134217727 +P 1000000 -env ERL_MAX_PORTS 40960000 -env ERTS_MAX_PORTS 40960000
// ポート 9999 でリッスンする 1 つのサーバーを起動します
ex:start(1, 9999)
// 100 クライアントがポート 9999 で接続を試みます
ex:connect_clients(100, 9999)
いくつかのコードをお見せしましょう:
start(Num,LPort) ->
case gen_tcp:listen(LPort,[{active, false},{packet,2}]) 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,loop,[S]),
server(LS, Nr+1);
Other ->
io:format("accept returned ~w - goodbye!~n",[Other]),
ok
end.
loop(S) ->
inet:setopts(S,[{active,once}]),
receive
{tcp,S, _Data} ->
Answer = 1,
gen_tcp:send(S,Answer),
loop(S);
{tcp_closed,S} ->
io:format("Socket ~w closed [~w]~n",[S,self()]),
ok
end.
client(PortNo) ->
{ok,Sock} = gen_tcp:connect("localhost", PortNo,
[]).
connect_clients(Number, Port) ->
spawn(ex, client, [Port]),
case Number of
0 -> ok;
_ -> connect_clients(Number-1, Port)
end.