亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

laravel/lumen 使用 redis隊(duì)列

mengbo / 779人閱讀

摘要:配置項(xiàng)用于配置失敗隊(duì)列任務(wù)存放的數(shù)據(jù)庫(kù)及數(shù)據(jù)表。要使用隊(duì)列驅(qū)動(dòng),需要在配置文件中配置數(shù)據(jù)庫(kù)連接。如果應(yīng)用使用了,那么可以使用時(shí)間或并發(fā)來控制隊(duì)列任務(wù)。你可以使用命令運(yùn)行這個(gè)隊(duì)列進(jìn)程。如果隊(duì)列進(jìn)程意外關(guān)閉,它會(huì)自動(dòng)重啟啟動(dòng)隊(duì)列進(jìn)程。

一、概述

在Web開發(fā)中,我們經(jīng)常會(huì)遇到需要批量處理任務(wù)的場(chǎng)景,比如群發(fā)郵件、秒殺資格獲取等,我們將這些耗時(shí)或者高并發(fā)的操作放到隊(duì)列中異步執(zhí)行可以有效緩解系統(tǒng)壓力、提高系統(tǒng)響應(yīng)速度和負(fù)載能力。

二、配置文件

我們?nèi)匀粡呐渲梦募_始,首先我們需要在配置文件中配置默認(rèn)隊(duì)列驅(qū)動(dòng)為Redis。lumen沒有配置文件,可以從laravel項(xiàng)目中拷貝一份config目錄過來。
隊(duì)列配置文件是config/queue.php

return [

    "default" => env("QUEUE_DRIVER", "sync"),

    "connections" => [
        "database" => [
            "driver" => "database",
            "table" => "jobs",
            "queue" => "default",
            "expire" => 60,
        ],
        "redis" => [
            "driver" => "redis",
            "connection" => "default",
            "queue" => "default",
            "expire" => 60,
        ],
    ],

    "failed" => [
        "database" => "mysql", "table" => "failed_jobs",
    ],
];

配置文件第一個(gè)配置項(xiàng)default用于指定默認(rèn)的隊(duì)列驅(qū)動(dòng),修改.env中的QUEUE_DRIVER即可。

connections配置項(xiàng)包含了Laravel支持的所有隊(duì)列驅(qū)動(dòng),我們使用Redis驅(qū)動(dòng),所以需要配置redis項(xiàng):connection對(duì)應(yīng)config/database.php中redis的default配置;queue為默認(rèn)隊(duì)列名稱;expire為隊(duì)列任務(wù)過期時(shí)間(秒)。這里我們可以保持其默認(rèn)配置不變。

failed配置項(xiàng)用于配置失敗隊(duì)列任務(wù)存放的數(shù)據(jù)庫(kù)及數(shù)據(jù)表。這里我們需要按照自己的數(shù)據(jù)庫(kù)配置對(duì)其做相應(yīng)修改。

要使用 redis 隊(duì)列驅(qū)動(dòng),需要在配置文件 config/database.php 中配置 Redis 數(shù)據(jù)庫(kù)連接。

如果 Redis 隊(duì)列連接使用 Redis Cluster(集群),隊(duì)列名稱必須包含 key hash tag,以確保給定隊(duì)列對(duì)應(yīng)的所有 Redis keys 都存放到同一個(gè) hash slot

"redis" => [
    "driver" => "redis",
    "connection" => "default",
    "queue" => "{default}",
    "retry_after" => 90,
],
注:對(duì)一般中小型應(yīng)用推薦使用 Redis 作為隊(duì)列驅(qū)動(dòng)。
三、驅(qū)動(dòng)預(yù)備知識(shí)

數(shù)據(jù)庫(kù)
要使用 database 隊(duì)列驅(qū)動(dòng),你需要數(shù)據(jù)表保存任務(wù)信息(比如失敗任務(wù))。要生成創(chuàng)建這些表的遷移,可以在項(xiàng)目目錄下運(yùn)行 Artisan 命令 queue:table,遷移被創(chuàng)建之后,可以使用 migrate 命令生成這些表:

php artisan queue:table
php artisan queue:failed_jobs

php artisan migrate

運(yùn)行后生成failed_jobs、jobsmigrations三張表。

四、創(chuàng)建任務(wù) 1、生成任務(wù)類

