Valery's Mlog

Mindlog of a Freak
January 18th, 2006 by Valery Dachev

lighttpd + fastcgi + php

Както е известно, на??ата мрежа приютява може би най-големия webchat, който може да съществува. Написани от dzver на PHP и разчитащ изключително на javascript чат обаче товари ужасно. 800 постоянно висящи процеси (за всяка връзка по един) в Apache ядат безкрайно много памет и карат всеки сървър да клекне. След всички оптимизации на Apache и на ма??ината въобще, Mantra е като че ли неспособна да понесе повече. Затова тези дни тръгнах да експериментирам на гърба на горките потребители и тази вечер ще се види доколко съм успял.

Доколкото на ма??ината работят стра??но много сайтове с всевъзможни изисквания, модулите на Apache и раз??иренията на PHP са значително повече от тези идеално оптимизираното количество необходимо за самия webchat. Опитът показва, че всеки потребител заема около 3 Мб оперативна памет. Затова целта бе??е да пусна самия webchat някак отделно. В крайния вариант на установката съм се спрял на lighttpd и PHP стартирано от неговия FastCGI модул. На сайта на lighttpd могат да се намерят много полезни публикации за настройката на FastCGI и оптимизирането на сървъра. Ето и някои специфични настройки в lighttpd.conf със съответните коментари към тях:

### включен е само един единствен модул и това е FastCGI
server.modules              = (
           "mod_fastcgi",
)

### този ред увеличава максималния брой отворени файлови дескриптори на lighttpd
### и не включва тези на CGI програмите, които работят. за всеки случай тук са
### увеличени, макар това да се препоръчва само в случаите, когато в error.log на
### lighttpd се появят гре??ки от типа на "... accept() failed: Too many open files"
server.max-fds = 1024

### "Keepalive Requests" фунционалността дава възможност в рамките на една връзка
### да се обработят няколко заявки една след друга. Тъй като в самия webchat има
### доста картинки, давам възможност 10 от тях да се заредят една след друга.
server.max-keep-alive-requests  = 10

### макс. изчакване след обработка на заявка до подаването на следващата е 2 сек.
server.max-keep-alive-idle = 2

### този ред дава възможност lighttpd да си спести извикването на stat() функцията
### за всеки файл, като ке??ира състоянието му и го следи с помощта на FAM
### (http://savannah.nongnu.org/projects/fam/)
server.stat-cache-engine = "fam"

### проследяването на символичните връзки и проверката на правата за достъп до
### всеки клон, както и зациклянето на връзките, отнема време. ако няма такива,
### както е в случая, е добре тази функционалност да е изключена.
server.follow-symlink = "disable"

fastcgi.server              = (
        ".php" => ((
### следващите два реда указват съответно минималния и максималния брой
### стартирани FastCGI процеси. за PHP всяка от тези две стойности трябва да се
### умножи по стойността на PHP_FCGI_CHILDREN променливата, която, ако не е
### установена по-долу, има стойност по подразбиране - 8.
                "min-procs"             => 1,
                "max-procs"             => 1,
### това задава граничната бройка на чакащи заявки за един процес, за да
### се стартира друг, който да започне обработката. 1 не е добра стойност
### по принцип, но, заради незавър??ващите PHP процеси, не мога да си
### позволя заявки, които да ги изчакват
                "max-load-per-proc"     => 1,
### дава броя секунди, след които неизползван процес да замре. прекаленото
### намаляване на тази стойност води до увеличаване на натоварването при
### непостоянна честота на заявките. увеличаването и пък води до прекалено
### използване на системните ресурси, така че трябва да се търси баланс
                "idle-timeout"          => 10,
                "socket"                => "/tmp/php-fastcgi.sock",
### тази настройка изключва проверката за съществуване на документа преди
### подаването му към скрипта. от една страна наличието на тази настройка е
### добре, защото не се задейства изли??но PHP процес, който да обработва
### нещо несъществуващо. от друга изключването на проверката спестява
### извикването на stat() за съответния файл. добре е да е изключен при малък
### брой обръщения към несъществуващи документи (с това раз??ирение)
                "check-local"           => "disable",
### към извикването на PHP интерпретатора е подаден допълнителен параметър
### за пътя към специфичния за сървъра php.ini файл.
                "bin-path"              => "/usr/bin/php5-cgi -c /path/to/php.ini",
                "bin-environment" => (
### следват настройки на самото PHP. първата променлива на средата определя
### броя PHP процеси, които да се пуснат. в моя случай бройката е по-голяма,
### броят висящи процеси е минимум броя на online потребителите. втората
### променлива определя броя заявки, които PHP процесът да обработи преди
### да погине. кончината му води до автомагично разчистване на използваната
### от него памет, но и до малко натоварване необходимо за стартиране на нов
### процес
                        "PHP_FCGI_CHILDREN" => "1024",
                        "PHP_FCGI_MAX_REQUESTS" => "40"
                )
        ))
)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: