Sorunum var: 1M eşzamanlı açık tcp bağlantısını tutabilen bir Erlang sunucusu oluşturmak istiyorum. Dosya tanımlayıcılarını yükseltmek için işletim sistemimi (Oracle Linux 7) ayarladı. sunucuda i gen_tcp yapın: dinlemekErlang aynı anda 1M istemcilerini bağla
// point_1
Soket = gen_tcp:
spawn (sap (Soket)) // i bağlarsanız point_1
için
geri başka bir iş parçacığı kabul sırayla onun hiçbir sorun, 100 saniyede 100K istemcileri bağladım; ama daha fazla bir şey için hiç bir isteğim yoktu.
Bağlantısını bağlantı yolu ile bağlamak isterseniz, örneğin 100'den yalnızca 80 bağlantı yapılır.
Bu her şeyi çalıştırmak nasıl:
erlc *.erl
erl +Q 134217727 +P 1000000 -env ERL_MAX_PORTS 40960000 -env ERTS_MAX_PORTS 40960000
// 9999
ex:start(1, 9999)
// 100 istemcileri noktası üzerinde bağlanmayı deneyin bağlantı noktasında dinleyecek bir sunucuyu başlatmak 9999
ex:connect_clients(100, 9999)
Size bir kod göstereyim:
Buradastart(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.
Gerçekten de, bu iki konu hakkında haklıydınız. Onları tamir ettim. Şimdi connect_clients (1000, 9999) dediğimde, saniyede yaklaşık 100 bağlanır ve 800'e gider; o zaman durur. Sunucu çökmez, böylece tekrar arayabilirim, bir müşteri veya istediğim numarayı bağlarım. Ancak, çağrı başına yaklaşık 800'den fazla bağlantı kuramıyorum. Connect_clients (1000000, 9999) çağırabilirdim, ancak VM'im donuyor. Düşüncesi olan var mı? Bana şimdiden yardım ettiğin için teşekkürler. –
Ayrıca, kabul ederken, daha iyi verim elde etmek için aynı dinleme soketinde 'gen_tcp: accept/1 'çağıran birkaç alıcı işlemine sahip olabileceğinizi unutmayın. –
@ ȘtefanStan, vurduğunuz yeni sorunları söylemek zor. Sasl etkinken çalışıyor musunuz? Fark edilmeyecek herhangi bir sorunla karşılaşmadığınızdan emin olmak için başlatabilirsiniz. İhtiyacınız olan bağlantı sayısını sağlamak için işletim sisteminizin doğru şekilde kurulduğundan emin misiniz? Kabuğundaki ulimit -n 'neyi gösteriyor? Ayrıca, hangi Erlang/OTP sürümünü kullanıyorsunuz? –