国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

laravel 隊列

BDEEFE / 3211人閱讀

摘要:如果任務沒有在規定時間內完成,那么該有序集合的任務將會被重新放入隊列中。這兩個進程操縱了三個隊列,其中一個,負責即時任務,兩個,負責延時任務與待處理任務。如果任務執行成功,就會刪除中的任務,否則會被重新放入隊列中。

在實際的項目開發中,我們經常會遇到需要輕量級隊列的情形,例如發短信、發郵件等,這些任務不足以使用 kafka、RabbitMQ 等重量級的消息隊列,但是又的確需要異步、重試、并發控制等功能。通常來說,我們經常會使用 Redis、Beanstalk、Amazon SQS 來實現相關功能,laravel 為此對不同的后臺隊列服務提供統一的 API,本文將會介紹應用最為廣泛的 redis 隊列。


在講解 laravel 的隊列服務之前,我們要先說說基于 redis 的隊列服務。首先,redis設計用來做緩存的,但是由于它自身的某種特性使得它可以用來做消息隊列

redis 隊列的數據結構 List 鏈表

redis 做消息隊列的特性例如FIFO(先入先出)很容易實現,只需要一個 list 對象從頭取數據,從尾部塞數據即可。

相關的命令:(1)左側入右側出:lpush/rpop;(2)右側入左側出:rpush/lpop。

這個簡單的消息隊列很容易實現。

Zset 有序集合

有些任務場景,并不需要任務立刻執行,而是需要延遲執行;有些任務很重要,需要在任務失敗的時候重新嘗試。這些功能僅僅依靠 list 是無法完成的。這個時候,就需要 redis 的有序集合。

Redis 有序集合和 Redis 集合類似,是不包含相同字符串的合集。它們的差別是,每個有序集合的成員都關聯著一個評分 score,這個評分用于把有序集合中的成員按最低分到最高分排列。

單看有序集合和延遲任務并無關系,但是可以將有序集合的評分 score 設置為延時任務開啟的時間,之后輪詢這個有序集合,將到期的任務拿出來進行處理,這樣就實現了延遲任務的功能。

對于重要的需要重試的任務,在任務執行之前,會將該任務放入有序集合中,設置任務最長的執行時間。若任務順利執行完畢,該任務會在有序集合中刪除。如果任務沒有在規定時間內完成,那么該有序集合的任務將會被重新放入隊列中。

相關命令:

(1) ZADD 添加一個或多個成員到有序集合,或者如果它已經存在更新其分數。

(2) ZRANGEBYSCORE 按分數返回一個成員范圍的有序集合。

(3) ZREMRANGEBYRANK 在給定的索引之內刪除所有成員的有序集合。

laravel 隊列服務的任務調度

隊列服務的任務調度過程如下:

laravel 的隊列服務由兩個進程控制,一個是生產者,一個是消費者。這兩個進程操縱了 redis 三個隊列,其中一個 List,負責即時任務,兩個 Zset,負責延時任務與待處理任務。

生產者負責向 redis 推送任務,如果是即時任務,默認就會向 queue:default 推送;如果是延時任務,就會向 queue:default:delayed 推送。

消費者輪詢兩個隊列,不斷的從隊列中取出任務,先把任務放入 queue:default:reserved 中,再執行相關任務。如果任務執行成功,就會刪除 queue:default:reserved 中的任務,否則會被重新放入 queue:default:delayed 隊列中。

laravel 隊列服務的總體流程

任務分發流程:

任務處理器運作:

創建任務 queue 設置
"redis" => [
        "driver" => "redis",
        "connection" => "default",
        "queue" => "default",
        "retry_after" => 90,
    ],

在config/queue.php中進行配置
一般來說,默認的 redis 配置如上,connection 是 database 中 redis 的連接名稱;queue 是 redis 中的隊列名稱,值得注意的是,如果使用的是 redis 集群的話,這個需要使用 key hash tag,也就是 {default};當任務運行超過 retry_after 這個時間后,該任務會被重新放入隊列當中。

任務類的創建

