現(xiàn)在做一個項目,有這么一個需求。
客戶在網(wǎng)站上下了訂單,但是訂單需要通過郵件來發(fā)送通知。以前的做法是在下單入庫的同時也進(jìn)行發(fā)送郵件操作。結(jié)果就是客戶在前臺需要等待比較長的時間。短時3-5秒,長則10秒以上。我覺得這種方法是任何一個訪客都無法接受的?,F(xiàn)在就想用workerman來進(jìn)行改造優(yōu)化。
使用定時器定時去執(zhí)行任務(wù)這個應(yīng)該可以。但是,這訂單量不多,能不能這樣,有訂單來了下單后就觸發(fā)一次發(fā)送郵件操作?期間記錄發(fā)送狀態(tài),成功,失敗次數(shù),重發(fā)次數(shù)等。
我的主要目的就是有訂單就觸發(fā)發(fā)送操作。
剛接觸workerman,太多東西還不是很了解。望walkor提供個能用于生產(chǎn)的方案流程。能有個代碼說明就更加是萬謝了。
mail_worker.php
<?php
use Workerman\Worker;
require_once './Workerman/Autoloader.php';
// mail worker,和調(diào)用端使用Text協(xié)議通訊
$mail_worker = new Worker('Text://0.0.0.0:12345');
// 如果發(fā)送郵件很慢,mail進(jìn)程數(shù)可以根據(jù)需要多開一些
$mail_worker->count = 80;
$mail_worker->name = 'MailWorker';
$mail_worker->onMessage = function($connection, $mail_data)
{
// 直接返回ok,避免調(diào)用端長時間等待
$connection->send('ok');
// 假設(shè)發(fā)來的是json數(shù)據(jù)
$mail_data = json_decode($mail_data, true);
// 根據(jù)mail_data發(fā)郵件,如果需要失敗重發(fā),
// 可以把失敗的郵件任務(wù)放到mysql里面,
// 做個定時器定時掃描失敗郵件重新發(fā)送
your_send_mail_func($mail_data);
};
if(!defined('GLOBAL_START'))
{
Worker::runAll();
}
在你的項目中這樣與mail_worker通訊發(fā)郵件。
//$ip = "mail_worker 的ip" ,本機(jī)的話為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協(xié)議后面"\n"換行符是必須的
$mail_buffer = json_encode($mail_data)."\n";
// 發(fā)送給mail worker
fwrite($socket, $mail_buffer);
這樣就可以異步發(fā)郵件了,防止主流程被發(fā)郵件阻塞,大大加快下單響應(yīng)時間。
其實下單后能夠在網(wǎng)站上實時通知也是個不錯的體驗,用戶這邊下單后,商家在網(wǎng)站上立刻得到通知,效果圖類似
接入非常簡單
詳細(xì)見:http://m.wtbis.cn/web-sender
// 直接返回ok,避免調(diào)用端長時間等待
$connection->send('ok');
這里不回復(fù)應(yīng)該也不會阻塞的, 只要對方發(fā)個數(shù)據(jù)來觸發(fā)發(fā)郵件就行了。
非常感謝walkor!講得很詳細(xì),已準(zhǔn)備敲代碼來試驗。
另外問一下,$mail_worker->count = 80; 這每個進(jìn)程需要的內(nèi)存大概是多少?