Задать вопрос

Httpd начинает жрать память... и вешается?

Есть один сайт, средней посещаемости. Крутится он на VPS с двумя гигами памяти (плюс два — своп) под Fedora (не помню, какой версии). Работал он замечательно до прошлых выходных. Почему-то Apache начал сжирать всю память без остатка, потом сжирал своп, после чего сервер буквально ложился. Впрочем, иногда он ложился раньше, с сообщением от oom killer'а в логах.

Следуя многочисленным советам в сети, я настроил выдачу статики через nginx, добавил памяти на eAccelerator, слегка перенастроил MySQL, и отследил наиболее часто запрашиваемые файлы (это оказались три скрипта, запрашиваемые аяксом; в них я просто добавил кэширование через shared memory).


Кусок httpd.conf:
KeepAlive Off<br/>
RLimitMEM 67108864 # 64 мегабайта я поставил уже под конец, потому что ограничение в гигабайт не помогало<br/>
RLimitCPU 20<br/>
# Честно говоря, не знаю, который из MPM используется, менял сразу оба. Но вроде не особо много стоит<br/>
&lt;IfModule prefork.c&gt;<br/>
StartServers 2<br/>
MinSpareServers 2<br/>
MaxSpareServers 8<br/>
ServerLimit 50<br/>
MaxClients 30<br/>
MaxRequestsPerChild 50<br/>
&lt;/IfModule&gt;<br/>
&lt;IfModule worker.c&gt;<br/>
StartServers 2<br/>
MaxClients 50<br/>
MinSpareThreads 5<br/>
MaxSpareThreads 30<br/>
ThreadsPerChild 15<br/>
MaxRequestsPerChild 50<br/>
&lt;/IfModule&gt;<br/>
Listen 127.0.0.1:8101 # Для nginx<br/>
HostnameLookups Off<br/>


MySQL:
[mysqld]<br/>
datadir=/var/lib/mysql<br/>
socket=/var/lib/mysql/mysql.sock<br/>
user=mysql<br/>
<br/>
low-priority-updates=yes<br/>
skip-external-locking=yes<br/>
skip-name-resolve=yes<br/>
skip-networking=yes<br/>
<br/>
bind-address=127.0.0.1<br/>
max_connections = 128<br/>
thread_cache_size = 16<br/>
query_cache_size = 64M<br/>
query_cache_type = ON<br/>
<br/>
symbolic-links=0<br/>


Кусок nginx.conf:
user nginx;<br/>
worker_processes 2;<br/>
worker_priority -1;<br/>
events {<br/>
 worker_connections 1024;<br/>
 use epoll;<br/>
}<br/>
<br/>
http {<br/>
 include /etc/nginx/mime.types;<br/>
 default_type application/octet-stream;<br/>
 log_format main '$remote_addr - $remote_user [$time_local] &quot;$request&quot; '<br/>
 '$status $body_bytes_sent &quot;$http_referer&quot; '<br/>
 '&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;';<br/>
 access_log /var/log/nginx/access.log main;<br/>
 sendfile on;<br/>
 keepalive_timeout 65;<br/>
 server_names_hash_bucket_size 64;<br/>
 include /etc/nginx/conf.d/*.conf;<br/>
}<br/>


Кусок секции server в отдельном файле у nginx:
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {<br/>
 root /var/www/indee;<br/>
 access_log off;<br/>
 expires 1d;<br/>
 add_header Last-Modified: $date_gmt;<br/>
 }<br/>
<br/>
location ~ /\.ht {<br/>
 deny all;<br/>
 }<br/>
<br/>
location / {<br/>
 proxy_pass <a href="http://127.0.0.1">127.0.0.1</a>:8101/;<br/>
 proxy_redirect off;<br/>
<br/>
proxy_set_header Host $host;<br/>
 proxy_set_header X-Real-IP $remote_addr;<br/>
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;<br/>
<br/>
client_max_body_size 10m;<br/>
 client_body_buffer_size 128k;<br/>
<br/>
proxy_connect_timeout 90;<br/>
 proxy_send_timeout 90;<br/>
 proxy_read_timeout 90;<br/>
 <br/>
 proxy_buffer_size 4k;<br/>
 proxy_buffers 4 32k;<br/>
 proxy_busy_buffers_size 64k;<br/>
 proxy_temp_file_write_size 64k;<br/>
 }<br/>


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

Версии:
Server version: Apache/2.2.3<br/>
Server built: Jan 31 2011 17:50:30

nginx: nginx version: nginx/1.0.0
PHP 5.3.6 (cli) (built: Apr 19 2011 13:21:12) <br/>
Copyright © 1997-2011 The PHP Group<br/>
Zend Engine v2.3.0, Copyright © 1998-2011 Zend Technologies<br/>
 with eAccelerator v0.9.6-svn358-dev, Copyright © 2004-2007 eAccelerator, by eAccelerator

mysqld_multi version 2.16 by Jani Tolonen

Фишка в том, что все работает некоторое время просто отлично. Но через несколько часов процессы httpd начинают просто неприлично жрать память и опять все виснет, причем рестарт апача не помогает (пишется, что не удается остановить службу). В чем причина такого поведения — просто теряюсь в догадках и прошу совета.
  • Вопрос задан
  • 10150 просмотров
Подписаться 3 Оценить 2 комментария
Пригласить эксперта
Ответы на вопрос 3
Wott
@Wott
Начинат надо с status и info для apache. Смотреть в сторону:

SetHandler server-status
SetHandler server-info

Дальше смотреть в какой mode: если prefork то это скорее всего безудержное размножение children. Если worker то где-то память хотят много и не освобождают. Как вариант — баг в Апаче или модуле. Но скорее всего — багнутый скрипт.

Делать мониторинг состояния apache и по нему и логам надо воспроизводить и локализовывать проблему.
Первое — анализ логов запросов — искать что повторяется каждый раз когда память утекает и проверять.
Второе — отключать по очереди и смотреть.

А в целом вопрос из разряда «у не работает Х. Что мы сделать что бы заработало ?»
Ответ написан
Комментировать
@Yashin
Но через несколько часов процессы httpd начинают просто неприлично жрать память и опять все виснет, причем рестарт апача не помогает (пишется, что не удается остановить службу).

Очень похоже на утечку памяти. Может есть какой-то скрипт, который не завершается, а продолжает висеть в памяти (max_execution_time в нем выставлен в 0)?
Ответ написан
homm
@homm
Посмотрите, где лежат сессии. Если на диске, посчитайте, сколько там файлов.
find /path/to/folder -type f | wc -l
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы