关于异步邮件发送服务的思路,和 Swoole 异步任务的一个问题

项目只用了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 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

我很久之前写个一个开源项目,用来解决异步场景超级好用 github.com/star7th/htq

3年前 评论
aidoudou 3年前

用htq几乎对php业务代码无侵入。不用考虑互相干扰啊生命周期啊回调之类的

3年前 评论

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

这里就说明了你代码的问题了啊

3年前 评论
Blings (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!