通常,所有的任務(wù)類都保存在 app/Jobs 目錄。laravelapp/Jobs 不存在,在運(yùn)行 Artisan 命令 make:job 的時(shí)候,它將會(huì)自動(dòng)創(chuàng)建。你可以通過 Artisan CLI 來生成隊(duì)列任務(wù)類:

php artisan make:job ProcessPodcast

生成的類都實(shí)現(xiàn)了 IlluminateContractsQueueShouldQueue 接口, 告訴 Laravel 將該任務(wù)推送到隊(duì)列,而不是立即運(yùn)行:

lumenapp/Jobs目錄已經(jīng)存在,由于不能執(zhí)行artisan命令,直接復(fù)制目錄中的ExampleJob.php即可。該文件繼承Job.php 從而實(shí)現(xiàn)了ShouldQueue。

2、任務(wù)類結(jié)構(gòu)

任務(wù)類非常簡(jiǎn)單,通常只包含處理該任務(wù)的 handle 方法,在任務(wù)被處理的時(shí)候調(diào)用,注意我們可以在任務(wù)的 handle 方法中進(jìn)行依賴注入。Laravel 服務(wù)容器會(huì)自動(dòng)注入這些依賴。

3、分發(fā)任務(wù)

創(chuàng)建好任務(wù)類后,就可以通過任務(wù)自身的 dispatch 方法將其分發(fā)到隊(duì)列。dispatch 方法需要的唯一參數(shù)就是該任務(wù)的實(shí)例:

lumen中用法:

4、指定最大失敗次數(shù)

指定隊(duì)列任務(wù)最大失敗次數(shù)的一種實(shí)現(xiàn)方式是通過 Artisan 命令 --tries 切換:

php artisan queue:work --tries=3

不過,你還可以在任務(wù)類自身定義最大失敗次數(shù)來實(shí)現(xiàn)更加細(xì)粒度的控制,如果最大失敗次數(shù)在任務(wù)中指定,則其優(yōu)先級(jí)高于命令行指定的數(shù)值:

   
5、超時(shí)
注:timeout 方法為 PHP7.1+pcntl 擴(kuò)展做了優(yōu)化。

類似的,隊(duì)列任務(wù)最大運(yùn)行時(shí)長(zhǎng)(秒)可以通過 Artisan 命令上的 --timeout 開關(guān)來指定:

php artisan queue:work --timeout=30

同樣,你也可以在任務(wù)類中定義該任務(wù)允許運(yùn)行的最大時(shí)長(zhǎng)(單位:秒),任務(wù)中指定的超時(shí)時(shí)間優(yōu)先級(jí)也高于命令行定義的數(shù)值:


6、基于時(shí)間的嘗試次數(shù)

除了定義在任務(wù)失敗前的最大嘗試次數(shù)外,還可以定義在指定時(shí)間內(nèi)允許任務(wù)的最大嘗試次數(shù),這可以通過在任務(wù)類中添加 retryUntil 方法來實(shí)現(xiàn):

/**
 * Determine the time at which the job should timeout.
 *
 * @return DateTime
 */
public function retryUntil()
{
    return now()->addSeconds(5);
}
注:還可以在隊(duì)列時(shí)間監(jiān)聽器中定義 retryUntil 方法。
7、頻率限制
注:該功能要求應(yīng)用可以與 Redis 服務(wù)器進(jìn)行交互。

如果應(yīng)用使用了 Redis,那么可以使用時(shí)間或并發(fā)來控制隊(duì)列任務(wù)。該功能特性在隊(duì)列任務(wù)與有頻率限制的 API 交互時(shí)很有幫助,例如,通過 throttle 方法,你可以限定給定類型任務(wù)每 60 秒只運(yùn)行 10 次。如果不能獲取鎖,需要將任務(wù)釋放回隊(duì)列以便可以再次執(zhí)行:

Redis::throttle("key")->allow(10)->every(60)->then(function () {
    // Job logic...
}, function () {
    // Could not obtain lock...

    return $this->release(10);
});

注:在上面的例子中,上面的方法可能無法找到,但是直接復(fù)制即可使用(具體還不清楚,知道的大神可以留言指教)。key 可以是任意可以唯一標(biāo)識(shí)你想要限定訪問頻率的任務(wù)類型的字符串。舉個(gè)例子,這個(gè)鍵可以基于任務(wù)類名和操作 Eloquent 模型的 ID 進(jìn)行構(gòu)建。

8、最大進(jìn)程數(shù)量

