日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Go 語言實戰(zhàn):構(gòu)建強大的延遲任務(wù)隊列

來源: 責(zé)編: 時間:2024-02-01 12:50:08 193觀看
導(dǎo)讀介紹延遲隊列是一種數(shù)據(jù)結(jié)構(gòu),用于處理需要在未來某個特定時間執(zhí)行的任務(wù)。這些任務(wù)被添加到隊列中,并且指定了一個執(zhí)行時間,只有到達指定的時間點時才能從隊列中取出并執(zhí)行。在實際應(yīng)用中,延遲隊列可以用于處理各種需要延

介紹

延遲隊列是一種數(shù)據(jù)結(jié)構(gòu),用于處理需要在未來某個特定時間執(zhí)行的任務(wù)。這些任務(wù)被添加到隊列中,并且指定了一個執(zhí)行時間,只有到達指定的時間點時才能從隊列中取出并執(zhí)行。Orn28資訊網(wǎng)——每日最新資訊28at.com

在實際應(yīng)用中,延遲隊列可以用于處理各種需要延遲處理的任務(wù),例如發(fā)送郵件提醒、訂單自動取消、對超時任務(wù)的處理等。由于任務(wù)的執(zhí)行是在未來的某個時間點,因此這些任務(wù)不會立即執(zhí)行,而是存儲在隊列中,直到它的預(yù)定執(zhí)行時間才會被執(zhí)行。Orn28資訊網(wǎng)——每日最新資訊28at.com

Orn28資訊網(wǎng)——每日最新資訊28at.com

Simple

在 Go 語言中,我們可以使用 time 包提供的計時器功能,通過使用 Go 中的 slice 存儲延遲處理的任務(wù),實現(xiàn)一個簡單的延遲隊列的功能。Orn28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

type Task struct { ExecuteTime time.Time Job         func()}

首先,我們定義一個結(jié)構(gòu)體 Task,它包含一個可以執(zhí)行任務(wù)的函數(shù) Job,和一個執(zhí)行時間 ExecuteTime,這是期望執(zhí)行該函數(shù)的時間。Orn28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

type DelayQueue struct { TaskQueue []Task}

接下來,我們定義一個 DelayQueue 結(jié)構(gòu)體,它擁有一個 TaskQueue,這是一個 Task 類型的切片,用于保存待執(zhí)行任務(wù)的列表。Orn28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

// 添加任務(wù)func (d *DelayQueue) AddTask(t Task) { d.TaskQueue = append(d.TaskQueue, t)}// 移除任務(wù)func (d *DelayQueue) RemoveTask() { d.TaskQueue = d.TaskQueue[1:]}// 執(zhí)行任務(wù)func (d *DelayQueue) ExecuteTasks() { for len(d.TaskQueue) > 0 {  // 獲取隊列最頂部的任務(wù)  currentTask := d.TaskQueue[0]  // 如果執(zhí)行時間還沒到,等待  if time.Now().Before(currentTask.ExecuteTime) {   time.Sleep(currentTask.ExecuteTime.Sub(time.Now()))  }  // 執(zhí)行任務(wù)  currentTask.Job()  // 移除已執(zhí)行的任務(wù)  d.RemoveTask() }}

DelayQueue 包含三個方法:Orn28資訊網(wǎng)——每日最新資訊28at.com

  • 第一個方法是 AddTask(t Task)。此方法將提供的任務(wù) t 添加到 TaskQueue 的末尾。
  • 第二個方法是 RemoveTask()。此方法從 TaskQueue 中移除第一個任務(wù)。
  • 第三個方法是 ExecuteTasks()。此方法將執(zhí)行 TaskQueue 中的所有任務(wù)。如果隊列頂部任務(wù)的執(zhí)行時間還未到,該方法將等待。一旦時間到了,它將會執(zhí)行 Job 并從 TaskQueue 中移除該任務(wù)。

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

