欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang實現(xiàn)redis的延時消息隊列功能示例

 更新時間:2019年11月25日 16:08:33   作者:菜菜jjj  
這篇文章主要介紹了golang實現(xiàn)redis的延時消息隊列功能,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在學(xué)習(xí)過程中發(fā)現(xiàn)redis的zset還可以用來實現(xiàn)輕量級的延時消息隊列功能,雖然可靠性還有待提高,但是對于一些對數(shù)據(jù)可靠性要求不那么高的功能要求完全可以實現(xiàn)。本次主要采用了redis中zset中的zadd, zrangebyscore 和 zdel來實現(xiàn)一個小demo。

提前準備 安裝redis, redis-go

因為用的是macOS, 直接

$ brew install redis
$ go get github.com/garyburd/redigo/redis

又因為比較懶,生成任務(wù)的唯一id時,直接采用了bson中的objectId,所以:

$ go get gopkg.in/mgo.v2/bson

唯一id不是必須有,但如果之后有實際應(yīng)用需要攜帶,便于查找相應(yīng)任務(wù)。

生產(chǎn)者

通過一個for循環(huán)生成10w個任務(wù), 每一個任務(wù)有不同的時間

func producer() {
 count := 0
 //生成100000個任務(wù)
 for count < 100000 {
 count++
 dealTime := int64(rand.Intn(5)) + time.Now().Unix()
 uuid := bson.NewObjectId().Hex()
 redis.Client.AddJob(&job.JobMessage{
 Id: uuid,
 DealTime: dealTime,
 }, + int64(dealTime))
 }
}

其中AddJob函數(shù)在另一個包中, 將上一個函數(shù)中隨機生成的時間作為需要處理的時間戳.

// 添加任務(wù)
func (client *RedisClient) AddJob(msg *job.JobMessage, dealTime int64) {
 conn := client.Get()
 defer conn.Close()

 key := "JOB_MESSAGE_QUEUE"
 conn.Do("zadd", key, dealTime, util.JsonEncode(msg))
}

消費者

消費者處理流程分為兩個步驟:

  • 獲取小于等于當(dāng)前時間戳的任務(wù)
  • 通過刪除當(dāng)前任務(wù)來判斷誰獲得了當(dāng)前任務(wù)

因為在獲取小于等于當(dāng)前時間戳的任務(wù)時,可能有多個go routine同時讀到了當(dāng)前任務(wù),而只有一個任務(wù)可以來處理當(dāng)前任務(wù)。因此我們需要通過一個方案來判斷究竟由誰來處理這個任務(wù)(當(dāng)然如果只有一個消費者可以讀到就直接處理):這個時候可以通過redis的刪除操作來獲取,因為刪除指定value時只有成功的操作才會返回不為0,所以我們可以認為刪除當(dāng)前隊列成功的那個go routine拿到了當(dāng)前的任務(wù)。

下面是代碼:

// 消費者
func consumer() {
 // 啟動10個go routine一起去拿
 count := 0
 for count < 10 {
 go func() {
 for {
 jobs := redis.Client.GetJob()
 if len(jobs) <= 0 {
  time.Sleep(time.Second * 1)
  continue
 }
 currentJob := jobs[0]
 // 如果當(dāng)前搶redis隊列成功,
 if redis.Client.DelJob(currentJob) > 0 {
  var jobMessage job.JobMessage
  util.JsonDecode(currentJob, &jobMessage) //自定義的json解析函數(shù)
  handleMessage(&jobMessage)
 }

 }

 }()
 count++
 }
}

// 處理任務(wù)用函數(shù)
func handleMessage(msg *job.JobMessage) {
 fmt.Printf("deal job: %s, require time: %d \n", msg.Id, msg.DealTime)
 go func() {
 countChan <- true
 }()
}

redis部分的代碼,獲取任務(wù)和刪除任務(wù)

// 獲取任務(wù)
func (client *RedisClient) GetJob() []string {
 conn := client.Get()
 defer conn.Close()

 key := "JOB_MESSAGE_QUEUE"
 timeNow := time.Now().Unix()
 ret, err := redis.Strings(conn.Do("zrangebyscore", key, 0, timeNow, "limit", 0, 1))
 if err != nil {
 panic(err)
 }
 return ret
}

// 刪除當(dāng)前任務(wù), 用來判斷是否搶到了當(dāng)前任務(wù)
func (client *RedisClient) DelJob(value string) int {
 conn := client.Get()
 defer conn.Close()

 key := "JOB_MESSAGE_QUEUE"
 ret, err := redis.Int(conn.Do("zrem", key, value))
 if err != nil {
 panic(err)
 }
 return ret
}

代碼大抵如此。最后跑起來之后,大概每3-4秒鐘能夠處理掉1w個任務(wù),速度上確實是...

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Go語言中排序的3種實現(xiàn)方法

    Go語言中排序的3種實現(xiàn)方法

    在寫代碼過程中,排序是經(jīng)常會遇到的需求,這篇文章主要為大家介紹三種常用的方法,文中的示例代碼簡潔易懂,需要的小伙伴可以參考下
    2023-08-08
  • Go語言實現(xiàn)JSON解析的神器詳解

    Go語言實現(xiàn)JSON解析的神器詳解

    php轉(zhuǎn)go是大趨勢,越來越多公司的php服務(wù)都在用go進行重構(gòu),重構(gòu)過程中,會發(fā)現(xiàn)php的json解析操作是真的香。本文和大家分享了一個Go語言實現(xiàn)JSON解析的神器,希望對大家有所幫助
    2023-01-01
  • 詳解Go語言如何實現(xiàn)并發(fā)安全的map

    詳解Go語言如何實現(xiàn)并發(fā)安全的map

    go語言提供的數(shù)據(jù)類型中,只有channel是并發(fā)安全的,基礎(chǔ)map并不是并發(fā)安全的,本文為大家整理了三種實現(xiàn)了并發(fā)安全的map的方案,有需要的可以參考下
    2023-12-12
  • golang關(guān)閉chan通道的方法示例

    golang關(guān)閉chan通道的方法示例

    在go語言中,通道(channel)是一個非常重要的概念,通道提供了一種在不同 goroutine 之間安全地傳遞數(shù)據(jù)的方式,在本文中,我們將討論如何關(guān)閉通道以及在關(guān)閉通道時需要考慮的事項,需要的朋友可以參考下
    2024-02-02
  • Go中JSON解析時tag的使用

    Go中JSON解析時tag的使用

    本文主要介紹了Go中JSON解析時tag的使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Go 語言結(jié)構(gòu)實例分析

    Go 語言結(jié)構(gòu)實例分析

    在本篇文章里小編給大家整理的是一篇關(guān)于Go 語言結(jié)構(gòu)實例分析的相關(guān)知識點,有興趣的朋友們可以學(xué)習(xí)下。
    2021-07-07
  • 使用Go重試機制代碼更可靠

    使用Go重試機制代碼更可靠

    這篇文章主要為大家介紹了使用Go重試機制的使用,使你的代碼更加可靠,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 一文搞懂Golang 時間和日期相關(guān)函數(shù)

    一文搞懂Golang 時間和日期相關(guān)函數(shù)

    這篇文章主要介紹了Golang 時間和日期相關(guān)函數(shù),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • go語言Timer計時器的用法示例詳解

    go語言Timer計時器的用法示例詳解

    Go語言的標(biāo)準庫里提供兩種類型的計時器Timer和Ticker。這篇文章通過實例代碼給大家介紹go語言Timer計時器的用法,代碼簡單易懂,感興趣的朋友跟隨小編一起看看吧
    2020-05-05
  • Go泛型的理解和使用小結(jié)

    Go泛型的理解和使用小結(jié)

    泛型是一種非常強大的編程技術(shù),可以提高代碼的復(fù)用性和可讀性,通過泛型容器和類型參數(shù)化,Go語言中的泛型可以實現(xiàn)更加靈活和通用的編程,提高代碼的復(fù)用性和可維護性,本文給大家介紹Go泛型的理解和使用,感興趣的朋友一起看看吧
    2023-12-12

最新評論