除此之外,還可以指定可以同時(shí)處理給定任務(wù)的最大進(jìn)程數(shù)量。這個(gè)功能在隊(duì)列任務(wù)正在編輯一次只能由一個(gè)任務(wù)進(jìn)行處理的資源時(shí)很有用。例如,使用 funnel 方法你可以給定類型任務(wù)一次只能由一個(gè)工作進(jìn)程進(jìn)行處理:

Redis::funnel("key")->limit(1)->then(function () {
    // Job logic...
}, function () {
    // Could not obtain lock...

    return $this->release(10);
});
注:使用頻率限制時(shí),任務(wù)在運(yùn)行成功之前需要的最大嘗試次數(shù)很難權(quán)衡,因此,將頻率限制和基于時(shí)間的嘗試次數(shù)結(jié)合起來使用是個(gè)不錯(cuò)的選擇。
9、運(yùn)行隊(duì)列進(jìn)程

Laravel 自帶了一個(gè)隊(duì)列進(jìn)程用來處理被推送到隊(duì)列的新任務(wù)。你可以使用 queue:work 命令運(yùn)行這個(gè)隊(duì)列進(jìn)程。請(qǐng)注意,隊(duì)列進(jìn)程開始運(yùn)行后,會(huì)持續(xù)監(jiān)聽隊(duì)列,直至你手動(dòng)停止或關(guān)閉終端:

php artisan queue:work
注:為了保持隊(duì)列進(jìn)程 queue:work 持續(xù)在后臺(tái)運(yùn)行,需要使用進(jìn)程守護(hù)程序,比如 Supervisor 來確保隊(duì)列進(jìn)程持續(xù)運(yùn)行。

簡(jiǎn)單處理可以使用 php artisan queue:work --daemon &

10、運(yùn)行隊(duì)列監(jiān)聽器

開始進(jìn)行隊(duì)列監(jiān)聽
laravel 包含了一個(gè) Artisan 命令來運(yùn)行推送到隊(duì)列中的任務(wù)的執(zhí)行。你可以使用 queue:listen 命令來運(yùn)行監(jiān)聽器:

php artisan queue:listen
注意:queue:listen要比queue:work --daemon 性能差很多。

你也可以指定監(jiān)聽哪一個(gè)連接的隊(duì)列:

php artisan queue:listen connection-name

請(qǐng)記住,隊(duì)列進(jìn)程是長(zhǎng)生命周期的進(jìn)程,會(huì)在啟動(dòng)后駐留內(nèi)存。若應(yīng)用有任何改動(dòng)將不會(huì)影響到已經(jīng)啟動(dòng)的進(jìn)程。所以請(qǐng)?jiān)诎l(fā)布程序后,重啟隊(duì)列進(jìn)程。

可以通過 Aritisan 命令 queue:restart 來優(yōu)雅地重啟隊(duì)列進(jìn)程:

php artisan queue:restart

該命令將在隊(duì)列進(jìn)程完成正在進(jìn)行的任務(wù)后,結(jié)束該進(jìn)程,避免隊(duì)列任務(wù)的丟失或錯(cuò)誤。由于隊(duì)列進(jìn)程會(huì)在執(zhí)行 queue:restart 命令后死掉,你仍然需要通過進(jìn)程守護(hù)程序如 Supervisor 來自動(dòng)重啟隊(duì)列進(jìn)程。

注:隊(duì)列使用緩存來存儲(chǔ)重啟信號(hào),所以在使用此功能前你需要驗(yàn)證緩存驅(qū)動(dòng)配置正確。
五、配置 Supervisor

安裝 Supervisor

Supervisor 是 Linux 系統(tǒng)中常用的進(jìn)程守護(hù)程序。如果隊(duì)列進(jìn)程 queue:work 意外關(guān)閉,它會(huì)自動(dòng)重啟啟動(dòng)隊(duì)列進(jìn)程。在 Ubuntu 安裝Supervisor 非常簡(jiǎn)單:

sudo apt-get install supervisor
注:如果自己配置 Supervisor 有困難,可以考慮使用 Laravel Forge,它會(huì)為 Laravel 項(xiàng)目自動(dòng)安裝并配置 Supervisor。

配置 Supervisor

Supervisor 配置文件通常存放在 /etc/supervisor/conf.d 目錄,在該目錄下,可以創(chuàng)建多個(gè)配置文件指示 Supervisor 如何監(jiān)視進(jìn)程,例如,讓我們創(chuàng)建一個(gè)開啟并監(jiān)視 queue:work 進(jìn)程的 laravel-worker.conf 文件:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d 
command= php /home/forge/app.com/artisan queue:work redis --sleep=3 --tries=3 --daemon
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log

在本例中,numprocs 指令讓 Supervisor 運(yùn)行 8 個(gè) queue:work 進(jìn)程并監(jiān)視它們,如果失敗的話自動(dòng)重啟。當(dāng)然,你需要修改 queue:work sqs 的 command 指令來映射你的隊(duì)列連接。

啟動(dòng) Supervisor

當(dāng)成功創(chuàng)建配置文件后,需要刷新 Supervisor 的配置信息并使用如下命令啟動(dòng)進(jìn)程:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

使用top 或者ps aux | grep php 命令可以看到啟動(dòng)的php進(jìn)程。
你可以通過 Supervisor 官方文檔獲取更多信息。

CentOS中配置稍微有些區(qū)別:

yum -y install python-setuptools
easy_install supervisor

supervisor安裝完成后會(huì)生成三個(gè)執(zhí)行程序:

supervisortd  supervisor的守護(hù)進(jìn)程服務(wù)(用于接收進(jìn)程管理命令)
supervisorctl 客戶端(用于和守護(hù)進(jìn)程通信,發(fā)送管理進(jìn)程的指令)
echo_supervisord_conf 生成初始配置文件程序。

將配置文件重定向到/etc/目錄下面

mkdir /etc/supervisor
echo_supervisord_conf > /etc/supervisor/supervisord.conf

默認(rèn)配置文件在/etc/supervisor/supervisord.conf 。
編輯配置文件:找到最后一行,引入自定義配置文件

;[include]
;files = conf.d/*.ini

去掉[include]files前面的“;” include生效,在/etc/supervisor/下創(chuàng)建conf.d文件夾,在其中添加類似ubuntu中配置文件。

mkdir conf.d
啟動(dòng):
supervisord 啟動(dòng)supervisor
supervisorctl 控制supervisord
啟動(dòng)后會(huì)看到一堆信息,但是不影響。
/usr/lib/python2.7/site-packages/supervisor/options.py:296: UserWarning: 
Supervisord is running as root and it is searching for its configuration file 
in default locations (including its current working directory); 
you probably want to specify a "-c" argument specifying an absolute path 
to a configuration file for improved security.
  "Supervisord is running as root and it is searching "

可指定配置文件: supervisord -c /etc/supervisord.conf

每次修改配置后都需要重啟supervisor才能生效

supervisorctl reload 

監(jiān)控狀態(tài):

supervisorctl status

附一個(gè)sqs錯(cuò)誤處理,redis方式不使用sqs

In SqsConnector.php line 26:
                                       
  Class "AwsSqsSqsClient" not found 

使用 composer 安裝:

composer require aws/aws-sdk-php-laravel

本文參考:laravel學(xué)院

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/28721.html

相關(guān)文章

  • Laravel、Lumen 錯(cuò)誤集錦

    摘要:解決這句移到下方,可解決隊(duì)列錯(cuò)誤發(fā)現(xiàn)異步有些不會(huì)處理,同問這個(gè)問題,目前沒有解決。開啟后,自動(dòng)監(jiān)聽任務(wù),線程數(shù)決定刷新頻率。問題可使用重新生成在環(huán)境中也會(huì)有遇到,需要設(shè)置的和項(xiàng)目一致 持續(xù)更新。。。 這里收集了遇見的laravel 或則 lumen 錯(cuò)誤 和解決方法。 controller或者model不存在 1. not found Class AppUserController ...

    張率功 評(píng)論0 收藏0
  • 基于 lumen 的微服務(wù)架構(gòu)實(shí)踐

    摘要:現(xiàn)在的提供了一種更易于使用和維護(hù)的計(jì)劃任務(wù)方式。注意事項(xiàng)建議開啟這樣會(huì)極大的加速類的加載。 lumen 為速度而生的 Laravel 框架 官網(wǎng)的介紹很簡(jiǎn)潔,而且 lumen 確實(shí)也很簡(jiǎn)單,我在調(diào)研了 lumen 相關(guān)組件(比如緩存,隊(duì)列,校驗(yàn),路由,中間件和最重要的容器)之后認(rèn)為已經(jīng)能夠滿足我目前這個(gè)微服務(wù)的需求了。 任務(wù)目標(biāo) showImg(https://segmentfault...

    hatlonely 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<