關於非同步郵件傳送服務的思路,和 Swoole 非同步任務的一個問題

Blings發表於2020-07-17

專案只用了swoole原生,使用Swoole的非同步Redis Server來觸發非同步任務,但是在服務在task_worker_num的數量的次數呼叫後,就會掛掉。
這個問題是執行任務的work程式沒有處理好的問題麼。
另外,目前郵件服務我掛載到了容器中,目前是用的DI容器,根據rediskey value動態的去呼叫模板,這樣Swoole Server來根據模板從容器中取出對應的Emailer。 會是DI容器的坑麼?(smtp伺服器已經協程化)

折騰了一天之後 發現可能是我在傳送郵件後 會銷燬掉smtp服務端的類中的屬性,但是這個問題為什麼在第最大任務程式數量次數後才出現。

懇求各位哥哥姐姐們給個思路,指點一下。。。

使用redis-cli呼叫

mail CreateCustomerNotify yichu4 123456 xx@lunion.com.cn

服務端除錯

task_work_num 設定為了2

 $this->server = $container->get('Kernel');

        $this->server->set([
            'task_worker_num' => 2,
            'worker_num'      => 2,
        ]);

服務的setHandler方法 處理redis的一個key

 public function mailHandle($fd, $data)
    {
        $taskID = $this->server->task($data);

        $this->logger->Info(sprintf('Create Task ID is %s',$taskID));

        $template = $data[0] ?? null;
        if(null === $template){
            return $this->server->send($fd, Server::format(Server::ERROR, 'Template is empty'));
        }

        $emailAddress = $data[1] ?? null;
        if(null === $emailAddress){
            return $this->server->send($fd, Server::format(Server::ERROR, 'Email is empty'));
        }

        try {
            $this->container->make('Mail',[
                'template' => $template
            ]);
        } catch (TemplateNotFoundException $exception) {
            return $this->server->send($fd, Server::format(Server::ERROR, 'Template ['.$template.']is not ready yet'));
        }

        if (false === $taskID) {
            return $this->server->send($fd, Server::format(Server::ERROR));
        } else {
            return $this->server->send($fd, Server::format(Server::INT, 1));
        }
    }

任務處理方法

public function onTask($server, $taskID, $workID, $data)
    {

        $template = $data[0] ?? null;
        if(null === $template){
            $this->logger->error('Template is empty');
        }

        $emailAddress = $data[1] ?? null;
        if(null === $emailAddress){
            $this->logger->error('Email is empty');
        }


        $this->logger->Info(sprintf('Handle Task ID is %s',$taskID));
        $this->logger->Info(sprintf('Handle Task Work ID is %s',$workID));
        $this->logger->Info(sprintf('Use %s Mail-Template, send to %s,Server is loading',$template, $emailAddress));

        $Mailer   = $this->container->make('Mail',[
            'template' => $template
        ]);

        array_shift($data);

        try{
            $result = $Mailer->sendMail(...$data);
        }catch (\Exception $e){
            $this->logger->error(sprintf('Use %s Mail-Template, send to %s, the task is failed ! Look at %s :',$template, $data[2], $e->getMessage()));

        }

        $this->logger->Info(sprintf('Use %s Mail-Template, send to %s,  Success!',$template, $data[2]));

        return true;
    }

果然第3次執行 就掛了

➜  \[0_0]/  yichu  ~/workspace/MessageCenter git:(master) ✗ php bin/start.php
Here Task ID is 0
Here Work ID is 1
string(41) "App\Business\Message\CreateCustomerNotify" #這裡是我列印的模板名稱變數
Here Task ID is 1
Here Work ID is 1
string(41) "App\Business\Message\CreateCustomerNotify"
Here Task ID is 2
Here Work ID is 1
NULL #沒了???? 我好菜
PHP Fatal error:  Uncaught TypeError: call_user_func() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php:51
Stack trace:
#0 /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php(51): call_user_func(Array, 'yichu4', '123456', 'xx@lunion.co...')
#1 /mnt/d/ubuntu/space/MessageCenter/src/Server/App.php(84): App\Server\MailCenter->sendMail('yichu4', '123456', 'xx@lunion.co...')
#2 [internal function]: App\Server\App->onTask(Object(Swoole\Redis\Server), 2, 1, Array)
#3 /mnt/d/ubuntu/space/MessageCenter/src/Server/App.php(92): Swoole\Redis\Server->start()
#4 /mnt/d/ubuntu/space/MessageCenter/bin/start.php(14): App\Server\App->start()
#5 {main}
  thrown in /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php on line 51

Fatal error: Uncaught TypeError: call_user_func() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php:51
Stack trace:
#0 /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php(51): call_user_func(Array, 'yichu4', '123456', 'xx@lunion.co...')
#1 /mnt/d/ubuntu/space/MessageCenter/src/Server/App.php(84): App\Server\MailCenter->sendMail('yichu4', '123456', 'xx@lunion.co...')
#2 [internal function]: App\Server\App->onTask(Object(Swoole\Redis\Server), 2, 1, Array)
#3 /mnt/d/ubuntu/space/MessageCenter/src/Server/App.php(92): Swoole\Redis\Server->start()
#4 /mnt/d/ubuntu/space/MessageCenter/bin/start.php(14): App\Server\App->start()
#5 {main}
  thrown in /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php on line 51
[2020-07-17 17:56:35 ^3455.2]   ERROR   php_swoole_server_rshutdown (ERRNO 503): Fatal error: Uncaught TypeError: call_user_func() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php:51
Stack trace:
#0 /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php(51): call_user_func(Array, 'yichu4', '123456', 'xx@lunion.co...')
#1 /mnt/d/ubuntu/space/MessageCenter/src/Server/App.php(84): App\Server\MailCenter->sendMail('yichu4', '123456', 'xx@lunion.co...')
#2 [internal function]: App\Server\App->onTask(Object(Swoole\Redis\Server), 2, 1, Array)
#3 /mnt/d/ubuntu/space/MessageCenter/src/Server/App.php(92): Swoole\Redis\Server->start()
#4 /mnt/d/ubuntu/space/MessageCenter/bin/start.php(14): App\Server\App->start()
#5 {main}
  thrown in /mnt/d/ubuntu/space/MessageCenter/src/Server/MailCenter.php on line 51
[2020-07-17 17:56:35 $3454.0]   WARNING swManager_check_exit_status: worker#2[pid=3455] abnormal exit, status=255, signal=0
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章