laravel5.6 基於redis,使用消息隊列(郵件推送)


郵件發送如何配置參考:https://www.cnblogs.com/clubs/p/10640682.html

用到的用戶表:

 1 CREATE TABLE `recruit_users` (
 2   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 3   `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
 4   `phone` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT '手機號碼',
 5   `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
 6   `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
 7   `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
 8   `status` tinyint(4) DEFAULT '1' COMMENT '帳戶狀態(0失效 1正常)',
 9   `created_at` timestamp NULL DEFAULT NULL,
10   `updated_at` timestamp NULL DEFAULT NULL,
11   `lastlogintime` timestamp NULL DEFAULT NULL COMMENT '最后登陸時間',
12   PRIMARY KEY (`id`)
13 ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

1.在 Laravel 中使用 Redis 你需用通過 Composer 來安裝 predis/predis 包文件,不然會報錯Class 'Predis\Client' not found

composer require predis/predis ^1.1

2. laravel隊列配置(配置文件 .env 和 config/queue.php)

優先配置.env 文件如下:

1 QUEUE_DRIVER=redis
2 
3 REDIS_HOST=127.0.0.1
4 REDIS_PASSWORD=******
5 REDIS_PORT=6379

當.env 文件沒有配置 或者 設置變量為空時,會按照 config/queue.php 文件的配置信息運行laravel,一般只配置.env文件,不修改queue.php文件
config/queue.php 文件如下:

 1 return [
 2     'default' => env('QUEUE_DRIVER', 'redis'),//修改隊列驅動,使用redis
 3 
 4     'connections' => [
 5         'sync' => [
 6             'driver' => 'sync',
 7         ],
 8 
 9         'database' => [
10             'driver' => 'database',
11             'table' => 'jobs',
12             'queue' => 'default',
13             'retry_after' => 90,
14         ],
15 
16         'beanstalkd' => [
17             'driver' => 'beanstalkd',
18             'host' => 'localhost',
19             'queue' => 'default',
20             'retry_after' => 90,
21         ],
22 
23         'sqs' => [
24             'driver' => 'sqs',
25             'key' => env('SQS_KEY', 'your-public-key'),
26             'secret' => env('SQS_SECRET', 'your-secret-key'),
27             'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
28             'queue' => env('SQS_QUEUE', 'your-queue-name'),
29             'region' => env('SQS_REGION', 'us-east-1'),
30         ],
31 
32         'redis' => [
33             'driver' => 'redis',
34             'connection' => 'default',
35             'queue' => 'default',
36             'retry_after' => 90,
37             'block_for' => null,
38         ],
39     ],
40 
41     'failed' => [
42         'database' => env('DB_CONNECTION', 'mysql'),//隊列執行失敗 存放的數據庫
43         'table' => 'failed_jobs',//隊列執行失敗 存放的表
44     ],
45 ];

Redis 在應用中的配置文件存儲在 config/database.php,在這個文件中,你可以看到一個包含了 Redis 服務信息的 redis 數組:

1 'redis' => [
2     'client' => 'predis',
3     'default' => [
4         'host' => env('REDIS_HOST', '127.0.0.1'),
5         'password' => env('REDIS_PASSWORD', null),
6         'port' => env('REDIS_PORT', 6379),
7         'database' => 0,//選擇使用的redis庫
8     ],
9 ],

3. 創建隊列任務類(app/Jobs/xxx.php)

使用artisan命令 在app/Jobs 目錄下創建執行隊列任務的類:
php artisan make:job SendEmail
app/Jobs/SendEmail.php 代碼如下:

 1 <?php
 2 
 3 namespace App\Jobs;
 4 
 5 use Illuminate\Bus\Queueable;
 6 use Illuminate\Queue\SerializesModels;
 7 use Illuminate\Queue\InteractsWithQueue;
 8 use Illuminate\Contracts\Queue\ShouldQueue;
 9 use Illuminate\Foundation\Bus\Dispatchable;
10 use Illuminate\Support\Facades\Mail;
11 use App\Models\RecruitUser as User;
12 
13 class SendEmail implements ShouldQueue
14 {
15     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
16 
17     protected $user;
18 
19     /**
20      * Create a new job instance.
21      *
22      * @return void
23      */
24     public function __construct(User $user)
25     {
26         $this->user = $user;
27     }
28 
29     /**
30      * Execute the job.
31      *
32      * @return void
33      */
34     public function handle()
35     {
36         $user = $this->user;
37         Mail::raw('這里填寫郵件的內容', function ($message) {
38             // 收件人的郵箱地址
39             $message->to($this->user->email);
40             // 郵件主題
41             $message->subject('隊列發送郵件');
42         });
43     }
44 }

4. 控制器將數據添加到隊列中

 1 <?php
 2 
 3 namespace App\Http\Controllers\Home;
 4 
 5 use App\Jobs\SendEmail;
 6 use App\Http\Controllers\Controller;
 7 use Illuminate\Http\Request;
 8 use App\Models\RecruitUser as User;
 9 
10 class MessageController extends Controller
11 {
12     public function index()
13     {
14         $user = User::find(2);
15         $res = $this->dispatch(new SendEmail($user));
16         dd($res);
17     }
18 }

5. 啟動、監聽隊列

5.1 php artisan queue:work —queue=sendEmail
指定啟動sendEmail隊列

5.2 php artisan queue:restart
重啟隊列

5.3 php artisan queue:work —timeout=60
隊列進程 queue:work 可以設定超時 —timeout 項。該 —timeout 控制隊列進程執行每個任務的最長時間,如果超時,該進程將被關閉。
注:參數項 —timeout 的值應該始終小於配置項 retry_after 的值,這是為了確保隊列進程總在任務重試以前關閉。如果 —timeout 比retry_after 大,那么你的任務可能被執行兩次。

5.4 php artisan queue:work —sleep=3
休眠時間,每執行一個任務后休眠3秒

 

監聽三種情況:

 queue:work 默認只執行一次隊列請求, 當請求執行完成后就終止;

 queue:listen 監聽隊列請求,只要運行着,就能一直接受請求,除非手動終止;

 queue:work --daemon 同listen一樣,不同的是work不需要再次加載框架,直接運行任務,一般推薦使用這個來處理隊列監聽。

 注意: 使用 queue:work —daemon , 當更新代碼的時候, 需要停止, 然后重新啟動, 這樣才能把修改的代碼應用上

6. 設置API路由,執行請求,執行隊列任務

1 Route::post('messageindex', ['uses' => $namespaces . 'MessageController@index', 'as' => 'messageIndex']);

使用postman發送post請求即可以測試發送郵件隊列

 

 查看redis是否有隊列數據

 

命令行監聽界面:

 

查看郵箱發件箱,郵件已發出

7. 使用Supervisor將隊列任務啟動 添加到守護進程中

推薦安裝Supervisor,將 php artisan queue:work —queue sendEmail 等一系列隊列進程,添加到進程保護中,防止中途崩潰時候,可以自救,哈哈~😄
關於Supervisor,可以參考《centos安裝Supervisor以及簡單配置(添加進程守護)

總結

  1. 引入 predis/predis 包
  2. laravel隊列配置(配置文件 .env 和 config/queue.php)
  3. 創建隊列任務類(app/Jobs/xxx.php)
  4. 控制器將數據添加到隊列中
  5. 啟動、監聽隊列
  6. 設置API路由,執行請求,執行隊列任務
  7. 使用Supervisor將隊列任務啟動 添加到守護進程中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM