Я веду веб-сайт и отправляю подписчикам ежедневную рассылку новостей по электронной почте. И веб-хостинг, и отправка электронной почты выполняются на одной машине.
У меня около 100 000 подписчиков, которые подписались на мою ежедневную рассылку новостей по электронной почте. Мой PHP-скрипт до недавнего времени неплохо справлялся с отправкой писем всем им, но по мере того, как список рос, я не успеваю за ним.
Когда я бегу на вершине, у меня очень высокая нагрузка - обычно не менее 6 или 7, иногда до 15 - хотя у меня всего два процессора. Однако, когда я запускаю sar, мой процессор простаивает в среднем около 30% времени. Итак, похоже, я не привязан к процессору. Когда я запускаю iostat, мне кажется, что я не привязан к диску, потому что мой% util для каждого устройства очень низкий (не более 5%).
Учитывая, что я, похоже, не привязан к процессору или к диску, почему топ сообщает о такой высокой нагрузке?
Кроме того, поскольку я, похоже, не привязан к процессору или диску, почему мой скрипт отправки электронной почты не успевает?
Вот что я вижу, когда забегаю на вершину:
top - 11:33:28 up 74 days, 18:49, 2 users, load average: 7.65, 8.79, 8.28
Tasks: 168 total, 5 running, 162 sleeping, 0 stopped, 1 zombie
Cpu(s): 38.9%us, 58.6%sy, 0.8%ni, 0.0%id, 0.7%wa, 0.2%hi, 0.8%si, 0.0%st
Mem: 3083012k total, 2144436k used, 938576k free, 281136k buffers
Swap: 2048248k total, 39164k used, 2009084k free, 1470412k cached
Вот что я вижу при запуске iostat -mx:
avg-cpu: %user %nice %system %iowait %steal %idle
34.80 1.20 55.24 0.37 0.00 8.38
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 0.19 71.70 1.59 29.45 0.02 0.07 5.90 0.55 17.82 1.16 3.59
sda1 0.00 0.00 0.00 0.00 0.00 0.00 7.10 0.00 13.80 13.72 0.00
sda2 0.05 50.45 1.13 24.57 0.01 0.29 24.25 0.35 13.43 1.15 2.97
sda3 0.05 10.17 0.20 2.33 0.01 0.05 43.75 0.05 20.96 2.45 0.62
sda4 0.00 0.00 0.00 0.00 0.00 0.00 2.00 0.00 70.50 70.50 0.00
sda5 0.07 0.22 0.03 0.07 0.00 0.00 32.84 0.08 856.19 8.03 0.08
sda6 0.02 5.45 0.03 0.72 0.00 0.02 67.55 0.02 26.72 5.26 0.39
sda7 0.00 1.56 0.00 0.42 0.00 0.01 38.04 0.00 8.88 5.84 0.24
sda8 0.01 3.84 0.20 1.35 0.00 0.02 28.55 0.05 31.90 4.08 0.63
Вот что я вижу при запуске sar:
09:40:02 AM CPU %user %nice %system %iowait %steal %idle
09:50:01 AM all 30.59 1.01 49.80 0.23 0.00 18.37
10:00:08 AM all 31.73 0.92 51.66 0.13 0.00 15.55
10:10:06 AM all 30.43 0.99 48.94 0.26 0.00 19.38
10:20:01 AM all 29.58 1.00 47.76 0.25 0.00 21.42
10:30:01 AM all 29.37 1.02 47.30 0.18 0.00 22.13
10:40:06 AM all 32.50 1.01 52.94 0.16 0.00 13.39
10:50:01 AM all 30.49 1.00 49.59 0.15 0.00 18.77
11:00:01 AM all 29.43 0.99 47.71 0.17 0.00 21.71
11:10:07 AM all 30.26 0.93 49.48 0.83 0.00 18.50
11:20:02 AM all 29.83 0.81 48.51 1.32 0.00 19.52
11:30:06 AM all 31.18 0.88 51.33 1.15 0.00 15.47
Average: all 26.21 1.15 42.62 0.48 0.00 29.54
Вот несколько процессов, перечисленных в тот конкретный момент, когда мне довелось запускать top -c
:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8180 mysql 16 0 57448 19m 2948 S 26.6 0.7 4702:26 /usr/sbin/mysqld --basedir=/ --datadir=/var/lib/mysql --user=mysql --pid-file=/var/lib/mysql/bristno.pid --skip-external-locking
26956 brristno 17 0 0 0 0 Z 8.0 0.0 0:00.24 [php] <defunct>
26958 brristno 17 0 94408 43m 37m R 5.0 1.4 0:00.15 /usr/bin/php /home/brristno/public_html/dbv.php
22852 nobody 16 0 9628 2900 1524 S 0.7 0.1 0:00.17 /usr/local/apache/bin/httpd -k start -DSSL
8591 brristno 34 19 96896 13m 6652 S 0.3 0.4 0:29.82 /usr/local/bin/php /home/brristno/bin/mailer.php 1qwqyb6 i0gbor
24469 nobody 16 0 9628 2880 1508 S 0.3 0.1 0:00.08 /usr/local/apache/bin/httpd -k start -DSSL
25495 nobody 15 0 9628 2876 1500 S 0.3 0.1 0:00.06 /usr/local/apache/bin/httpd -k start -DSSL
26149 nobody 15 0 9628 2864 1504 S 0.3 0.1 0:00.04 /usr/local/apache/bin/httpd -k start -DSSL
Спасибо, Дмитрий!
1) У меня уже есть скрипт, который отменяет подписку на адреса электронной почты, которые были возвращены по крайней мере пять раз за последний месяц, так что, надеюсь, мой список относительно ограничен активными адресами электронной почты.
2) Я использую exim 4.69. Мой файл конфигурации находится по адресу
/etc/exim.conf
и мои файлы журнала находятся по адресу:
/ вар / журнал / exim_mainlog
/ вар / журнал / exim_paniclog
/ вар / журнал / exim_rejectlog
Кроме того, когда я смотрю /etc/syslog.conf, я вижу следующее:
# Log all the mail messages in one place.
mail.* -/var/log/maillog
Я не знаю, что означает "-" в начале -/var/log/maillog
но когда я заглядываю в этот файл, становится ясно, что там много чего регистрируется.
Кроме того, в этот файл записывается много:
/ вар / журнал / exim_mainlog
С тех пор я добавил в /etc/exim.conf эту строку:
no_message_logs
Я думал, что это отключит ведение журнала почты (я перезапустил exim), но когда я смотрю на / var / log / maillog и на / var / log / exim_mainlog, оба файла все еще получают новые записи журнала.
Вопрос: Как я могу отключить большинство / все журналирование exim?
3) Когда я смотрю в / var / log / exim_paniclog, я вижу множество таких записей:
2010-12-19 04:03:32 1PUFB1-0006xZ-GF User 0 set for local_delivery transport is on the never_users list
После некоторого осмотра кажется, что это означает, что exim пытается доставить на корневой адрес электронной почты. Как лучше всего обрабатывать эти доставки почты root, используя как можно меньше ресурсов процессора?
Как уже отмечалось, средняя загрузка связана с количеством ожидающих процессов в очереди выполнения. Если у каждого из этих процессов очень мало работы и он быстро освобождает процессор, вы можете справиться с гораздо большей средней нагрузкой, чем обычное эмпирическое правило 1 на процессор.
Почта в значительной степени является прекрасным примером этого, каждому процессу требуется ЦП для отправки сообщения, но очень и очень мало. Я видел почтовые системы, использующие sendmail со средней нагрузкой в диапазоне от 25 до 35, но система по-прежнему интерактивна и работает нормально.
отметка
Системные метрики (нагрузка, ЦП, ввод-вывод) часто являются единственными индикаторами производительности их системы, которые есть у большинства людей, однако фактическая производительность транзакций - это совсем другое. Эти показатели могут дать представление о том, как ограничивается производительность, но на самом деле гораздо полезнее посмотреть, сколько времени на самом деле занимают транзакции.
почему мой скрипт отправки электронной почты не успевает?
Означает ли это, что вы видите проблемы с неочищающейся почтовой очередью? Или это время, необходимое для выполнения скрипта? Или вы делаете вывод, что это проблема, исходя из высокой нагрузки?
Как говорит mfarver, высокая нагрузка на почтовые системы не редкость, особенно с увеличением количества синхронных проверок, выполняемых почтовыми серверами во избежание спама.
Лично я не большой поклонник exim - у меня был гораздо лучший опыт работы с sendmail и postfix, хотя я признаю, что прошло несколько лет с тех пор, как я проводил какое-либо серьезное тестирование MTA. Конечно, вы попадаете в приблизительную точку, где вам нужно быть более сложным в обработке электронной почты.
Вместо того, чтобы отключать ведение журнала, было бы неплохо временно добавить пересылку для учетной записи root, чтобы точно знать, о чем все те электронные письма, которые не доставляются.
Я предполагаю, что MTA настроен для отправки почты непосредственно получателям. Если у вас есть проблемы с производительностью, вы можете рассмотреть возможность использования интеллектуального реле для более быстрой выгрузки сообщений с вашего сервера. Но попробуйте переключить exim в очередь только для того, чтобы увидеть, решит ли это сначала проблему загрузки (и, что более важно, любую производительность). Кроме того, взгляните на свое кеширование DNS и посмотрите, можно ли его улучшить.
Если вы уже используете интеллектуальное реле, проверьте его правильность настройки - IME, с настройкой на основе sendmail, вызовы php mail () блокируются в течение длительного времени (но каким-то образом сообщения все еще доставляются?), Если MTA не может подключиться к смарт-хосту.
Многие поставщики услуг электронной почты теперь реализуют регулирование как метод блокировки спама - хотя сортировка списка адресов электронной почты по домену поможет сократить количество запросов DNS, у вас могут возникнуть проблемы с регулированием или блокировкой почты удаленными системами. Убедитесь, что вы делаете все возможное, чтобы не выглядеть спамером (например, SPF, DKIM) - IIRC Exim напрямую не поддерживает milters - доступно много полезных milter - особенно milter-limit.
Во-первых, ваша нагрузка не так уж велика. Загрузка 8 на 2 процессора означает загрузку 4 на процессор. Также современные процессоры обычно двухъядерные, так что это как 2 процессора в одном, так что нагрузка на самом деле больше как 2 на процессор.
Что касается обработки писем, есть 2 вещи, которые вы можете сделать, чтобы уменьшить нагрузку: 1) убедитесь, что у вас есть скрипт, который обрабатывает возвращенные электронные письма, чтобы вы могли пометить адрес электронной почты как «возвращающийся» и не отправлять на него адрес больше. Обычный показатель отказов для большого списка адресов электронной почты, даже если вы выбрали подписку, составляет около 20%. Отказы действительно мешают серверу, потому что не только ваш сервер должен отправлять электронные письма, которые люди не видят, он также должен получать и обрабатывать отклоненные электронные письма.
2) Отключите ведение журнала в maillog. В списке рассылки большого объема запись добавляется в журнал сообщений при каждом отправляемом электронном письме, а также при каждом полученном ответном сообщении о недоставке. Запись в почтовый журнал требует значительных ресурсов, поскольку требует записи на диск. Просто отключив maillog, вы можете «сильно» снизить нагрузку на вашу систему, иногда на 50%. Я не знаю, какой почтовый сервер вы используете, но в Linux вы обычно смотрите в /etc/syslog.conf
Просто закомментируйте запись для почты и перезапустите службу системного журнала.
Еще раз: отклоненные электронные письма обычно возвращаются в корневую учетную запись. Система очень часто достигает предела почтового ящика для учетной записи root, который обычно составляет 100 МБ. Как только предел достигнут, вы начинаете другую проблему, когда вы даже не можете принимать отклоненные электронные письма, поэтому ваша система может отправлять свои собственные сообщения о недоставке, добавляя еще больше нагрузки.
Вывод: отслеживайте свои отказы и держите свой список в чистоте - отмеченные отказывания аккаунтов и больше не отправляйте им письма.
high load
средний размер run queue
- например, процессы, которые нужно запускать на центральном процессоре. Похоже, ваш скрипт много работает с процессором. Итак, вы должны профилировать его и размещать здесь его источники. Как вы отправляете письма?
Ваша запись в почтовом журнале помечена как не очищаемая для каждой записи. Это должно помочь снизить накладные расходы ЦП на запись в этот журнал. Однако, поскольку вы используете Exim, этот журнал по умолчанию не используется. Проверьте свою конфигурацию, чтобы убедиться, что вы не включили использование системного журнала.
Чтобы уменьшить количество журналов, добавьте log_selector
спецификацию вашей конфигурации. Возможные значения подробно описаны в Спецификации eximʻa (вероятно, глава 49). Хотя, скорее всего, это не ваша проблема.
Попробуйте бежать exiwhat
чтобы узнать, какие доставки выполняются. mailq
не должно быть много сообщений, ожидающих доставки, и сообщений, которые находились в очереди в течение часа или более. Длинный список сообщений, которые некоторое время находились в очереди, указывает на то, что вы пытаетесь выполнить доставку, которая может быть отклонена.
Exim плохо справляется с множеством запущенных одновременно процессов доставки. Вам следует посмотреть изменения конфигурации, которые могут помочь.
queue_only_load
делать это условно.queue_run_max
чтобы ограничить количество процессов обработчика очереди. Чтобы разрешить попытки доставки по маршруту, вы можете использовать транспорт или псевдоним. Я использую псевдоним root для своего адреса электронной почты. Ubuntu использует этот маршрутизатор для предотвращения доставки от имени root.
mail4root: debug_print = "R: mail4root for $local_part@$domain" driver = redirect domains = +local_domains data = /var/mail/mail file_transport = address_file local_parts = root user = mail group = mail