Ich habe ein Problem: Ich möchte einen Erlang-Server erstellen, der 1M gleichzeitige offene TCP-Verbindung halten kann. Ich habe mein Betriebssystem (Oracle Linux 7) angepasst, um die Dateideskriptoren zu erhöhen. Auf dem Server tun i gen_tcp: hörenErlang verbinden Sie gleichzeitig 1M Clients
// Point_1
Sockel = gen_tcp: akzeptieren
spawn (Griff (Sockel)) // anderen Thread
zurück zu Point_1
Wenn ich eine Verbindung sequentiell ist es kein Problem, in 100 Sekunden habe ich 100K Clients verbunden; aber ich hatte keine Geduld mehr.
Wenn ich diese in einer conncurent Weise verbinden möchten, werden nur etwa 80 Verbindungen von 100 hergestellt, zum Beispiel. Diese
ist, wie ich das alles laufen:
erlc *.erl
erl +Q 134217727 +P 1000000 -env ERL_MAX_PORTS 40960000 -env ERTS_MAX_PORTS 40960000
// einen Server starten, der auf Port 9999
ex:start(1, 9999)
// 100 Clients versuchen, eine Verbindung auf Port 9999
hörenex:connect_clients(100, 9999)
Lassen Sie mich Ihnen einen Code zeigen:
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.
In der Tat, Sie hatten Recht mit diesen beiden Fragen. Ich habe diese behoben. Jetzt, wenn ich connect_clients (1000, 9999) anrufe, verbindet es sich ungefähr 100 pro Sekunde und es geht zu 800; dann hört es auf. Der Server stürzt nicht ab, so dass ich ihn erneut anrufen kann, indem ich einen Client oder die Nummer, die ich möchte, anschließe. Aber ich kann nicht mehr als etwa 800 pro Anruf verbinden. Ich wünschte, ich könnte connect_clients (1000000, 9999) aufrufen, aber dann friert meine VM ein. Irgendwelche Gedanken? Danke für das, was Sie mir bereits geholfen haben. –
Denken Sie auch daran, dass Sie mehrere Akzeptor-Prozesse haben können, die 'gen_tcp: accept/1' auf demselben Listen-Socket aufrufen, um einen besseren Durchsatz beim Akzeptieren zu erreichen. –
@ ŞtefanStan schwer zu sagen, welche neuen Probleme Sie treffen. Laufen Sie mit 'sasl' aktiviert? Sie können es starten, um sicherzustellen, dass Sie keine Probleme bemerken, die unbemerkt bleiben. Sind Sie sicher, dass Ihr Betriebssystem richtig eingerichtet ist, um die Anzahl der benötigten Verbindungen zuzulassen? Was bedeutet "ulimit -n" in deiner Shell? Welche Version von Erlang/OTP benutzt du? –