Maximální počet klientů vlastního TCP serveru

Maximální počet klientů vlastního TCP serveru
« kdy: 19. 12. 2019, 12:20:54 »
Ahoj, chtel bych se zeptat, zda by mi nekdo nedokazal poradit s TCP serverem. Napsal jsem si testovaci TCP server ke kteremu se pripojuji nejaka zarizeni zvenku a server z nich kazkou minutu stahne nejaka data. Ta zarizeni jsou trvale pripojena k serveru. Toto vse plni ma ocekavani a spolehlive funguje. Problem nastal v momente, kdy jsem se rozhodnul zatizit server. Zatez byla provedena tak, ze se vytvoril TCP clienta, ktery simuluje nove zarizeni a tento client byl nekoliksetkrat spusten. Jakmile mnozstvi clientu presahlo hodnotu 1024 server se zacal chovat divne a padat. Udajne je to dane tim, ze kazdy proces v linuxu ma nastaveno maximalni mnozstvi filedescriptoru, ktere muze pri svem behu otevrit. Overil jsem tedy tento prikaz:
Kód: [Vybrat]
ulimit -a a dostal tento vypis:
Kód: [Vybrat]
[core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 14853
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 14853
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Z tohoto jsem usoudil, ze mam skutecne nastaven maly limit a tak jsem do souboru:
Kód: [Vybrat]
/etc/security/limits.confpridal tyto dva radky:
Kód: [Vybrat]
rudolf          hard     nofile          32768
rudolf          soft     nofile          32768

Po restartu PC a novem vypisu maximalniho mnozstvi jsem dostal ocekavane udaje. Jake bylo ale me prekvapeni, kdyz po vytvoreni 1024 clientu server opet spadnul. V tento moment jsem uz naprosto bezradny a nevim jak dal. Nevite kde je problem? DIK.
« Poslední změna: 19. 12. 2019, 12:50:33 od Petr Krčmář »


alex6bbc

  • *****
  • 1 432
    • Zobrazit profil
    • E-mail
Re:TCP server
« Odpověď #1 kdy: 19. 12. 2019, 12:45:32 »
v cem jsi to psal?
jestli to neomezil nejaky framework??

Re:TCP server
« Odpověď #2 kdy: 19. 12. 2019, 12:51:05 »
Je to napsany v Ccku s pouzitim standartnich systemovych knihoven. Verze linuxu: Ubuntu 18.04.1 LTS.

alex6bbc

  • *****
  • 1 432
    • Zobrazit profil
    • E-mail
Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #3 kdy: 19. 12. 2019, 14:00:34 »
chtelo by to testovat navratove hodnoty z funkci, zda to padne na otevirani socketu.

alex6bbc

  • *****
  • 1 432
    • Zobrazit profil
    • E-mail
Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #4 kdy: 19. 12. 2019, 14:14:28 »
zkusit nejakou implementaci stahnout z netu a zkusit, zda to je nastavenim os, nebo chyba v kodu.


luvar

  • ***
  • 225
    • Zobrazit profil
    • E-mail
Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #5 kdy: 19. 12. 2019, 14:22:15 »
Ako mas na tom
Kód: [Vybrat]
net.core.somaxconn hodnotu? Viď https://stackoverflow.com/questions/410616/increasing-the-maximum-number-of-tcp-ip-connections-in-linux, časť "on server side". Taktiež prípadne ostatné paraetre... Ak budeš daľej zaseknutý, skús zagoogliť, ako sa tunovalo jadro pre erlang aplikácie a maximálny počet spojení. Minimálne nejaké buffre treba zvačšiť a podobne.

PS: UDP nie je možnosť?

Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #6 kdy: 19. 12. 2019, 14:39:34 »
Jak ten server spustis? PAM limity se tykaji konkretni login session.
Systemd ignoruje /etc/security/limits.conf a musi se nastavit v service.
Nejlepsi je spustis ten proces, podivat se na pid a zkontrolovat limity v /proc/PID/limits

Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #7 kdy: 19. 12. 2019, 15:48:23 »
Střelba od boku: nepoužíváš náhodou select()?
Tam je limit FD_SETSIZE pro jednu sadu socketů což může být zrovna těch 1024.
A navíc se zdá že to může mít problém s hodnotou handle>1023
Viz http://man7.org/linux/man-pages/man2/select.2.html

Pokud ano, tak zkus kouknout na alternativy (poll, epoll,...)

Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #8 kdy: 19. 12. 2019, 16:16:16 »
Dik za reakce, zkousim co se da...googleni, zmena bufru a nic nepomaha. Vse se zda ze by to melo fungovat.
Posledni reakce:
Citace
Střelba od boku: nepoužíváš náhodou select()?
Tak zde jsem ze zaseknul, protoze select skutecne pouzivam....

Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #9 kdy: 19. 12. 2019, 18:20:22 »
Posledni reakce:
Citace
Střelba od boku: nepoužíváš náhodou select()?
Tak zde jsem ze zaseknul, protoze select skutecne pouzivam....

Což mi odpovídá na otázku, jestli je ten server rozvlákněný. Inu: není.

Svého času na kernelu 2.4 jsem měl TCP server, který startoval asi 4 vlákna (threads) na každého přišedšího klienta. pthread_create() začal mít kecy někde nad 100 klienty. Po přechodu na kernel 2.6 to omezení zmizelo... ale kde je další strop, to netuším.

alex6bbc

  • *****
  • 1 432
    • Zobrazit profil
    • E-mail
Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #10 kdy: 19. 12. 2019, 19:38:16 »
tak predpripravit pool vlaken a kdyz prijde pozadavek, tak vlakno z poolu vyuzit at udela ten pozadavek.

koukl bych do nginxu.

Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #11 kdy: 19. 12. 2019, 20:44:24 »
Dik za reakce, zkousim co se da...googleni, zmena bufru a nic nepomaha. Vse se zda ze by to melo fungovat.
Posledni reakce:
Citace
Střelba od boku: nepoužíváš náhodou select()?
Tak zde jsem ze zaseknul, protoze select skutecne pouzivam....
Nedávno jsem si dělal takový teoretický průzkum tak jsem na to narazil.
Viz ten odkaz co jsem dával, pro takhle velký počet to na linuxu nejspíš nebude fungovat.
Ono obcně pro tolik socketů je select považován za pomalý a používá se spíš něco jako poll nebo epoll.
Případně nějaké knihovna co použije to co na danné platformě je, třeba libevent.

Jinak ten problém může být i jinde, jak už tu bylo napsáno, to bych nepodceňoval.
Možná by pomohl log návratovými hodnotami jednotlivých funkcí, nebo alespoň těch co vrací chybu :) .


