如何使用workerman处理后台耗时操作?

osacar

现在做一个项目,有这么一个需求。
客户在网站上下了订单,但是订单需要通过邮件来发送通知。以前的做法是在下单入库的同时也进行发送邮件操作。结果就是客户在前台需要等待比较长的时间。短时3-5秒,长则10秒以上。我觉得这种方法是任何一个访客都无法接受的。现在就想用workerman来进行改造优化。
使用定时器定时去执行任务这个应该可以。但是,这订单量不多,能不能这样,有订单来了下单后就触发一次发送邮件操作?期间记录发送状态,成功,失败次数,重发次数等。
我的主要目的就是有订单就触发发送操作。

刚接触workerman,太多东西还不是很了解。望walkor提供个能用于生产的方案流程。能有个代码说明就更加是万谢了。

9509 3 0
3个回答

walkor

mail_worker.php

<?php
use Workerman\Worker;
require_once './Workerman/Autoloader.php';

// mail worker,和调用端使用Text协议通讯
$mail_worker = new Worker('Text://0.0.0.0:12345');
// 如果发送邮件很慢,mail进程数可以根据需要多开一些
$mail_worker->count = 80;
$mail_worker->name = 'MailWorker'; 
$mail_worker->onMessage = function($connection, $mail_data)
{
     // 直接返回ok,避免调用端长时间等待
     $connection->send('ok'); 
     // 假设发来的是json数据
     $mail_data = json_decode($mail_data, true);
     // 根据mail_data发邮件,如果需要失败重发,
     // 可以把失败的邮件任务放到mysql里面,
     // 做个定时器定时扫描失败邮件重新发送
     your_send_mail_func($mail_data);
};
if(!defined('GLOBAL_START'))
{
    Worker::runAll();
}

在你的项目中这样与mail_worker通讯发邮件。

//$ip = "mail_worker 的ip" ,本机的话为127.0.0.1
$socket = stream_socket_client("tcp://$ip:12345", $errno, $errmsg, 5);
if(!$socket) echo $errmsg;
$mail_data = array("from"=>"...", "to"=>"...", "content"=>"...");
// 注意,Text协议后面"\n"换行符是必须的
$mail_buffer = json_encode($mail_data)."\n";
// 发送给mail worker
fwrite($socket, $mail_buffer);

这样就可以异步发邮件了,防止主流程被发邮件阻塞,大大加快下单响应时间。

其实下单后能够在网站上实时通知也是个不错的体验,用户这边下单后,商家在网站上立刻得到通知,效果图类似

接入非常简单
详细见:http://www.workerman.net/web-sender

  • tongxinmao 2015-12-29

    // 直接返回ok,避免调用端长时间等待
    $connection->send('ok');

    这里不回复应该也不会阻塞的, 只要对方发个数据来触发发邮件就行了。

osacar

非常感谢walkor!讲得很详细,已准备敲代码来试验。
另外问一下,$mail_worker->count = 80; 这每个进程需要的内存大概是多少?

  • 暂无评论
walkor

每个进程大概占用10-20M内存

  • 暂无评论
年代过于久远,无法发表回答
🔝