【问题标题】:Running beanstalk workers hangs the server运行 beanstalk 工作人员会挂起服务器
【发布时间】:2015-12-24 10:17:01
【问题描述】:

我有五个用 PHP 编写的 beanstalk 工作人员,每个工作人员都在监视某个管道并处理数据,主要发送电子邮件、消息电子邮件、通知电子邮件和注册电子邮件,每个工作人员都在与数据库交谈并在发送前获取一些数据电子邮件。

我尝试使用“屏幕”和“crontab”运行工作程序,目前我正在尝试“supervisord”,但无论我使用什么,服务器都会挂起并且它给我“内存分配错误”所以我必须重新启动每次服务器,我的本地服务器是8GB内存,运行worker时我应该考虑什么,例如内存,CPU使用率,谁能指出我在哪里看?

这是一个发送消息电子邮件的示例工人

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);
    }
}

提前致谢

【问题讨论】:

  • 这似乎是 php 代码的问题,而不是用于运行它的作业调度程序。如果可能的话,您可能应该在您的帖子中添加 php 代码。
  • 好的,我会添加一个工人样本
  • PHP 将由其他人检查,因为我不是 PHP 专家。话虽如此,似乎有一段时间(真)没有中断/退出。这不是无限期执行吗?
  • 是的,与工人打交道需要一个无限循环来充当监听器。
  • 如果我问了一些愚蠢的问题,我深表歉意。如果存在无限循环,为什么需要作业调度程序来启动它们?在启动时启动它们不是更好吗?

标签: php backgroundworker amazon-elastic-beanstalk supervisord beanstalkd


【解决方案1】:

因此,如果您的内存不足,则说明您在某处泄漏了内存。请调查如何找到它。

否则,在一批工作人员或一段时间后停止并重新启动工作人员一次是一种可接受的技术。例如:每 10k 条消息重启工作者,或每 24 小时重启工作者。这将关闭处理程序,释放内存并重新开始。如何实现这一点是另一个有趣的话题,它可以是自我管理的,比如退出。比主管会重新启动它。

最好将所有这些都放在线程中。每个作业都将在它自己的子线程中处理,这就是我们现在在 PHP 中运行工作者的方式,我们这样运行以避免内存泄漏和处理程序。

另外,最好设置一个代理或 ochestrator,它可以是一个简单的 PHP 脚本,它可以永远运行,在启动时启动,它的工作是启动,每分钟使用进程脚本检查一次工作人员的状态,以及找到他们是否死亡并重新启动。逻辑是你的,你可以控制你想如何管理它,但要保持简单。此代理脚本可以从 CLI 中永久运行,并且不会发生内存泄漏。

【讨论】:

    猜你喜欢
    • 2020-12-19
    • 2011-07-24
    • 2015-03-24
    • 2021-08-22
    • 2015-09-02
    • 2016-09-17
    • 2020-06-06
    • 1970-01-01
    • 2020-03-25
    相关资源
    最近更新 更多