Nějaké odkazy:
http://man7.org/linux/man-pages/man2/select.2.html
http://byteliu.com/2019/05/08/LINUX-–-IO-MULTIPLEXING-–-SELECT-VS-POLL-VS-EPOLL/
https://blog.cloudflare.com/io_submit-the-epoll-alternative-youve-never-heard-about/

Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #12 kdy: 19. 12. 2019, 22:39:43 »
Tak jsem zkusil ten celej server predelat ze select() na epool() podle tohodle prikladu:
http://www.voidcn.com/article/p-uvhjqbmi-uo.html
V tuhle chvili mi startujou klienti a uz jich je vic nez 1600. Zatim se nestal zadnej karambol, takze se zda ze to bylo skutecne maximalnim omezenim FD_SETSIZE, ktere je defaultne na 1024.

Problem tedy povazuju za vyreseny. Dik moc vsem zucastnenym, doufam ze Vam prace dela radost :)

Jest bych chtel dodat, ze to proc ten server padal jsem doposud uplne nepochopil. Zrejme to bylo zpusobeno volanim FD_ISSET, vstupni parametry jsem totiz nekontroloval. Asi se to zavolalo s nejakym nesmyslem a tim to spadlo. Tim uz se ale zabyvat nebudu.

Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #13 kdy: 20. 12. 2019, 22:53:05 »
Jen dodám, že select() nedoporučuju používat v žádném případě. Ani na čekaní na jeden descriptor. Stačí, když descriptor má číslo větší než FD_SIZE a program jde do háje. Za určitých okolností se to dá zneužít, takže to zároveň představuje bezpečnostní riziko, například pokud je FD_SET realizován v zásobníku, může útočník způsobit buffer overrun a hacknout se do kódu.

 Když už, tak poll, pak samozřejmě epoll. Na příkaz select() zapomeňte a vyhejbejte se mu jak čert kříži.

gill

  • ****
  • 270
    • Zobrazit profil
    • E-mail
Re:Maximální počet klientů vlastního TCP serveru
« Odpověď #14 kdy: 21. 12. 2019, 13:51:14 »
tak predpripravit pool vlaken a kdyz prijde pozadavek, tak vlakno z poolu vyuzit at udela ten pozadavek.

koukl bych do nginxu.

u trvalých socketových spojení nejde použít. Uvažoval bych o epoll nebo nějaké knihovně nad tím.