У меня есть пять бобовых стеблей, написанных на PHP, каждый из которых наблюдает за определенной трубкой и обрабатывает данные, в основном отправляя электронные письма, электронные письма с сообщениями, электронные письма с уведомлениями и электронные письма о подписке, каждый рабочий обращается к базе данных и извлекает некоторые данные перед отправкой электронных писем.
Я попытался запустить рабочие, используя «Screen» и «crontab», и я пытаюсь «supervisord» в данный момент, но что бы я ни использовал, сервер зависает, и это дает мне «ошибку выделения памяти», поэтому мне приходится перезагружать сервер каждый время моего локального сервера составляет 8 ГБ памяти, что я должен учитывать при запуске рабочих, память, например, использование процессора, кто-нибудь может указать мне, где искать?
вот пример работника для отправки сообщений по электронной почте
public function actionMessages() {
$pheanstalk = new Pheanstalk("127.0.0.1");
while (true) {
// worker (performs jobs)
$job = $pheanstalk
->watch('MessageEmail')
->ignore('default')
->reserve();
$jobData = json_decode($job->getData(), true);
$usersObj = new Users();
$circlesObj = new Circles();
$messageId = NULL;
$listUsers = [];
$finalDataArray = [];
$finalDataUsersArray = [];
foreach ($jobData['circlesIds'] as $circle) {
// get users in lists
foreach ($jobData['lists'] as $list) {
$listsObj = new Lists();
$listUsers = $listsObj->getListInfoWithOutsiders($list);
}
$circleInfo = $circlesObj->getBasicInfoById($circle);
if (sizeof($listUsers) > 0) {
// send emails to the list
foreach ($listUsers as $userInListId) {
// check if the user is circlu or outsider
if ($userInListId['outsider']) {
$circlesProfilesObj = new CirclesMembersManagement();
$userInfo = $circlesProfilesObj->getMemberEmailById($userInListId['user_id']);
$finalDataArray[] = ['circle' => $circleInfo, 'email' => $userInfo['email'],
'post' => ['html' => $jobData['messageText'], 'date' => $jobData['postDate']]];
// send email
} else {
$userInfo = $usersObj->getUserEmailById($userInListId['user_id']);
// insert the main message
$messages = new Messages();
$messageId = $messages->addCircleMessage($jobData['messageText'], $userInListId['user_id'], $circleInfo['id']);
$finalDataArray[] = ['circle' => $circleInfo, 'email' => $userInfo['email'],
'post' => ['html' => $jobData['messageText'], 'date' => $jobData['postDate']]];
}
}
EmailHelper::sendMessageEmail($finalDataArray);
}
// send messages to the the users
if (sizeof($jobData['users']) > 0) {
foreach ($jobData['users'] as $userId) {
// insert the main message
if ($messageId) {
// send direct message
$userMessagesObj = new UserMessages();
$userMessagesObj->sendCircleMessage($circleInfo['id'], $userId, $messageId);
} else {
$messages = new Messages();
$messages->addCircleMessage($jobData['messageText'], $userId, $circleInfo['id']);
}
$userInfo = $usersObj->getUserEmailById($userId);
$finalDataUsersArray[] = ['circle' => $circleInfo, 'email' => $userInfo['email'],
'post' => ['html' => $jobData['messageText'], 'date' => $jobData['postDate']]];
// send email
}
EmailHelper::sendMessageEmail($finalDataUsersArray);
}
}
$pheanstalk->delete($job);
}
}
заранее спасибо
Так что, если у вас заканчивается память, вы теряете где-то память. Пожалуйста, исследуйте это, как найти и найти это.
В противном случае, это приемлемый метод — останавливать и перезапускать работника один раз после партии или времени. Например: после каждых 10 тыс. Сообщений перезапускать работника или каждые 24 часа перезапускать работника. Это закроет обработчики, освободит память и начнет все заново. Как этого добиться — еще одна интересная тема, это может быть самостоятельное управление, например, выход. Тогда супервизор перезапустил бы его.
Лучше всего было бы поместить все это в темы. И каждое задание будет обрабатываться в своем собственном дочернем потоке, вот как мы сейчас запускаем рабочих в PHP, и мы запускаем так, чтобы избежать утечки памяти и обработчиков.
Также хорошо настроить брокера или ochestrator, который может быть простым PHP-скриптом, который работает вечно, запускается при загрузке, и его задача — запускать и раз в минуту проверять состояние своих работников с помощью сценария процесса и определять, находятся ли они. умер и перезапустить. Логика ваша, вы контролируете, как вы хотите управлять этим, но сохраняйте это простым. Этот скрипт брокера может работать вечно из CLI и не должен иметь утечки памяти.
Других решений пока нет …