Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Часть процессов phpDaemon впадает в бесконечный цикл вызовов epoll_wait и увеличивают использование cpu #300

Open
lightbliss opened this issue Jul 27, 2021 · 6 comments

Comments

@lightbliss
Copy link

Добрый день!
Используем phpDaemon для обработки API-запросов.
Столкнулись с такой проблемой, что несколько (примерно равно количеству ядер на сервере) процессов phpd через некоторое время (если полностью перезапустить мастер-процесс, то через 10 минут) начинают очень активно делать системные вызовы "epoll_wait" такого вида:
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 766) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 766) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 766) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 764) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 764) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 764) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 764) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 763) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 763) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 763) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 763) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 763) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 762) = 1
[pid 7118] epoll_wait(7, {EPOLLIN, {u32=2, u64=2}}, 32, 762) = 1

Стрейс статистика по процессу показывает такое:
% time | seconds | usecs/call | calls | errors | syscall
98.98 | 0.661405 | 5 | 121343 | | epoll_wait

lsof процесса выглядит так:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
php 7118 root 2u a_inode 0,10 0 6487 [eventfd]
php 7118 root 3r CHR 1,9 0t0 1033 /dev/urandom
php 7118 root 4u a_inode 0,10 0 6487 [eventfd]
php 7118 root 5u a_inode 0,10 0 6487 [eventpoll]
php 7118 root 6u a_inode 0,10 0 6487 [eventfd]
php 7118 root 7u a_inode 0,10 0 6487 [eventpoll]
php 7118 root 8w REG 253,0 79811 136834586 /var/log/phpdaemon.log
php 7118 root 9u a_inode 0,10 0 6487 [eventfd]
...

Эти процессы сразу начинают использовать cpu на 100% и cpu на сервере начинает упираться в полку (50% system, 40% nice).
При этом кажется, что процессы просто греют воздух и реальной работы не делают. Когда же приходят настоящие запросы, то они успешно выполняются и 5xx ошибок мы не наблюдаем.

Версия phpDaemon: commit e8d5178
Версия php 7.0.33
Версия php-расширения event 2.4.1
libevent2 headers version => 2.0.21-stable

Конфиг phpDaemon:
min-workers 64;
max-workers 128;
min-spare-workers 32;
max-spare-workers 64;
start-workers 64;
max-idle 120;
max-requests 16384;

phpDaemon запускается через systemd

На виртуалке - 8 ядер, система - CentOS Linux 7.
Также, по наблюдениям, если уменьшить первые 4 опции в конфиге phpDeamon в 2 раза (min-workers, max-workers, min-spare-workers, max-spare-workers), то 100% использования cpu прекращается, но по htop и strace видно, что больные процессы все еще появляются в системе. На более мощном сервере (20 ядер), при таких же настройках phpDaemon, процессы с бесконечным вызовом epoll_wait не появляются.

Можно ли как-то такое поведение с воркерами починить, чтобы не было бесконечных вызовов epoll_wait?

@kakserpom
Copy link
Owner

kakserpom commented Jul 27, 2021 via email

@lightbliss
Copy link
Author

Добрый день!
Могу попросить вас более подробно рассказать про это исключение?

Я заглянул поглубже в код, но, пока, не нашел место, откуда такое исключение может выбрасываться. Обернул самые верхние функции в try/catch, но тоже пока ничего не словил.

И, по идее, если выбрасывается необработанное исключение, то запрос должен завершаться неудачей с 5xx ошибкой, а в логах должно появляться что-то вроде "Fatal error: Uncaught Exception", но мы таких записей не наблюдаем. Или я ошибаюсь и оно так не работает?

@lightbliss
Copy link
Author

Еще забыл добавить такое уточнение, что если перезапустить все процессы phpd полностью, то воркеры заболевают одновременно и ровно через 10 минут (засекали по часам). Это не зависит от мощности сервера и нагрузки на сервер, всегда 10 минут.

@nkolosov
Copy link

nkolosov commented Aug 3, 2021

В итоге, удалось выяснить, что проблема исчезает, если использовать eio-enabled = false

eio

eio support => enabled
Debug support => disabled
Version => 2.0.4

Кажется, что зависает где-то на вызове PHPDaemon\FS\FileSystem::waitAllEvents() при завершении работы воркера

@kakserpom
Copy link
Owner

kakserpom commented Aug 3, 2021 via email

@nkolosov
Copy link

nkolosov commented Aug 3, 2021

Да, конечно, буду рад https://t.me/nkolosov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants