PHP 的異步進程助手,借助于 AMQP 實現異步執行 PHP 的方法,將一些很耗時、追求高可用、需要重試機制的操作放到異步進程中去執行,將你的 HTTP 服務從繁重的業務邏輯中解脫出來。以一個較低的成本將傳統 PHP 業務邏輯轉換成非阻塞、高可用、可擴展的異步模式。
通過 composer 安裝
composer require l669/async-helper
或直接下載項目源碼
wget https://github.com/l669306630/async-helper/archive/master.zip
使用范例
業務邏輯:這里定義了很多等待被調用的類和方法,在你的項目中這可能是數據模型、或是一個發送郵件的類。
<?phpclass SendMailHelper {  /**   * @param array $mail   * @throws Exception   */  public static function request($mail)  {    // 在這里發送郵件,或是通過調用第三方提供的服務發送郵件    // 發送失敗的時候你拋出了異常,希望被進程捕獲,并按設定的規則進行重試  }  }生產者:通常是 HTTP 服務,傳統的 PHP 項目或是一個命令行程序,接收到某個請求或指令后進行一系列的操作。
<?php use l669/AsyncHelper;class UserController{  public function register()  {    // 假設這是一個用戶注冊的請求,用戶提交了姓名、郵箱、驗證碼    // 第一步、校驗用戶信息    // 第二步、實例化異步助手,這時候會連接 AMQP    $async_helper = new AsyncHelper([      'host' => '127.0.0.1',      'port' => '5672',      'user' => 'root',      'pass' => '123456',      'vhost' => '/'    ]);    // 第三步、保存用戶信息到數據庫    $mail = [      'from' => 'service@yourdomain.com',       'to' => 'username@163.com',       'subject' => '恭喜你注冊成功',      'body' => '請點擊郵件中的鏈接完成驗證....'    ];    // 第四步、通過異步助手發送郵件    $async_helper->run('//SendMailHelper', 'request', [$mail]);        // 這是同步的模式去發送郵件,如果郵件服務響應遲緩或異常,就會直接影響該請求的響應時間,甚至丟失這封重要郵件    // SendMailHelper::request($mail);  }}消費者:PHP 的異步進程,監聽消息隊列,執行你指定的方法。并且該消費者進程是可擴展的高可用的服務,這一切都得益于 AMQP,這是系統解耦、布局微服務的最佳方案。
consume.php
<?phprequire_once('vendor/autoload.php');require_once('SendMailHelper.php');use l669/AsyncHelper;use l669/CacheHelper;$cache_helper = new CacheHelper('127.0.0.1', 11211);while(true){  try{    $async_helper = new AsyncHelper([      'host' => '127.0.0.1',      'port' => '5672',      'user' => 'root',      'pass' => '123456',      'vhost' => '/',      'cacheHelper' => $cache_helper    ]);    $async_helper->consume();  }catch(Exception $e){    // 可以在這里記錄一些日志    sleep(2);  }}# 在命令行下啟動消費者進程,推薦使用 supervisor 來管理進程
php consume.php
支持事務:需要一次提交執行多個異步方法,事務可以確保完成性。
// 接著上面的示例來說,這里省略了一些重復的代碼,下同$async_helper->beginTransaction();try{  $async_helper->run('//SendMailHelper', 'request', [$mail1]);  $async_helper->run('//SendMailHelper', 'request', [$mail2]);  $async_helper->run('//SendMailHelper', 'request', [$mail3]);  $async_helper->commit();}catch(/Exception $e){  $async_helper->rollback();}阻塞式重試:當異步進程執行一個方法,方法內部拋出異常時進行重試,一些必須遵循執行順序的業務就要采用阻塞式的重試,通過指定重試最大阻塞時長來控制。
use l669/CacheHelper;use l669/AsyncHelper;$async_helper = new AsyncHelper([  'host' => '127.0.0.1',  'port' => '5672',  'user' => 'root',  'pass' => '123456',  'vhost' => '/',  'cacheHelper' => new CacheHelper('127.0.0.1', 11211),  'retryMode' => AsyncHelper::RETRY_MODE_REJECT, // 阻塞式重試  'maxDuration' => 600              // 最長重試 10 分鐘]);$send_mail_helper = new /SendMailHelper();$mail = new /stdClass();$mail->from = 'service@yourdomain.com';$mail->to = 'username@163.com';$mail->subject = '恭喜你注冊成功';$mail->body = '請點擊郵件中的鏈接完成驗證....';$async_helper->run($send_mail_helper, 'request', [$mail]);// 如果方法中需要拋出異常來結束程序,又不希望被異步進程重試,可以拋出以下幾種錯誤碼,進程捕獲到這些異常后會放棄重試:// l669/AsyncException::PARAMS_ERROR// l669/AsyncException::METHOD_DOES_NOT_EXIST// l669/AsyncException::KNOWN_ERROR非阻塞式重試:當異步執行的方法內部拋出異常,async-helper 會將該方法重新放進隊列的尾部,先執行新進入隊列的方法,回頭再重試剛才執行失敗的方法,通過指定最大重試次數來控制。
use l669/CacheHelper;use l669/AsyncHelper;$async_helper = new AsyncHelper([  'host' => '127.0.0.1',  'port' => '5672',  'user' => 'root',  'pass' => '123456',  'vhost' => 'new',  'cacheHelper' => new CacheHelper('127.0.0.1', 11211),  'queueName' => 'emails.vip',          // 給付費的大爺走 VIP 隊列  'retryMode' => AsyncHelper::RETRY_MODE_TTL,   // 非阻塞式重試  'maxRetries' => 10               // 最多重試 10 次]);$mail = new /stdClass();$mail->from = 'service@yourdomain.com';$mail->to = 'username@163.com';$mail->subject = '恭喜你注冊成功';$mail->body = '請點擊郵件中的鏈接完成驗證....';$async_helper->run('//SendMailHelper', 'request', [$mail]);應用和解惑
和傳統 PHP 相比
 
  | 
新聞熱點
疑難解答
圖片精選