func main() { fmt.Println("Start DelayQueue") queue := DelayQueue{} firstTask := Task{  ExecuteTime: time.Now().Add(4 * time.Second),  Job: func() {   fmt.Println("Executed task 1 after delay")  }, } queue.AddTask(firstTask) secondTask := Task{  ExecuteTime: time.Now().Add(10 * time.Second),  Job: func() {   fmt.Println("Executed task 2 after delay")  }, } queue.AddTask(secondTask) queue.ExecuteTasks() fmt.Println("Done!")}

輸出結(jié)果:Orn28資訊網(wǎng)——每日最新資訊28at.com

Start DelayQueueExecuted task 1 after delayExecuted task 2 after delayDone!

在示例代碼中,我們創(chuàng)建了一個延時隊列,將任務(wù)添加到隊列中,并在指定的延時后執(zhí)行它們。Orn28資訊網(wǎng)——每日最新資訊28at.com

通過使用這些結(jié)構(gòu)體和方法,我們可以在 Go 中實現(xiàn)簡單的延遲執(zhí)行任務(wù)的功能。Orn28資訊網(wǎng)——每日最新資訊28at.com

但是,當(dāng) Go 程序重啟時,存儲在 slice 中的延遲處理的任務(wù)將全部丟失。Orn28資訊網(wǎng)——每日最新資訊28at.com

Complex

在 Go 程序中,如果想在重啟后保留數(shù)據(jù),我們可以將數(shù)據(jù)持久化到 Redis,可以使用 go-redis/redis 庫[1]與 Redis 交互。而對于延遲隊列的需求,則可以使用 Redis 的 ZSET(有序集合)特性來實現(xiàn)。Orn28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

// 定義一個全局的redisdb變量var redisdb *redis.Client// 初始化連接func initClient() (err error) { redisdb = redis.NewClient(&redis.Options{  Addr:     "localhost:6379",  Password: "", // no password set  DB:       0,  // use default DB }) _, err = redisdb.Ping().Result() if err != nil {  return err } return nil}

全局變量 redisdb 是 redis.Client 類型的指針,用來保存到 Redis 客戶端的引用。Orn28資訊網(wǎng)——每日最新資訊28at.com

initClient 函數(shù)初始化連接到 Redis 服務(wù)器,該服務(wù)器在本地主機的 6379 端口運行。它將一個新的 Redis 客戶端分配給 redisdb 變量。如果連接成功,它就會 ping Redis 服務(wù)器以測試連接。Orn28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

// 向隊列中添加任務(wù)func addTaskToQueue(task string, executeTime int64) { err := redisdb.ZAdd("delay-queue", redis.Z{  Score:  float64(executeTime),  Member: task, }).Err() if err != nil {  panic(err) }}

addTaskToQueue 函數(shù)將具有執(zhí)行時間的任務(wù)添加到 Redis 等待排序的集合 "delay-queue"。執(zhí)行時間是一個 UNIX 時間戳,作為排序集合中的項目的 score,允許 Redis 按照他們應(yīng)該執(zhí)行的時間來排序項目。Orn28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

// 從隊列中獲取并處理任務(wù)func getAndExecuteTasks() { for {  // 使用 ZRANGEBYSCORE 命令獲取分數(shù)(時間戳)<= 當(dāng)前時間的任務(wù)  tasks, err := redisdb.ZRangeByScore("delay-queue", redis.ZRangeBy{   Min: "-inf",   Max: fmt.Sprintf("%d", time.Now().Unix()),  }).Result()  if err != nil {   time.Sleep(1 * time.Second)   continue  }  // 處理任務(wù)  for _, task := range tasks {   fmt.Println("Executing task: ", task)   // 執(zhí)行完任務(wù)后,用 ZREM 移除該任務(wù)   redisdb.ZRem("delay-queue", task)  }  // 暫停一秒  time.Sleep(1 * time.Second) }}

getAndExecuteTasks 函數(shù)不斷檢查 "delay-queue"。它提取隊列中 score 小于或等于當(dāng)前時間戳的任務(wù),意味著這些任務(wù)現(xiàn)在應(yīng)該執(zhí)行或者他們應(yīng)該在過去就已經(jīng)執(zhí)行。獲取任務(wù)后,它打印任務(wù)(模擬執(zhí)行)并從隊列中刪除任務(wù)。Orn28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Orn28資訊網(wǎng)——每日最新資訊28at.com

func main() { err := initClient() if err != nil {  fmt.Println("redis connect error:", err)  return } // 添加一些測試任務(wù) addTaskToQueue("task1", time.Now().Add(10*time.Second).Unix()) addTaskToQueue("task2", time.Now().Add(20*time.Second).Unix()) // 執(zhí)行延遲隊列中的任務(wù) getAndExecuteTasks()}

輸出結(jié)果:Orn28資訊網(wǎng)——每日最新資訊28at.com

Executing task:  task1Executing task:  task2

main 函數(shù)調(diào)用這些函數(shù)。首先,它初始化 Redis 客戶端。如果初始化和連接成功,它將一些測試任務(wù)添加到隊列中,并啟動任務(wù)執(zhí)行循環(huán)。Orn28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)一下,這段 Go 代碼使用 Redis 的 Sorted Set 數(shù)據(jù)類型創(chuàng)建了一個延時隊列系統(tǒng),其中的任務(wù)按照他們的執(zhí)行時間進行排序,一個任務(wù)工作者循環(huán)獲取并執(zhí)行隊列中的任務(wù)。這是一個簡單而高效地實現(xiàn)作業(yè)調(diào)度系統(tǒng)的方法。Orn28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

本文我們分別實現(xiàn)簡單版和復(fù)雜版的延遲隊列,其中簡單版延遲隊列,只使用 Go 實現(xiàn),復(fù)雜版延遲隊列,使用 Go 和 Redis 實現(xiàn)。Orn28資訊網(wǎng)——每日最新資訊28at.com

(1) 只使用 Go 實現(xiàn)延遲隊列:Orn28資訊網(wǎng)——每日最新資訊28at.com

優(yōu)點:Orn28資訊網(wǎng)——每日最新資訊28at.com

  • 不需要外部依賴:只使用 Go 實現(xiàn)延遲隊列,你不需要安裝和維護外部的 Redis 服務(wù)器。

缺點:Orn28資訊網(wǎng)——每日最新資訊28at.com

  • 健壯性和持久性:如果程序崩潰或重新啟動,延遲隊列的數(shù)據(jù)可能會丟失。
  • 并發(fā)控制:使用 Go 內(nèi)置的數(shù)據(jù)結(jié)構(gòu)(如 channels 或 slices)在多個 goroutines 之間共享狀態(tài)變量可能需要精細的并發(fā)控制,比如使用 mutexes 或者 channels。

(2) 使用 Go + Redis 實現(xiàn)延遲隊列:Orn28資訊網(wǎng)——每日最新資訊28at.com

優(yōu)點:Orn28資訊網(wǎng)——每日最新資訊28at.com

  • 數(shù)據(jù)持久性:Redis 提供了數(shù)據(jù)持久性,即使在程序重啟或崩潰后,隊列中的數(shù)據(jù)依然可以恢復(fù)。
  • 簡化并發(fā):Redis 提供的數(shù)據(jù)結(jié)構(gòu)(如 sorted set)是原子操作,可以簡化并發(fā)控制。
  • 功能強大:使用 Redis,你可以利用其提供的一些內(nèi)建功能,如超時、TTL、持久化等。

缺點:Orn28資訊網(wǎng)——每日最新資訊28at.com

  • 需要額外的組件:使用 Redis 意味著需要安裝和運行 Redis 服務(wù)器,這可能增加系統(tǒng)的復(fù)雜性和運維成本。
  • 網(wǎng)絡(luò)延遲:如果 Go 程序和 Redis 服務(wù)器不在同一臺機器上,網(wǎng)絡(luò)延遲可能會影響延遲的準確性。

總的來說,如果我們對延遲隊列的持久性、準確性和并發(fā)性有高要求,那么 Go + Redis 的方案可能會更適合。如果我們想要一個更簡單的解決方案,并且可以容忍在程序崩潰時部分數(shù)據(jù)丟失,那么只使用 Go 實現(xiàn)可能會更合適。Orn28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-70436-0.htmlGo 語言實戰(zhàn):構(gòu)建強大的延遲任務(wù)隊列

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 提升代碼可讀性的秘密武器——Pygments庫詳解!

下一篇: 老板與秘書的故事理解CORS(跨域),真的超級簡單

標(biāo)簽:
  • 熱門焦點
  • 一文看懂為蘋果Vision Pro開發(fā)應(yīng)用程序

    譯者 | 布加迪審校 | 重樓蘋果的Vision Pro是一款混合現(xiàn)實(MR)頭戴設(shè)備。Vision Pro結(jié)合了虛擬現(xiàn)實(VR)和增強現(xiàn)實(AR)的沉浸感。其高分辨率顯示屏、先進的傳感器和強大的處理能力
  • 從零到英雄:高并發(fā)與性能優(yōu)化的神奇之旅

    作者 | 波哥審校 | 重樓作為公司的架構(gòu)師或者程序員,你是否曾經(jīng)為公司的系統(tǒng)在面對高并發(fā)和性能瓶頸時感到手足無措或者焦頭爛額呢?筆者在出道那會為此是吃盡了苦頭的,不過也得
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人員可能會涉及各種各樣的安全任務(wù),包括但不限于:開發(fā)某些安全工具的插件,滿足自己特定的安全需求;自定義github搜索工具,快速查找所需的安全資料、漏洞poc、exp
  • 騰訊蓋樓,字節(jié)拆墻

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之&ldquo;想重溫暴刷深淵、30+技能搭配暴搓到爽的游戲體驗嗎?一起上晶核,即刻暴打!&rdquo;曾憑借直播騰訊旗下代理格斗游戲《DNF》一
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產(chǎn)懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風(fēng)頭無兩。你可以說陳思誠的
  • 小米公益基金會捐贈2500萬元馳援北京、河北暴雨救災(zāi)

    8月2日消息,今日小米科技創(chuàng)始人雷軍在其微博上發(fā)布消息稱,小米公益基金會宣布捐贈2500萬元馳援北京、河北暴雨救災(zāi)。攜手抗災(zāi),京冀安康!以下為公告原文
  • 2021中國國際消費電子博覽會與青島國際軟件融合創(chuàng)新博覽會新聞發(fā)布會隆重舉行

    9月18日,2021中國國際消費電子博覽會與青島國際軟件融合創(chuàng)新博覽會新聞發(fā)布會在青島國際新聞中心隆重舉行。發(fā)布會上青島市政府領(lǐng)導(dǎo)聯(lián)袂出席,對本次雙展會情
  • 利用職權(quán)私自解除被封帳號 Meta開除20多名員工

    11月18日消息,據(jù)外媒援引知情人士表示,過去一年時間內(nèi),F(xiàn)acebook母公司Meta解雇或處罰了20多名員工以及合同工,指控這些人通過內(nèi)部系統(tǒng)以不當(dāng)方式重置用戶帳號,其
  • 榮耀Magic4 至臻版 首創(chuàng)智慧隱私通話 強勁影音系統(tǒng)

    2022年第一季度臨近尾聲,在該季度內(nèi),許多品牌陸續(xù)發(fā)布自己的最新產(chǎn)品,讓大家從全新的角度來了解當(dāng)今的手機技術(shù)。手機是電子設(shè)備中,更新迭代十分迅速的一款產(chǎn)品,基
Top 主站蜘蛛池模板: 永登县| 东台市| 临夏县| 乌兰察布市| 南部县| 扶风县| 盐亭县| 新安县| 九江县| 乐亭县| 巴南区| 鄂尔多斯市| 阿尔山市| 富平县| 黄骅市| 团风县| 黑水县| 措勤县| 东港市| 本溪市| 晋州市| 临汾市| 山阴县| 大关县| 安福县| 通山县| 东丽区| 彩票| 南涧| 精河县| 甘孜县| 开封县| 涿鹿县| 汨罗市| 库伦旗| 电白县| 阳城县| 南陵县| 叶城县| 富阳市| 武定县|