Помните проблему прерывания выполнения программы, вызванную перезапуском php-fpm

PHP

Предыстория и предварительное расследование

  • Тревога сработала, когда дело по заказу было согласовано, и был заказ, которого не было в нашей собственной библиотеке монго.
  • бизнес-интерфейс/3/xx/vgift/sendсистема подарков звонковsendPresentИнтерфейс завершает подарок, а затем пишет монго, но в журнале ошибок php нет журнала исключений монго.
  • В написании монго нет аномалий, но записи в библиотеке нет, предполагается, что есть только две возможности.

1 - лог ошибок, лог потерян 2 заключается в том, что он не работает после завершения операции sendPresent во время выполнения программы, в результате чего запись в монго не выполняется. -В первом случае многолетнего опыта работы должно не хватить, поэтому продолжим проверку по второму случаю.

  • Затем перейдите к журналу php-fpm, чтобы увидеть, есть ли какие-либо отклонения в соответствующий момент времени.
[wu.daolin@web001.m6~]$ grep "2017 05:28" /var/log/php-fpm.log
[25-Jun-2017 05:28:01] NOTICE: Terminating ...

  • Просто он совпадает со временем заказа, поэтому его надо изучить.

Ознакомьтесь с управлением php-fpm

php-fpm черезphp-fpmЧтобы управлять этой командой, давайте сначала рассмотрим эту команду.

man php-fpm

Здесь упоминается,php-fpm then responds to several POSIX signalsphp-fpm будет (собственно) обрабатывать следующие сигналы

  • SIGINT, SIGTERM: immediate termination
  • SIGQUIT: graceful stop
  • SIGUSR1: re-open log file
  • SIGUSR2: graceful reload of all workers + reload of fpm conf/binary
Проверьте это
  • sudo kill -QUIT {php-fpm-pid}
[26-Jun-2017 13:58:22] NOTICE: Finishing ...                                                                                            
[26-Jun-2017 13:58:22] NOTICE: exiting, bye-bye!

  • sudo kill -TERM {php-fpm-pid}
[26-Jun-2017 13:59:21] NOTICE: Terminating ...                                                                                          
[26-Jun-2017 13:59:21] NOTICE: exiting, bye-bye!
  • sudo kill -USR2 12583

[26-Jun-2017 14:00:48] NOTICE: Reloading in progress ...                                                                                
[26-Jun-2017 14:00:48] NOTICE: reloading: execvp("/usr/sbin/php-fpm", {"/usr/sbin/php-fpm", "--daemonize"})                             
[26-Jun-2017 14:00:48] NOTICE: using inherited socket fd=8, "10.30.60.87:9000"                                                          
[26-Jun-2017 14:00:48] NOTICE: using inherited socket fd=8, "10.30.60.87:9000"                                                          
[26-Jun-2017 14:00:48] NOTICE: fpm is running, pid 12696                                                                                
[26-Jun-2017 14:00:48] NOTICE: ready to handle connections

Сделать вывод из результатов проверки

существует05:28:01На этот раз кто-то отправил сообщение на PHP-FPMSIGTERMСигнал, в этот момент, скорее всего, задача на время, подтвердите, что это28 5 * * * root /etc/init.d/php-fpm restart> /dev/null

Наше управление php-fpm
  • сценарий инициализации/etc/init.d/php-fpm
  • где остановкаkillproc -p ${pidfile} php-fpm, очевидно, из журнала результатkill -TERM, В документе также говорится, что сигнал по умолчанию TERMkillproc sends signals to all processes that use the spec­ified executable. If no signal name is specified, the signal SIGTERM is sent.

Посмотрите на ответ nginx в этом случае

image

Обобщите причину

  • Выполняется после завершения бизнес-запросаsendPresentПосле этого действия нет времени写mongo库, php-fpm просто оказалсяterminateТеперь .... как раз вовремя

