vps на debian 6: nginx + apache worker + php-fcgi

Главные вкладки

Аватар пользователя NoNeed NoNeed 28 февраля 2012 в 21:20

Добрый день. Раньше сайт + пара сайтиков крутилось на обчном шаред-хостинге. Бодро и шустро бегал, бед не знали. Сайт решили модернизировать, нагрузка на шаред возрасла и нас попросили съехать, предложив купить VPS.
ВПС оказался на OpenVZ, соответсвенно свопа нет.
Памяти 768М, burstable установлена в 1024, 40gb диск.
OS - Debian 6 x86. + ispmanager lite.

nginx-0.7.67-3+squeeze1
конфиг: https://gist.github.com/1933438
конфиг виртуального хоста: https://gist.github.com/1933451

apache2-2.2.16-6+squeeze6
конфиг:https://gist.github.com/1933464
конфиг виртуального хоста: https://gist.github.com/1933468

php5-5.3.3-7+squeeze8 в режиме FastCGI
конфиг: https://gist.github.com/1933540

mysql-server-5.1-5.1.49-3
конфиг: https://gist.github.com/1933474

сейсас без нагрузки вижу следующее:
https://gist.github.com/1933409

Сайт грузится примерно следующим образом: Нажимаем enter, ждем 3 секунды, затем сайт начинает прогружаться.
Залил html сайт - грузится на ура. тоесть статику ngnix прекрасно и быстро отдает.

Как диагностировать затык?
Это проблема в сопряжении nginx-apache или сам апач тупит, или fcgi?

Под нагрузкой полный армагедец...
Смущает особенно поведение php - процессы висят в памяти и занимают по 60-100 мегабайт.

Что тут можно наоптимизировать? Может кто юзает впсы в подобной конфигурации и поделится своими конфигами?

Буду очень длагодарен.

Комментарии

Аватар пользователя bsyomov bsyomov 29 февраля 2012 в 1:32

1. Понять, что вы в общем-то получили не аналог маленького выделенного сервера, а тот же шаред хостинг,наверняка с оверселлингом, плюс необходимость настройки и администрирования.

2. Как самый минимум, надо переехать на другой, более вменяемый шаред, а если посещаемость действительно велика, взять бюджетный сервер, или в самом крайнем случае, полноценную виртуалку у приличного хостера. И искать сисадмина, который его нормально настроит, и будет сопровождать, минимум решая проблемы по запросу, а лучше постоянно .

3. Если сайт один, или если их немного, панелька вам не нужна - она только загоняет вас в рамки своих шаблонных настроек, например в вашем случае, не даёт выкинуть, совершенно не нужный в вашей схеме апач.

4. процессы жрут аномально много памяти по причине "своеобразия" выделения памяти в openvz. Можно уменшить размер стека и ещё по всякому извращаться, но ето плохой выход - ничего хорошеого от вашей недовиртуалки ждать не стоит. Она лишь возможность для вашего хостера продолжить на вас зарабатывать, ограничив вам жёстко ресурсы и свалив на вас часть проблем, прекрывшись красивыми маркетинговыми высказованиями.

Аватар пользователя NoNeed NoNeed 29 февраля 2012 в 8:32

ЧТо этот тот-же шаред, только в профиль я понимаю.
Вы ведь админ, и занимаетесь настройкой? Цена вопроса с учетом подробного растолкования действий?
Для меня важно не просто настроить, а понимать что было настроено.
Спасибо.

Аватар пользователя bsyomov bsyomov 29 февраля 2012 в 9:17

Консультация бесплатно, в свободное время - пишите в скайп, посмотрим, что у вас вообще там творится.

Настройка от 2000р, OS, nginx, php-fpm, mysql, ftp(опционально - есть sftp, лишние сервисы лучше не запускать), почта(опционально - в вашем случае лучше внешний сервис), можно с толкованием. Smile

Но в любом случае, я крайне советую вам сначала переехать с вашего OpenVZ, на XEN|KVM|VMWare|Hyper-V пусть даже на тариф с меньшими ресурсами, зато более гарантированными, а лучше поискать хороший шаред, т.к. OpenVZ практически всегда тотальный оверселлинг, и очень высокая плотность виртуалок на сервер, и кроме памяти(которой у вас 768, а не 1024 (это по праздникам и рассчитывать на него не надо - если перестанут выделять, приложение её получившее будет убито, вот поясняющая картинка http://phpsuxx.blogspot.com/2010/02/openvz.html), будут ещё тормоза и по сети и по диску наверняка.

Аватар пользователя bsyomov bsyomov 29 февраля 2012 в 10:31

Да, среднее звено занимается только парсингом .htaccess по большому счёту и тратит на это огромное кол-во памяти. Но в варианте ТС она определяется используемой панелью, которая с одним nginx не полетит.

Аватар пользователя chilic chilic 29 февраля 2012 в 12:22

"bsyomov" wrote:
по большому счёту и тратит на это огромное кол-во памяти

Сомнительное утверждение Smile даже холиварное Smile

Однако nginx + php-fpm намного лучше чем nginx + apache + php-fcgi.

Аватар пользователя iryston iryston 29 февраля 2012 в 12:30

Зачем откатывать?
У меня все прекрасно работает в связке DEBIAN 6 + NGINX 1.0.1x + PHP-FPM 5.3 (Drupal 6 и 7)
Как сделать смотри тут
http://www.dotdeb.org/instructions/ (установка php-fpm + nginx)
https://github.com/perusio/drupal-with-nginx (конфиг nginx под друпал)

Правда вместо MySQL у меня Percona, но, я думаю, это большой роли не играет.

Аватар пользователя chilic chilic 29 февраля 2012 в 12:39

Как переписать апачевские правила для Drupal:

        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

при использовании nginx/FastCGI ?

Вот так:

        location / {
            try_files      $uri  $uri/  @drupal;
        }
                 
        location @drupal {
            fastcgi_pass   ...;

            fastcgi_param  SCRIPT_FILENAME  /path/to/index.php;
            fastcgi_param  SCRIPT_NAME      /index.php;
            fastcgi_param  QUERY_STRING     q=$uri&$args;

            ... прочие fastcgi_param
        }

Обычно практикуемая прямая трансляция правил:

        location / {
            if (!-e $request_filename) {
                rewrite  ^(.*)  /index.php?q=$1  last;
            }
        }

        location = /index.php {
            fastcgi_pass  ...
            ... прочие fastcgi_param
        }

достойна всяческого порицания.

(C) Игорь Сысоев

Аватар пользователя NoNeed NoNeed 1 марта 2012 в 18:41

gor wrote:
NoNeed wrote:
поставил nginx и php-fpm c этими https://github.com/perusio/drupal-with-nginx конфигами
чета капец как медленно ползет.

ради сравнения не хочешь на патруле поставить? На простой хостинг.

Поделитесь ссылочкой пожалуйста.

Аватар пользователя marazmus marazmus 1 марта 2012 в 9:50

Мне на свежеустановленной Ubuntu помогло в my.cnf

innodb_flush_log_at_trx_commit=2

Разбираться времени не было, но все заработало как надо, по скорости (мгновенное открытие страниц на свежеустановленном друпале).

Аватар пользователя NoNeed NoNeed 1 марта 2012 в 18:42

marazmus wrote:
Мне на свежеустановленной Ubuntu помогло в my.cnf

innodb_flush_log_at_trx_commit=2

Разбираться времени не было, но все заработало как надо, по скорости (мгновенное открытие страниц на свежеустановленном друпале).

к сожалению нет, я не использую я innodb

Аватар пользователя marazmus marazmus 1 марта 2012 в 9:52

"gor" wrote:
ради сравнения не хочешь на патруле поставить? На простой хостинг.

И да, +100 Гору, на патруле Друпалы летают без заморочек. Идеально для занятых людей, которым важно развивать сами сайты, а не трахаться с заморочками VDS и тупых хостеров.

Аватар пользователя NoNeed NoNeed 1 марта 2012 в 11:28

Может и попробуем, спасибо за совет.

Сталкнулся вот с какой проблемой:
php-fpm стартует от имени www-data, как и сам nginx.
пришлось на сайтах папкам sites/myste.com/files делать владельца www-data
есть способ запускать для каждого сайта отдельный процесс от имени пользователя сайта?

Аватар пользователя bsyomov bsyomov 1 марта 2012 в 13:06

"<a href="mailto:chilic@drupal.org">chilic@drupal.org</a>" wrote:
Сомнительное утверждение Smile даже холиварное Smile
Однако nginx + php-fpm намного лучше чем nginx + apache + php-fcgi.

В случае именно этой связки, нет ничего холиварного и сомнительного. А учитывая специфику выделения памяти Openvz для тредов, то таки да, огромное.

"NoNeed" wrote:
уговорили) попробую ночером откатить php до 5.2, накатить nginx + php-fpm отказавшись от апача.

Зачем для этого откатываться на 5.2?

"NoNeed" wrote:
есть способ запускать для каждого сайта отдельный процесс от имени пользователя сайта?

/etc/php5/fpm/pool.d - там лежит сейчас заготовка для 1 пула. Делаем нужное количество. Меняем сокет, пользователя, возможно кол-во процессов. В Nginx соответственно для определённого сайта прописываем сокет нужного пула.

"<a href="mailto:chilic@drupal.org">chilic@drupal.org</a>" wrote:
Есть, писать конфиг php-fpm для каждого сайта.
Либо использовать mpm-itk, что намного удобнее :)

Слегка удобнее, но намного медленее (и медленее остальных MPM) и потенциально опаснее, т.к. до момента принятия решения куда отнести запрос, работает ITK от root. Это очень спорный MPM, который не приняли за 4 года в апстрим.
Если и делать с апачем, то на нескольких экземплярах апача с MPM prefork. но в ситуации TC это не актуально.

Аватар пользователя NoNeed NoNeed 1 марта 2012 в 21:58

bsyomov wrote:

/etc/php5/fpm/pool.d - там лежит сейчас заготовка для 1 пула. Делаем нужное количество. Меняем сокет, пользователя, возможно кол-во процессов. В Nginx соответственно для определённого сайта прописываем сокет нужного пула.

чет не пойму как правильно указать это дело.
у nginx.conf проинклужено upstream_phpcgi_unix.conf
в котором в свою очереь прописаны юникс сокеты, которые должны работать шустрее чем tcp.

upstream phpcgi {
    fair;
    server unix:/var/run/php-fpm.sock;                #оригинальный
    server unix:/var/run/php-fpm.othersport.sock      #добавленый мною
    server unix:/var/run/php-fpm-zwei.sock;

}

upstream phpcgi_backup {
    server unix:/var/run/php-fpm-drei.sock;
}

сокеты активны, видны в процессах

519       1366  0.0  0.2  21792  2688 ?        S    20:56   0:00 php-fpm: pool othersport                        
519       1367  0.0  0.2  21792  2688 ?        S    20:56   0:00 php-fpm: pool othersport                        
519       1368  0.0  0.2  21792  2688 ?        S    20:56   0:00 php-fpm: pool othersport  

root@vps:/etc/nginx# netstat --unix -l
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ACC ]     STREAM     LISTENING     83936603 tmp/ispmgr.sock
unix  2      [ ACC ]     STREAM     LISTENING     83926718 /var/run/mysqld/mysqld.sock
unix  2      [ ACC ]     STREAM     LISTENING     83926441 /var/run/saslauthd/mux
unix  2      [ ACC ]     STREAM     LISTENING     83926385 /var/run/php-fpm.sock
<strong>unix  2      [ ACC ]     STREAM     LISTENING     83926387 /var/run/php-fpm.othersport.sock</strong>
unix  2      [ ACC ]     STREAM     LISTENING     83936605 tmp/ispmgr.adm.sock
unix  2      [ ACC ]     STREAM     LISTENING     83927067 /var/run/sendmail/mta/smcontrol

по идее теперь я могу их прописать в конфигах сервера как

...
server {
    listen ...;
    server_name ...;
    fastcgi_pass /var/run/php-fpm.othersport.sock;
...

но nginx ругается

root@vps:/etc/nginx/sites-available# service nginx restart
Restarting nginx: nginx: [emerg] "fastcgi_pass" directive is not allowed here in /etc/nginx/sites-enabled/othersport:20
nginx: configuration file /etc/nginx/nginx.conf test failed

где и какой директивой правильно указатьнужный сокет?

Аватар пользователя NoNeed NoNeed 1 марта 2012 в 16:07

Благодарю за подсказу! Многие бессоные ночи сбивают с толку и притупляют внимание...

Собственно сейчас проблема примерно такая-же как и в связке с апачем.
Запрос, ожидание 3-4 секунды, затем грузится контент.
если загрузка контента занимала на апаче порядка 2х секунд, то сейчас это 0.5-1с
косяк скорее всего в связке php <-> mysql?

Подскажите как диагностировать пожалуйста.

Аватар пользователя NoNeed NoNeed 1 марта 2012 в 21:02

<a href="mailto:chilic@drupal.org">chilic@drupal.org</a> wrote:
В этом тоже может быть проблема. Самое страшное - это блокировка таблиц. :)

skip-innodb прописано в конфиге. Оно не может влять на производительность.

Странно.

root@vps:/var/log/mysql# cat /var/log/mysql/mysql-slow.log
/usr/sbin/mysqld, Version: 5.1.58-1~dotdeb.1-log ((Debian)). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument

эти ведь параметры прописал?

log_slow_queries        = /var/log/mysql/mysql-slow.log
long_query_time = 1
Аватар пользователя NoNeed NoNeed 1 марта 2012 в 22:15

Попробовал позагружать страницу
/admin/reports/status/php
она ведь не лезет в базу?
пауза перед началом загрузки все-равно от 1.5 до 5-6 секунд, затем она прогружкется за 02-03 мс...
Значит дело не в базе? Где может так серьезно тупить php?

Аватар пользователя bsyomov bsyomov 1 марта 2012 в 23:48

"NoNeed" wrote:
чет не пойму как правильно указать это дело.
у nginx.conf проинклужено upstream_phpcgi_unix.conf
в котором в свою очереь прописаны юникс сокеты, которые должны работать шустрее чем tcp.

upstream phpcgi {
fair;
server unix:/var/run/php-fpm.sock; #оригинальный
server unix:/var/run/php-fpm.othersport.sock #добавленый мною
server unix:/var/run/php-fpm-zwei.sock;

}

upstream phpcgi_backup {
server unix:/var/run/php-fpm-drei.sock;
}

сокеты активны, видны в процессах


Ай-ай. Smile Либо несколько секций upstream, в каждой из которых по одному вашему пулу, но вам не нужно это, это для балансировки.
Либо fastcgi_pass unix:/path/to/socket;, fastcgi_pass при этом должен быть в location, где вы обрабатываете php, а отнюдь не в корне секции server.
Почитайте доки, примеры, проясните разум. Smile

На самом деле, надо было конечно начинать с поиска узкого места, а не с выкидывания апача, хотя это всё равно стоило сделать, и ещё не поздно найти в чём реальная проблема. Smile

Поднимите какой-нибудь munin, соберите статистику - использование процессора, выделение памяти, задержка обращения к диску, кол-во открытых tcp соединений, медленные запросы в mysql (включите их логирование).

Да, на сладкое - когда всё сделаете и у вас всё будет хорошо работать, можете ещё изолировать ваши сайты с помощью chroot - это полезно. Smile

Аватар пользователя NoNeed NoNeed 2 марта 2012 в 11:16

Ерунда какая-то. Прописал нужный сокет в location, сокет работает, процесс запущен от нужного пользователя.
Даю нагрузку на сайт и вижу что робит php-fpm запущенный вовсе не от hudfond а от www-data

root@vps:~# vim /etc/php5/fpm/pool.d/hudfond.conf
[hudfond]
listen = /var/run/php-fpm.hudfond.sock
;listen.allowed_clients = 127.0.0.1

listen.owner = hudfond
listen.group = hudfond
listen.mode = 0600

user = hudfond
group = hudfond

pm = dynamic
pm.max_children = 6
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 5
pm.max_requests = 500

;pm.status_path = /fpm-status
;ping.path = /ping
;ping.response = pong
request_terminate_timeout = 120s
request_slowlog_timeout = 5s
slowlog = /var/log/$pool.log.slow
rlimit_files = 4096
rlimit_core = 0
;chdir = /var/www/hudfond/
catch_workers_output = yes

сам конфиг хочта вот как выглядит

server {
        listen myip;
        server_name mysite;
        limit_conn arbeit 32;

        ## Access and error logs.
        access_log /var/www/nginx-logs/hudfond.com.access.log;
        error_log /var/www/nginx-logs/hudfond.com.error.log;

        ## Filesystem root of the site and index.
        root /var/www/hudfond/data/www/hudfond.com;
        index index.php;

location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
        fastcgi_pass unix:/var/run/php-fpm.hudfond.sock;
#       fastcgi_pass unix:/var/run/php-fpm.sock;
        include sites-available/microcache_fcgi.conf;
}

location ~ /\.ht {
        deny all;
}

location ~ \.php$ {
        if (!-f $request_filename) {
                rewrite  ^(.*)$  /index.php last;
       }
#       fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_pass unix:/var/run/php-fpm.hudfond.sock;
        include sites-available/microcache_fcgi.conf;
}

## All static files will be served directly.
#location ~* \.(js|css|png|jpg|jpeg|gif|swf|xml|txt)$ {
location ~* ^.+\.(?:css|js|jpe?g|gif|htc|ico|png|swf|html|txt|xml)$ {
        access_log off;
        expires 30d;
        tcp_nodelay off;
        open_file_cache max=3000 inactive=120s;
        open_file_cache_valid 45s;
        open_file_cache_min_uses 2;
        open_file_cache_errors off;
}

location = /favicon.ico {
        log_not_found off;
        access_log off;
}

} # HTTP server

естетсвенно после изменений переталкивал апач и пхп
service nginx restart
service php5-fpm restart

может пользователю hudfond надо дать права на что-то?

Аватар пользователя bsyomov bsyomov 2 марта 2012 в 11:45

А что в sites-available/microcache_fcgi.conf?

Вообще у вас конфиг не корректен. Вам надо читать документацию.
Должно быть в общих чертах так:

location / {
  try_files $uri $uri/ /index.php?q=$uri&$args;
}

location ~ \.php$ {
  try_files $uri =404;
  include fastcgi_params;
  fastcgi_pass unix:/var/run/php-fpm.hudfond.sock;
}

А в настройках пула:

listen.owner = www-data
listen.group = www-data

Или другой пользователь, от которого запущен nginx, если он запущен не от www-data.

Аватар пользователя NoNeed NoNeed 2 марта 2012 в 12:45

кажись заработало)

### Implementation of the microcache concept as presented here:
### http://fennb.com/microcaching-speed-your-app-up-250x-with-no-n

## The cache zone referenced.
fastcgi_cache microcache;
## The cache key.
fastcgi_cache_key $host$request_uri;

## For 200 and 301 make the cache valid for 1s seconds.
fastcgi_cache_valid 200 301 15s;
## For 302 make it valid for 1 minute.
fastcgi_cache_valid 302 1m;
## For 404 make it valid 1 second.
fastcgi_cache_valid 404 1s;
## If there are any upstream errors or the item has expired use
## whatever it is available.
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
## The Cache-Control and Expires headers should be delivered untouched
## from the upstream to the client.
fastcgi_ignore_headers Cache-Control Expires;
## If we have a cookie we should bypass the cache. The same if we have a
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
## Add a cache miss/hit status header.
add_header X-Micro-Cache $upstream_cache_status;
## To avoid any interaction with the cache control headers we expire
## everything on this location immediately.
expires epoch;
## If you're using a Nginx version greater than 1.1.11 then uncomment
## the line below. See:
## http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache...
## Cache locking mechanism for protecting the backend of too many
## simultaneous requests.
#fastcgi_cache_lock on;
## The default timeout, i.e., the time to way before forwarding the
## second request upstream if no reply as arrived in the meantime is 5s.
# fastcgi_cache_lock_timeout 8000; # in miliseconds.

Аватар пользователя bsyomov bsyomov 2 марта 2012 в 22:16

microcache этот стоит выключить нафиг. Вообще эта концепция очень ограничено применима.
Кешировать на фронтэнде можно, но нормальная реализация намного сложнее. Эта реализация для сайта где нет, например, зарегистрированных пользователей, кол-во запросов на 1 url > 2 во время жизни кеша и.т.п. Да и вообще придумана для совершенно отличной от вашей ситуации, когда подержав секунду контент на одном из многих фронтэндов, можно уменьшить в разы количество запросов к бекэнду, как временная мера, пережить пик посещаемости.
Лучше озаботьтесь правильной настройкой кеширования в Drupal и проверьте стоит-ли у вас APC или аналогичный кешер опкодов.