Autor Zpráva
sniclman
Profil *
Ahoj, potřeboval bych poradit s vyčerpání maximálního počtu běžících procesů.
Provozuji na jednom eshopu vlastní chat pro zákazníky. Nastal ale problém s počtem soucačně běžících PHP procesů.

Příklad:
1. AJAX zavolá metodou GET soubor chat.php (s nějakými proměnnými GET)

2. chat.php se připojí k databázi, a pak ve smyčce (po dobu 20 sekund) kontroluje zda nedošlo v databázi pro danou komunikační relaci ke změně.
-->pokud přesáhne 20 sekund vrátí false
-->pokud dojde ke změně zobrazí změněná data

3.AJAX přijme data, zobrazí je uživateli a zavolá znovu soubor chat.php

Problém je, že takhle vznikne běžící PHP proces který trvá 20 sekund a pokud se připojí 10 uživatelů vznikne takto 10 souběžně běžích procesů a další procesy nejsou k dispozici => nezobrazí dalšímu uživateli web dokud není ukončen některý z procesů.

Prozatím jsem to vyřešil tak, že PHP neběží ve smyčce a odesílá data z databáze ihned. AJAX po zobrazení dat počká 2 sekundy a zavolá znovu soubor chat.php. Připadne mi ovšem, že se odesílá zbytečně moc datazů na soubor chat.php.
Původní řešení odesílá uživateli data jen jednou za 20 sekund (pokud nedojde ke změně).

Máte prosím nějaké vhodné řešení nebo radu jak tento problém eliminovat?
Zechy
Profil
sniclman:
a pak ve smyčce (po dobu 20 sekund)
To je trošku nešťastné řešení. Většinou se po nějakým intervalu odešle AJAXově požadavek na server, jestli není něco nového.

A rychlejší než AJAX je WebSocket (i datově méně náročnější, když se přenásí kvanta dat, tak ušetřená data hodně rostou, co jsem tak kdysi o tom četl), dle dostupných prostředků se to dá napsat i v PHPku (vyřešil jsem takhle multiplayer k ročníkovce). Jenže tam ti ten skript musí běžet v nekonečném cyklu v konzoli.
sniclman
Profil *
Zechy:
Ve smyčce je použita funkce sleep(1); aby to kontrolovalo každou sekundu.
Zechy
Profil
sniclman:
Stejně je to neštastné řešení, takhle se dvacet vteřin čeká, než se server na aktuální požadavek uráčí odpovědět.

Ptát se co 5 vteřin AJAXem výjde lépe - server odpoví už třeba do vteřiny a neběží vedle 50 procesů, které skončí až za 20 vteřin. Šikovné pak je i to, jakým stylem třeba fungoval chat na seznamu, čím déle uživatel nepsal, tím déle trvalo, než se jeho prohlížeč serveru znova zeptal. Tím se opět snižuje zátěž na množství požadavků.
juriad
Profil
sniclman:
Ten tvůj způsob by fungoval, ale bohužel ne s Apachem, musel bys použít nějaký speciální webový server, který nemá problém s udržením mnoha spojení. Tedy takový, který nevytváří pro každé spojení nové vlákno, ale zvládne v jednom vláknu obsluhovat všechny (asynchronní funkce pro práci se sockety nebo plně sekvenční zpracování).
Napřiklad Node.js běží v jednom vláknu a zpracovává vždy jen jeden požadak, ale ten požadavek může odložit práci na později funkcí setTimeout. Node.js nepodporuje PHP, umí jen JS na straně serveru, pokud jej použiješ jen na ten AJAX, může klidně běžet vedle PHP serveru na jiném portu.

Tvůj přístup také má problém se škálováním spojení k databázi. To může mít ještě menší limity než počet http spojení. Před sleepem by ses měl od databáze odpojit a po sleepu znovu připojit.
sniclman
Profil *
juriad:
No bohužel je eshop provozován na klasickém webhostingu. Takže nějaké rozšířené nastavení nehrozí.
Platforma Node.js může/nemůže být provozována na standardním webhostingu? (nemám s tím žádné zkušenosti)

Zechy:
Nad řešením jako je na seznamu jsem už přemýšlel a nejspíš to tak asi udělám.


Mimochodem na facebooku se odesílá v chatu požadavek GET a trvá v průměru 50 sekund (odtud jsem bral první inspiraci. Ale FB bude mít kdo ví jak nastavené servery).
Alphard
Profil
sniclman [#6]:
Provozovat vedle PHP aplikace ještě Node.js aplikaci, která bude víceméně duplikovat podstatnou část té PHP části se mi nezdá ideální. Jestli s tím má juriad zkušenosti, možná by to zprovoznil rychle, ale jinak s tím bude hromada problémů.

Jak moc je vaše aplikace vytížená? Je opravdu potřeba systémově řešit velké množství paralelní chatů, nebo stačí trochu opravit velmi špatně napsané řešení?

1. V první fázi bych vyhodil tu smyčku z PHP části, když není nic nového, ať hned vrátí false.
2. Javascript upravit tak, ať se po neúspěchu nedotazuje serveru hned, ale ať chvíli počká (a jak bylo uvedeno výše, ať čeká stále déle a déle).
sniclman
Profil *
Alphard:
Aplikace je vytížená podle návštěvnosti (průměrně 250 návštěv za den) + administrátorský chat.

1. Smyčku jsem už vyhodil, nebylo možné zobrazit stránky při velké návštěvnosti.
2. Zatím mám nastavenou prodlevu na 1 sekundu. Novou verzi předělám s prodlužování prodlevy.

Jiné řešení pro běžné hostingy asi není. Děkuji všem za pomoc s řešením problému.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: