Beste forum gebruikers,
Ik zal eerst wel even de situatie uitleggen, ik heb een Poll website gemaakt die gebruikt kan worden door Twitch.tv streamers om "Subscriber" of "Follower" only polls te maken. Het idee kwam van een wel bekende website binnen de twitch community "Strawpoll.me". Nu ben ik van een volledige php website waarmee de result pagina realtime was gemaakt door via javascript de result api te pollen en een mysql backend voor alle data overgestapt naar realtime updates via een websocket server. De de server die de websocket aan drijft heeft ook een tcp poort die ik gebruik om vanuit php alle data op te vragen (dus geen mysql meer). Deze server is geschreven in C++ en heeft veel betere performance dan een mysql achtergrond te gebruiken. Onder andere loginchecks worden via de tcp socket aan de pollserver gedaan.
(tcp socket wordt dus ALLEEN door php aangesproken, websocket door de browser)
Een voorbeeld van een poll: http://streampoll.tv/4110
Mijn probleem:
Ik open een connectie naar de pollserver door middel van een tcp socket vanuit php, deze socket open ik door middel van fsockopen en die sluit ik na de request ook meteen.
Het probleem daarmee is dat de server maar beschikt over 30.000 usuable ports, en dat na het aanroepen van fclose() de poort in een 60 seconden time_wait komt te staan. Dit zou betekenen een theoretische gemiddelde van maximaal 500 verzoeken per seconde. Nu komt tijdens een druk bezochten poll (een streamer kan wel 40.000 kijkers hebben) de reuqest per seconde veel hoger uit en krijg ik dus een probleem met de poorten.
tcp_tw_recycle en tcp_tw_reuse op linux geven geen uitkomst, hiermee recycled die de poorten wel maar het veroorzaakt daarnaast ook veel timeouts, de verbinding wordt dus niet meer betrouwbaar.
Nu zag ik de optie van pfsockopen (persistent). Welke in theory een socket connectie PER worker aan zou moeten maken. Dus zou het maximaal aantal connecties oplopen tot 1024 (php-fpm workers). Dit is verder helemaal geen probleem. Stel ik doe nu een benchmark run op mijn api, dan zal het aantal connecties tot 1024 oplopen en niet hoger. Maar als ik nu met mijn browser ga refreshen op de pagina dan opent hij nog eens 1024 connecties.
Op een of andere manier blijkt pfsockopen() per client(ip address) een extra persistent connectie op de worker open te zetten. Ik begrijp absoluut niet waarom PHP dit zou doen en zover ik lees over de functie is dat ook niet de bedoeling?
SETUP:
Debian 8.1 amd64
NGINX 1.8 (stable)
PHP Version 5.6.8
In praktijk draait er ook varnish om de api calls te cachen.
Een heel verhaal dus, ik wou zo veel mogelijk info/achtergrond geven over mijn situatie.
Om het even kort te stellen:
Ik wil pfsockopen gebruiken om persistent connecties te openen op mijn php workers. Elke php worker heeft dus uiteindelijk een connectie persistent open staan. Echter op het moment opent die per client_ip een persistent connectie. Het aantal connecties kan bij 30 mensen die continu f5 drukken en dus rouleren door de workers 30x1024 persistent connecties openen. Terwijl het idee max 1 per worker is.
Ideeën?
Ik zal eerst wel even de situatie uitleggen, ik heb een Poll website gemaakt die gebruikt kan worden door Twitch.tv streamers om "Subscriber" of "Follower" only polls te maken. Het idee kwam van een wel bekende website binnen de twitch community "Strawpoll.me". Nu ben ik van een volledige php website waarmee de result pagina realtime was gemaakt door via javascript de result api te pollen en een mysql backend voor alle data overgestapt naar realtime updates via een websocket server. De de server die de websocket aan drijft heeft ook een tcp poort die ik gebruik om vanuit php alle data op te vragen (dus geen mysql meer). Deze server is geschreven in C++ en heeft veel betere performance dan een mysql achtergrond te gebruiken. Onder andere loginchecks worden via de tcp socket aan de pollserver gedaan.
(tcp socket wordt dus ALLEEN door php aangesproken, websocket door de browser)
Een voorbeeld van een poll: http://streampoll.tv/4110
Mijn probleem:
Ik open een connectie naar de pollserver door middel van een tcp socket vanuit php, deze socket open ik door middel van fsockopen en die sluit ik na de request ook meteen.
Het probleem daarmee is dat de server maar beschikt over 30.000 usuable ports, en dat na het aanroepen van fclose() de poort in een 60 seconden time_wait komt te staan. Dit zou betekenen een theoretische gemiddelde van maximaal 500 verzoeken per seconde. Nu komt tijdens een druk bezochten poll (een streamer kan wel 40.000 kijkers hebben) de reuqest per seconde veel hoger uit en krijg ik dus een probleem met de poorten.
tcp_tw_recycle en tcp_tw_reuse op linux geven geen uitkomst, hiermee recycled die de poorten wel maar het veroorzaakt daarnaast ook veel timeouts, de verbinding wordt dus niet meer betrouwbaar.
Nu zag ik de optie van pfsockopen (persistent). Welke in theory een socket connectie PER worker aan zou moeten maken. Dus zou het maximaal aantal connecties oplopen tot 1024 (php-fpm workers). Dit is verder helemaal geen probleem. Stel ik doe nu een benchmark run op mijn api, dan zal het aantal connecties tot 1024 oplopen en niet hoger. Maar als ik nu met mijn browser ga refreshen op de pagina dan opent hij nog eens 1024 connecties.
Op een of andere manier blijkt pfsockopen() per client(ip address) een extra persistent connectie op de worker open te zetten. Ik begrijp absoluut niet waarom PHP dit zou doen en zover ik lees over de functie is dat ook niet de bedoeling?
SETUP:
Debian 8.1 amd64
NGINX 1.8 (stable)
PHP Version 5.6.8
In praktijk draait er ook varnish om de api calls te cachen.
Een heel verhaal dus, ik wou zo veel mogelijk info/achtergrond geven over mijn situatie.
Om het even kort te stellen:
Ik wil pfsockopen gebruiken om persistent connecties te openen op mijn php workers. Elke php worker heeft dus uiteindelijk een connectie persistent open staan. Echter op het moment opent die per client_ip een persistent connectie. Het aantal connecties kan bij 30 mensen die continu f5 drukken en dus rouleren door de workers 30x1024 persistent connecties openen. Terwijl het idee max 1 per worker is.
Ideeën?
3X Multiplus II 10KVA, 2x MPPT RS 450/200, 48v 82kWh LiFePO4, 21kwp PV