альтернативный план

  • Хотя php-fpm не объясняетterminateа такжеgraceful stopКонкретное значение , но если вы догадываетесь, первое заключается в прекращении выполнения программы напрямую, а второе может быть более щадящим и убивать все операции в обрабатываемом запросе. . .
  • во всяком случаеSIGTERMTerminate слишком грубо, чтобы настроить рабочий процесс php, лучше его изменить
  • изменить наSIGUSER2метод перезагрузки
  • изменить наSIGQUITпуть, положитьkillproc -p ${pidfile} php-fpmИзмените это предложение наkillproc -p ${pidfile} php-fpm -QUIT
  • Работник php-fpm будет убит и повторно вытащен после подсчета n раз.Если функция перезагрузки повторяется, нет необходимости регулярно перезапускать ее.Я все равно выбираю изящную остановку (SIGQUIT)
  • Конечно, когда проблема все же есть, зачем настраивать перезагрузку по расписанию и отправлять вышеуказанный контент в sa для чтения

а такжеsaвопросы и ответы

са сказал 3 комментария
  • Рекомендуется посмотреть -QUIT, нормальный ли код состояния Nginx? Кроме того, в некоторых случаях это может привести к длительному завершению процесса PHP-FPM, что повлияет на развертывание?

  • использоватьreload(SIGUSER2)Вместо того, чтобы использоватьSIGTERMОстановить и перезапустить. Увидев перезагрузку в наших предыдущих результатах теста, nginx сообщит 502, что не является изящной остановкой. Рекомендуется провести хорошую работу по тестированию и подтверждению, в том числе следует ли перезагружать при развертывании php-кода?Bug #60961 Graceful Restart (USR2) isn't very graceful

  • php-fpm регулярно перезапускает скрипт каждый день Этот синхронизированный скрипт, вероятно, был развернут в 2012 году, когда он был добавлен из-за проблем с утечкой памяти в PHP-FPM. Это все еще применимо? Рекомендуется найти автомат для отключения скрипта тайминга и долго его наблюдать.

Я отвечаю
  • SIGQUITНе понятно нормально ли, но тока по умолчаниюSIGTERMОпределенно ненормально немедленно останавливать процесс php — из журнала ошибок nginx для установленного соединения между nginx и php-fpm ошибка «104: сброс соединения узлом»; тот, который нужно подключить, — «111: В соединении отказано";

  • "111: Отказ в соединении" допустимо, просто нет соединения, пользователь может повторить попытку позже; "104: Сброс соединения узлом" принять сложно, я так понимаю эта ошибка означает连接已经建好了,php突然terminate了,然后发了个RST分节给nginx; Под этим подразумевается, что текущий запрос может выполнить только половину действия, а еще есть действия, которые не были выполнены, что может привести к потере данных. . . Например, вопрос, упомянутый в начале статьи

  • Перезагрузка на самом деле является сигналом -USR2, и эта ошибка, похоже, еще не исправлена. . . Однако иногда следует говорить, что -USR2 завершается, а -TERM должен быть завершен.

  • Теперь логика развертывания кода同步代码+清理opcache和yac缓存, 不对php-fpm进程做操作

  • php-fpm сам подсчитает количество запросов, обработанных рабочим процессом, и уничтожит его, а затем извлечет заново, когда оно достигнет определенного числа; поэтому у рабочего процесса не должно быть проблем с утечкой памяти; процесс-менеджер не ясно, но я думаю, что вероятность должна быть крайне низкой. Трудно доказать, применимо это или нет. . .

  • Так почему бы не найти 3 машины, одну с -QUIT, одну с -USR2 и одну для удаления этой временной задачи; сначала наблюдайте

  • са ответ да, мы можем понять это

конец

  • Сигнал SIGQUIT по-прежнему существует в nginx.104: Connection reset by peer, вроде в мануале написаноSIGQUIT: graceful stopНет гарантии, что все действия в запросе будут выполнены.
  • Окончательные результаты去掉这个定时重启php-fpm 的任务, Прошло больше 3-х месяцев, проблем не обнаружено, о да~

Справочная документация