任務類的結構很簡單,一般來說只會包含一個讓隊列用來調用此任務的 handle 方法。

如果想要使得任務被推送到隊列中,而不是同步執行,那么需要實現 IlluminateContractsQueueShouldQueue 接口。

如果想要讓任務推送到特定的連接中,例如 redis 或者 sqs,那么需要設置 conneciton 變量。

如果想要讓任務推送到特定的隊列中去,可以設置 queue 變量。

如果想要讓任務延遲推送,那么需要設置 delay 變量。

如果想要設置任務至多重試的次數,可以使用 tries 變量;

如果想要設置任務可以運行的最大秒數,那么可以使用 timeout 參數。

如果想要手動訪問隊列,可以使用 trait : IlluminateQueueInteractsWithQueue。

任務的分發
分發服務
寫好任務類后,就能通過 dispatch 輔助函數來分發它了。唯一需要傳遞給 dispatch 的參數是這個任務類的實例:

class PodcastController extends Controller
{
    public function store(Request $request)
    {
        // 創建播客...

        ProcessPodcast::dispatch($podcast);
    }
}

如果想延遲執行一個隊列中的任務,可以用任務實例的 delay 方法。

 ProcessPodcast::dispatch($podcast)
                ->delay(Carbon::now()->addMinutes(10));

通過推送任務到不同的隊列,可以給隊列任務分類,甚至可以控制給不同的隊列分配多少任務。要指定隊列的話,就調用任務實例的 onQueue 方法:

ProcessPodcast::dispatch($podcast)->onQueue("processing");

如果使用了多個隊列連接,可以將任務推到指定連接。要指定連接的話,可以在分發任務的時候使用 onConnection 方法:

ProcessPodcast::dispatch($podcast)->onConnection("redis
");

參考資源


KingFer

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29320.html

相關文章

  • 為什么 Laravel 會重復執行同一個隊列任務?

    摘要:把因執行超時的隊列從集合重新到當前執行的隊列中。從要執行的隊列中取任務可以看到在取要執行的隊列的時候,同時會放一份到一個有序集合中,并使用過期時間戳作為分值。 (原文鏈接:https://blog.tanteng.me/2017/...) 在 Laravel 中使用 Redis 處理隊列任務,框架提供的功能非常強大,但是最近遇到一個問題,就是發現一個任務被多次執行,這是為什么呢? 先說...

    vboy1010 評論0 收藏0
  • 分析Laravel隊列實現原理解決問題記錄

    摘要:在使用中的隊列時,產生沖突干擾。文件中的配置部分至此,兩個項目的隊列沖突原因就找到了。隊列監聽最后遇到問題,莫要病急亂投醫。從代碼入手,分析理解實現原理,找對點,解決方法也許很簡單,。 問題 公司項目使用Laravel的開發的兩個項目在同一個測試服務器部署,公用同一個redis。在使用laravel中的隊列時,產生沖突干擾。 查找問題原因 在laravel 隊列的操作類 Illumin...

    Corwien 評論0 收藏0
  • Laravel5.2隊列驅動expire參數設置帶來的重復執行問題 數據庫驅動

    摘要:已經取消了參數,都用來執行。取數據的過程事物處理已經打開。取得符合條件的隊列后程序會更新該條數據,并且更新完后即。 connections => [ .... database => [ driver => database, table => jobs, queue => defaul...

    ysl_unh 評論0 收藏0
  • Laravel5.4 隊列簡單配置與使用

    摘要:隊列的目的是將耗時的任務延時處理,比如發送郵件,從而大幅度縮短請求和相應的時間。每一種隊列驅動的配置都可以在該文件中找到,包括數據庫,,,,以及同步本地使用驅動。處理完畢后當前任務會自動刪除。基本就下面這個樣到此隊列簡單配置與使用就結束了。 概述 什么是隊列? 百度百科是這樣說的 隊列是在傳輸過程中保存數據的容器。 舉幾個生活中例子: iphone手機新款發布,三里屯iphone進的...

    _DangJin 評論0 收藏0

發表評論

0條評論

BDEEFE

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<