Apache - server reached MaxClients setting

Sziasztok

Van egy Apache webszerverem, ami másodpercenként átlagosan 15 kérést szolgál ki. Nekem ez nem tűnik túl nagy számnak. Ennek ellenére van, hogy elfogy a szabad szlotok száma a szerver alól, amit a tárgyban említett hibaüzenet követ a logban és elérhetetlenné válik a webszerver.

A konfigok állítgatásával már próbálkoztam. Szinte mindent kipróbáltam, ami nekem logikus volt, de semmi nem vitt előrébb. Ugyan az volt a helyzet, hogy teljesen rapszodikusan elkezd fogyni a szlotok száma. Még akkor is előfordul, amikor alig van terhelése a webszervernek.

A logokat turkálva nem látok DoS támadásra utaló jeleket. Tehát vagy beállítás hiba, vagy pedig apache bug. Akinek esetleg van tapasztalata ezen téren megosztaná velem?

Apache konfigom ide vonatkozó része:

Timeout 120
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

StartServers 25
MinSpareServers 15
MaxSpareServers 32
ServerLimit 1000
MaxClients 1000
MaxRequestsPerChild 300

Előre is köszönöm az építő jellegű hozzászólásokat.

Hozzászólások

Ilyen nem számottevő forgalom esetén, igen valószínű hogy a hiba valamelyik php szkriptedben van. Trace-eld le mi történik az apache szállal.

--------------
Sok ember hord Superman-pizsamát. Superman Chuck Norris-pizsamát hord.

Mindenképp meg kell nézned az apache logokat, hogy milyen kéréseket kap a szerver a problémás időszakban.
Azt kell kiderítened, hogy szabályos forgalom, vagy DoS/DDos jellegű támadás van a háttérben.
Szabályos forgalomnál az alkalmazást kell átnézni (mennyi ideig tart az oldalgenerálás, lehet-e alkalmazásszintű cache-t készíteni: a lényeg, hogy gyorsítani kell).
Ha viszont DoS támadással veszi el valaki az apache kapacitását, akkor:
- megfelelő tűzfalszabályok (pl. slowloris ellen -- http://ha.ckers.org/slowloris/)
- apache kiegészítő modulok: pl. mod_evasive
ami segíthet.

A következők jutnak hirtelen eszembe:

  • meg lehet próbálni a keep-alive kikapcsolását átmenetileg
  • le kell ellenőrizni, hogy van-e valahol névfeloldás a feldolgozásban (apache log, apache konfiguráció, php-n belül, külső rendszer felé kérés, pl. SSO vagy valami hasonló)
  • töltenek le nagy méretű statikus fájlokat (vagy akár php-n keresztül nagy méretű adatot), ami viszonylag sokáig tart (foglal egy apacs processzt)

Még valami: ha az apache apache2-mpm-prefork konfigurációban dolgozik, akkor a gép lefektetéséhez bőven elegendő jó sok http connection felépítése. Ha minden apacs process csak 3 MB-ot foglal, akkor is 3 GB lesz a vége. Ez alaposan megdolgoztathatja a lemezt, kihúzhatja a MySQL alól is a disk cache-t.

Most eszembe jutott, hogy mennyit szívtam az indiánnal, amíg végkép meg nem szabadultam tőle :)

Névfeloldás nincs. Az egészen biztos. Továbbá nagy méretű fájlokat se töltenek le.

http://cubesys.hu/munin.png

A mellékelt képen jól látszik, hogy olyan hajnali 4 körül semmi terhelés nem volt a gépen, ennek ellenére 400 szálam foglalt volt. Az ilyen grafikon részeket nem tudom hova tenni.

Az access.log alapján nem lehet kimutatni semmit?
Valami spider vagy egyéb adatgyűjtő? Némely crawler eléggé meg tudja húzni az oldalt, főleg ha nagyon régi, lemezen lévő adatokat kell előbányászni. Bár kicsit ellentmondásos, nem hiszem, hogy 400 connection-t használna :)
Mit csinál közben a gép? Lemez, memória, cpu?

A memória elfogy teljesen. Van amikor elkezd swappelni (nah nem 400 connection után, hanem amikor felmegy ezerig a kapcsolatok száma).
CPU szinte nulla terhelést kap.
IO-nál látok egy kis terhelést, de még az is bírja.
Load felmászik, de még az sem vészes.

Viszont az apache elszáll.

Mégegyszer megnéztem alaposan a grafikonokat...
Ami most feltűnt, hogy szép szabályos periodicitást mutat a reggel négytől ötig tartó időszakban a terhelés.
Vissza kellene nézni pár napra és ha ezt a mintát tartja, akkor mindenképpen alaposan átnéznék minden beütemezett karbantartót a szoftver-raid resync-től (ha van ilyen) az adatbázismentésig. Átnézni a crontab-ot, a weblap által indított job-okat, stb. Keresni 4 óra körül induló feladatokat.
Ezzel kezdeném...
Ha nem találok semmit, akkor jönnének a külső lehetőségek. Más szerverről van-e bármi hozzáférés ehhez? Bármi, ami be van ütemezve és eléri az oldalt, az adatbázist, stb. Hírlevélkiküldés indítása, stb...
Ja igen. MySQL mysql-slow.log alapos áttanulmányozása adott időszakra és nagyon előnyös, ha a weblap készít részletes error logot is a SQL hibákról. Gyorsan észre lehet venni az SQL-injection próbálkozásokat ;)

Úgy látom még nem javasolta senki a server-status használatát. A beállítása egyszerű. Persze ha elfogytak az apache szálak, akkor már késő, de addig pl. cronnal percenként lemented a server-statust, és akkor az elfogyás előtti állapotban megnézed mi foglalta a szálakat.