<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 安裝 > composer require topthink/think-queue ## 配置 > 配置文件位于?`config/queue.php` ### 公共配置 ~~~php [ 'default'=>'sync' //驅動類型,可選擇 sync(默認):同步執行,database:數據庫驅動,redis:Redis驅動//或其他自定義的完整的類名 ] ~~~ 配置消息隊列的驅動 根據選擇的存儲方式,在\\app\\config\\queue.php這個配置文件中,添加消息隊列對應的驅動配置 ![](https://img.kancloud.cn/d2/e1/d2e15e42103b59bc2acacd6121bd597c_1716x1418.png) ## 創建任務類 > 單模塊項目推薦使用?`app\job`?作為任務類的命名空間 多模塊項目可用使用?`app\module\job`?作為任務類的命名空間 也可以放在任意可以自動加載到的地方 > > 任務類不需繼承任何類,如果這個類只有一個任務,那么就只需要提供一個`fire`方法就可以了,如果有多個小任務,就寫多個方法,下面發布任務的時候會有區別 > 每個方法會傳入兩個參數?`think\queue\Job $job`(當前的任務對象) 和?`$data`(發布任務時自定義的數據) > > 還有個可選的任務失敗執行的方法?`failed`?傳入的參數為`$data`(發布任務時自定義的數據) ~~~ 例一:消息的消費與刪除 namespace app\job; use think\queue\Job; class Job1{ public function fire(Job $job, $data){ //....這里執行具體的任務 if ($job->attempts() > 3) { //通過這個方法可以檢查這個任務已經重試了幾次了 } //如果任務執行成功后 記得刪除任務,不然這個任務會重復執行,直到達到最大重試次數后失敗后,執行failed方法 $job->delete(); // 也可以重新發布這個任務 $job->release($delay); //$delay為延遲時間 } public function failed($data){ // ...任務達到最大重試次數后,失敗了 } } ~~~ ~~~ 例二: namespace app\lib\job; use think\queue\Job; class Job2{ public function task1(Job $job, $data){ } public function task2(Job $job, $data){ } public function failed($data){ } } ~~~ ~~~php 例三:多模塊舉例 ~~~ ~~~ <?php /** * 消息隊列(queue)使用方法 * 使用redis實現消息隊列demo */ namespace app\crm\job\export; use think\facade\Db; use think\queue\Job; class QueueJobTest { public function fire(Job $job,$data){ // 如有必要,可以根據業務需求和數據庫中的最新數據,判斷該任務是否仍有必要執行. $isJobStillNeedToBeDone = $this->checkJobNeedIfDone($data); if(!$isJobStillNeedToBeDone){ //刪除任務 $job->delete(); return; } $isJobDone = $this->saveInfo($data); //如果任務執行完成,刪除此隊列任務, if($isJobDone){ //刪除任務 $job->delete(); }else{ //通過這個方法可以檢查這個任務已經重試了幾次了 if ($job->attempts() > 3) { //如果大于設置的次數3,可執行刪除任務或重新發布此任務 //此處直接執行刪除任務 $job->delete(); //--begin-重新發布此任務------- //$job->release(2); //參數為設置的延遲時間,表示該任務延遲2秒后再執行 //--end-重新發布此任務--------—— } } } /** * 可選的任務失敗執行的方法,此處只作列舉 * 任務失敗,執行failed方法 * @param $data 發布任務時自定義的數據 */ //public function failed($data){ //// ...任務達到最大重試次數后,失敗了 //執行失敗的業務代碼 //} /** * 有些消息在到達消費者時,可能已經不再需要執行了 * @param array|mixed $data 發布任務時自定義的數據 * @return boolean 任務執行的結果 */ private function checkJobNeedIfDone($data){ //可查詢數據庫確認是否需要繼續執行,比如訂單支付的狀態更改等后續操作 //此處省略業務邏輯,直接返回true,表示繼續執行 return true; } /** * 任務執行的業務代碼 * 如發送郵件,數據入庫等 */ private function saveInfo($data){ //此處模擬數據入庫 $res = Db::name('test')->insert( [ 'title' => $data['title'], 'content' => $data['content'], 'add_time' => time() ] ); if($res){ return true; }else{ return false; } } } ~~~ ## 發布任務 > 兩個方法 > > `think\facade\Queue::push($job, $data = '', $queue = null);`?      //立即執行 > > 或? > > `think\facade\Queue::later($delay, $job, $data = '', $queue = null);`? //延時執行,在參數?`$delay?`秒后執行在`$delay`秒后執行 > > `$job`?是任務名 > 單模塊的,且命名空間是`app\job`的,比如上面的例子一,寫`Job1`類名即可 > 多模塊的,且命名空間是`app\module\job`的,寫`model/Job1`即可 > 其他的需要些完整的類名,比如上面的例子二,需要寫完整的類名`app\lib\job\Job2` > 如果一個任務類里有多個小任務的話,如上面的例子二,需要用@+方法名`app\lib\job\Job2@task1`、`app\lib\job\Job2@task2` > > `$data`?是你要傳到任務里的參數 > > `$queue`?隊列名,指定這個任務是在哪個隊列上執行,同下面監控隊列的時候指定的隊列名,可不填 > > **例:** > > ~~~php > 文件路徑: > > ~~~ > > **任務名(類名):app\\crm\\job\\export\\QueueJobTest** > > **傳到任務里的參數:**\['title' => '隊列任務入庫demo','content' => 'xxxx內容'\]**** > > **隊列名(可不填):queueJobTest** > > ****//生產者業務代碼中把任務push到隊列中:**** > > **think\\facade\\Queue::push('app\\crm\\job\\export\\QueueJobTest',? \['title' => '隊列任務入庫demo','content' => 'xxxx內容'\], '**queueJobTest**')** ![](https://img.kancloud.cn/f9/c9/f9c925d7d8abd5029b8533d7992bd79b_1700x537.png) **發布任務** ?瀏覽器中訪問:http://localhost/index.php/Test/actionQueueJobTest?? ## 監聽任務并執行 消費者進行處理隊列 ~~~ &> php think queue:listen &> php think queue:work ~~~ 兩種,具體的可選參數可以輸入命令加?`--help`?查看 **處理任務** > 方式一: > > 切換當前終端窗口的目錄到項目根目錄下,執行 > > php think queue:work --queue queueJobTest > > 或 > > php think queue:listen --queue queueJobTest > 方式二: > > supervisor安裝參考:https://www.cnblogs.com/chihuobao/p/15341719.html?? > > 可配合supervisor使用,保證進程常駐 > > 添加queueJobTest.ini文件輸入如下內容 > > > \[program:queueJobTest\] > user=root > command = php /home/wwwroot/test\_crm/think queue:listen --queue?queueJobTest --timeout 0 --memory 1024 > autostart=true > autorestart=false > stderr\_logfile=/tmp/queue\_stderr.log > stdout\_logfile=/tmp/queue\_stdout.log **1、首先,你需要在你的框架中下載queue這個擴展** ~~~ composer require topthink/think-queue ~~~ **2.公共配置,配置文件位于:config/queue.php** [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ~~~ return [ 'default' => 'redis', 'connections' => [ 'sync' => [ 'type' => 'sync', ], 'database' => [ 'type' => 'database', 'queue' => 'default', 'table' => 'jobs', 'connection' => null, ], 'redis' => [ 'type' => 'redis', 'queue' => 'default', 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'select' => 0, 'timeout' => 0, 'persistent' => false, ], ], 'failed' => [ 'type' => 'none', 'table' => 'failed_jobs', ], ]; ~~~ [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") **你可以在配置文件中選擇你需要使用數據庫的類型,根據自己的需求使用,這里我選擇的是redis** ~~~ 'default'=>'sync' //驅動類型,可選擇 sync(默認):同步執行,database:數據庫驅動,redis:Redis驅動//或其他自定義的完整的類名 ~~~ **3.創建任務類** **單模塊項目推薦使用?`app\job`?作為任務類的命名空間** **多模塊項目可用使用?`app\module\job`?作為任務類的命名空間 也可以放在任意可以自動加載到的地方** **我這里是在? app\\admin\\job? 創建了這個任務類** **里面執行了我發送郵件的任務,這里的例子可以實現延遲發送郵件的任務** **示例代碼如下** [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ~~~ <?php namespace app\admin\job; use think\facade\Log; use think\queue\Job; use tool\SendMail; class Test { public function fire(Job $job, $data){ if ($job->attempts()>3){ //執行失敗寫入錯誤日志 Log::error('fire執行失敗'); //刪除這個任務 $job->delete(); }else{ $toemail="407489255@qq.com"; //定義收件人的郵箱 $username="407486225@qq.com"; //發送方的郵箱地址 $password="qmxrvjgohiucbbgj"; //發送方郵箱的密碼 $setFrom="1223524552@qq.com"; //設置發件人信息 $addReplyTo="1003729782@qq.com"; //設置收件人信息 $contrnt="郵件內容是 <b>您的驗證碼是:123456</b>,哈哈哈!111122"; //設置郵件內容 SendMail::sendMail($toemail,$username,$password,$setFrom,$addReplyTo,$contrnt); //執行成功刪除這個任務 $job->delete(); } } } ~~~ [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ~~~ 這個是發送郵件的封住類 配合上面的使用 ~~~ [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ~~~ <?php namespace tool; use PHPMailer\PHPMailer\PHPMailer; class SendMail { public static function sendMail($toemail,$username,$password,$setFrom,$addReplyTo,$contrnt) { $toemail ="$toemail";//定義收件人的郵箱 $mail = new PHPMailer(); $mail->isSMTP();// 使用SMTP服務 $mail->CharSet = "utf8";// 編碼格式為utf8,不設置編碼的話,中文會出現亂碼 $mail->Host = "smtp.qq.com";// 發送方的SMTP服務器地址 $mail->SMTPAuth = true;// 是否使用身份驗證 $mail->Username = "$username";// 發送方的163郵箱用戶名,就是你申請163的SMTP服務使用的163郵箱</span><span style="color:#333333;"> $mail->Password = "$password";// 發送方的郵箱密碼,注意用163郵箱這里填寫的是“客戶端授權密碼”而不是郵箱的登錄密碼!</span><span style="color:#333333;"> $mail->SMTPSecure = "ssl";// 使用ssl協議方式</span><span style="color:#333333;"> $mail->Port = 465;// 163郵箱的ssl協議方式端口號是465/994 $mail->setFrom("$setFrom", "Mailer");// 設置發件人信息,如郵件格式說明中的發件人,這里會顯示為Mailer(xxxx@163.com),Mailer是當做名字顯示 $mail->addAddress($toemail, 'Wang');// 設置收件人信息,如郵件格式說明中的收件人,這里會顯示為Liang(yyyy@163.com) $mail->addReplyTo("$addReplyTo", "Reply");// 設置回復人信息,指的是收件人收到郵件后,如果要回復,回復郵件將發送到的郵箱地址 //$mail->addCC("xxx@163.com");// 設置郵件抄送人,可以只寫地址,上述的設置也可以只寫地址(這個人也能收到郵件) //$mail->addBCC("xxx@163.com");// 設置秘密抄送人(這個人也能收到郵件) //$mail->addAttachment("bug0.jpg");// 添加附件 $mail->Subject = "這是一個測試郵件";// 郵件標題 $mail->Body = "$contrnt";// 郵件正文 //$mail->AltBody = "This is the plain text純文本";// 這個是設置純文本方式顯示的正文內容,如果不支持Html方式,就會用到這個,基本無用 if (!$mail->send()) {// 發送郵件 echo "Message could not be sent."; echo "Mailer Error: " . $mail->ErrorInfo;// 輸出錯誤信息 } else { echo '發送成功'; } } } ~~~ [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") **4.發布任務? ?控制器調用這個? 進入發布任務** [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ~~~ <?php declare (strict_types = 1); namespace app\admin\controller; use think\facade\Queue; use think\Request; class index { /** * 顯示資源列表 * * @return \think\Response */ public function index() { //設置執行這個任務 Queue::later('20','app\admin\job\Test@fire',['name'=>'Test'],'fire'); } ~~~ [![復制代碼](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "復制代碼") ~~~ 注:一寫參數的解釋與使用方法 ~~~ > `think\facade\Queue::push($job, $data = '', $queue = null)`?和?`think\facade\Queue::later($delay, $job, $data = '', $queue = null)`?兩個方法,前者是立即執行,后者是在`$delay`秒后執行 `$job`?是任務名 單模塊的,且命名空間是`app\job`的,比如上面的例子一,寫`Job1`類名即可 多模塊的,且命名空間是`app\module\job`的,寫`model/Job1`即可 其他的需要些完整的類名,比如上面的例子二,需要寫完整的類名`app\lib\job\Job2` 如果一個任務類里有多個小任務的話,如上面的例子二,需要用@+方法名`app\lib\job\Job2@task1`、`app\lib\job\Job2@task2` `$data`?是你要傳到任務里的參數 `$queue`?隊列名,指定這個任務是在哪個隊列上執行,同下面監控隊列的時候指定的隊列名,可不填 ## 5.監聽任務并執行 這是我的執行的方法 ~~~ php think queue:listen --queue fire ~~~ **參數解釋** > php think queue:listen > php think queue:work 兩種,具體的可選參數可以輸入命令加 --help 查看 > 可配合supervisor使用,保證進程常駐
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看