精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

通過 SingleFlight 模式學習 Go 并發編程

開發
最近接觸到微服務框架go-zero,翻看了整個框架代碼,發現結構清晰、代碼簡潔,所以決定閱讀源碼學習下。

本次閱讀的源碼位于 core/syncx/singleflight.go 

 go-zero  SingleFlight 的作用是: 將并發請求合并成一個請求,以減少對下層服務的壓力。

應用場景

1.查詢緩存時,合并請求,提升服務性能。

假設有一個 IP 查詢的服務,每次用戶請求先在緩存中查詢一個 IP 的歸屬地,如果緩存中有結果則直接返回,不存在則進行 IP 解析操作。

如上圖所示,n 個用戶請求查詢同一個 IP(8.8.8.8)就會對應 n 個 Redis 的查詢,在高并發場景下,如果能將 n 個 Redis 查詢合并成一個 Redis 查詢,那么性能肯定會提升很多,而 SingleFlight 就是用來實現請求合并的,效果如下:

2.防止緩存擊穿。

緩存擊穿問題是指:在高并發的場景中,大量的請求同時查詢一個 key ,如果這個 key 正好過期失效了,就會導致大量的請求都打到數據庫,導致數據庫的連接增多,負載上升。

通過 SingleFlight 可以將對同一個Key的并發請求進行合并,只讓其中一個請求到數據庫進行查詢,其他請求共享同一個結果,可以很大程度提升并發能力。

應用方式

直接上代碼:

func main() {
round := 10
var wg sync.WaitGroup
barrier := syncx.NewSingleFlight()
wg.Add(round)
for i := 0; i < round; i++ {
go func() {
defer wg.Done()
// 啟用10個協程模擬獲取緩存操作
val, err := barrier.Do("get_rand_int", func() (interface{}, error) {
time.Sleep(time.Second)
return rand.Int(), nil
})
if err != nil {
fmt.Println(err)
} else {
fmt.Println(val)
}
}()
}
wg.Wait()
}

以上代碼,模擬 10 個協程請求 Redis 獲取一個 key 的內容,代碼很簡單,就是執行 Do() 方法。其中,接收兩個參數,第一個參數是獲取資源的標識,可以是 redis 中緩存的 key,第二個參數就是一個匿名函數,封裝好要做的業務邏輯。最終獲得的結果如下:

從上看出,10個協程都獲得了同一個結果,也就是只有一個協程真正執行了 rand.Int() 獲取了隨機數,其他的協程都共享了這個結果。

源碼解析

先看代碼結構:

type (
// 定義接口,有2個方法 Do 和 DoEx,其實邏輯是一樣的,DoEx 多了一個標識,主要看Do的邏輯就夠了
SingleFlight interface {
Do(key string, fn func() (interface{}, error)) (interface{}, error)
DoEx(key string, fn func() (interface{}, error)) (interface{}, bool, error)
}
// 定義 call 的結構
call struct {
wg sync.WaitGroup // 用于實現通過1個 call,其他 call 阻塞
val interface{} // 表示 call 操作的返回結果
err error // 表示 call 操作發生的錯誤
}
// 總控結構,實現 SingleFlight 接口
flightGroup struct {
calls map[string]*call // 不同的 call 對應不同的 key
lock sync.Mutex // 利用鎖控制請求
}
)

然后看最核心的 Do方法 做了什么事情:

func (g *flightGroup) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
c, done := g.createCall(key)
if done {
return c.val, c.err
}

g.makeCall(c, key, fn)
return c.val, c.err
}

代碼很簡潔,利用 g.createCall(key) 對 key 發起 call 請求(其實就是做一件事情),如果此時已經有其他協程已經在發起 call 請求就阻塞住(done 為 true 的情況),等待拿到結果后直接返回。如果 done 是 false,說明當前協程是第一個發起 call 的協程,那么就執行 g.makeCall(c, key, fn) 真正地發起 call 請求(此后的其他協程就阻塞在了 g.createCall(key) )。

從上圖可知,其實關鍵就兩步:

  1. 判斷是第一個請求的協程(利用map)
  2. 阻塞住其他所有協程(利用 sync.WaitGroup)

來看下 g.createCall(key) 如何實現的:

func (g *flightGroup) createCall(key string) (c *call, done bool) {
g.lock.Lock()
if c, ok := g.calls[key]; ok {
g.lock.Unlock()
c.wg.Wait()
return c, true
}

c = new(call)
c.wg.Add(1)
g.calls[key] = c
g.lock.Unlock()

return c, false
}

先看第一步:判斷是第一個請求的協程(利用map)

g.lock.Lock()
if c, ok := g.calls[key]; ok {
g.lock.Unlock()
c.wg.Wait()
return c, true
}

此處判斷 map 中的 key 是否存在,如果已經存在,說明已經有其他協程在請求了,當前這個協程只需要等待,等待是利用了 sync.WaitGroup  Wait() 方法實現的,此處還是很巧妙的。 要注意的是,map 在 Go 中是非并發安全的,所以需要加鎖。

再看第二步:阻塞住其他所有協程(利用 sync.WaitGroup)

c = new(call)
c.wg.Add(1)
g.calls[key] = c

因為是第一個發起 call 的協程,所以需要 new 這個 call,然后將 wg.Add(1) ,這樣就對應了上面的 wg.Wait() ,阻塞剩下的協程。隨后將 new 的 call 放入 map 中,注意此時只是完成了初始化,并沒有真正去執行call請求,真正的處理邏輯在 g.makeCall(c, key, fn) 中。

func (g *flightGroup) makeCall(c *call, key string, fn func() (interface{}, error)) {
defer func() {
g.lock.Lock()
delete(g.calls, key)
g.lock.Unlock()
c.wg.Done()
}()

c.val, c.err = fn()
}

這個方法中做的事情很簡單,就是執行了傳遞的匿名函數 fn() (也就是真正call請求要做的事情)。最后處理收尾的事情(通過defer),也是分成兩步:

  1. 刪除 map 中的 key,使得下次發起請求可以獲取新的值。
  2. 調用 wg.Done() ,讓之前阻塞的協程全部獲得結果并返回。

至此, SingleFlight 的核心代碼就解析完畢了,雖然代碼不長,但是這個思想還是很棒的,可以在實際工作中借鑒。

總結

  • map 非并發安全,記得加鎖。
  • 巧用 sync.WaitGroup 去完成 需要阻塞控制協程 的應用場景。
  • 通過匿名函數 fn 去封裝傳遞具體業務邏輯,在調用 fn 的上層函數中去完成統一的邏輯處理。

項目地址

https://github.com/zeromicro/go-zero

責任編輯:張燕妮 來源: 微服務實踐
相關推薦

2021-03-24 06:06:13

Go并發編程Singlefligh

2022-10-17 08:07:13

Go 語言并發編程

2023-09-12 11:10:00

代碼優化Go

2017-11-10 11:27:48

Go并行算法

2025-03-24 00:25:00

Go語言并發編程

2024-07-08 00:01:00

GPM模型調度器

2023-11-27 18:07:05

Go并發編程

2025-06-17 09:32:15

2023-02-10 09:40:36

Go語言并發

2023-12-29 08:10:41

Go并發開發

2013-05-28 09:43:38

GoGo語言并發模式

2023-10-28 15:37:39

Go編程語言

2023-01-30 15:41:10

Channel控制并發

2024-09-06 10:48:13

2024-01-29 00:35:00

Go并發開發

2021-12-30 18:34:29

緩存GoSinglefligh

2021-11-28 22:33:01

Go選項模式

2020-01-14 11:17:33

Go并發Linux

2014-04-25 10:13:00

Go語言并發模式

2024-10-15 10:00:06

點贊
收藏

51CTO技術棧公眾號

一级淫片免费看| 波多野结衣 在线| 中文字幕中文字幕在线十八区| 国产一区二区不卡在线| 色综合久久88色综合天天看泰| 在线观看网站黄| 在线免费三级电影网站| 日本一二三四高清不卡| 97视频资源在线观看| 五月婷婷开心网| 国产精品99一区二区三| 亚洲国产成人91精品| 亚洲一区二区蜜桃| 岛国片av在线| 国产精品久久福利| 蜜桃av噜噜一区二区三| 国产女人18毛片水真多| 国产伦理一区| 欧美放荡办公室videos4k| 天天躁夜夜躁狠狠是什么心态 | 国产精品中文在线| 久久久久久久福利| 日韩大片在线播放| 亚洲精品国产精品久久清纯直播 | 国产成人亚洲精品狼色在线| 日韩av免费在线观看| 欧美色图亚洲天堂| 日韩精品免费| 亚洲精选中文字幕| www.美色吧.com| av在线国产精品| 欧美偷拍一区二区| 激情六月丁香婷婷| 大桥未久在线视频| 亚洲精品国产a| 一本一道久久久a久久久精品91| 婷婷开心激情网| 国产精品一区专区| 国产日韩欧美成人| 中文字幕视频一区二区| 亚洲欧美网站| 韩国三级电影久久久久久| 精品人妻伦九区久久aaa片| 不卡一区综合视频| 一本色道久久综合狠狠躁篇怎么玩 | 9999热视频在线观看| 亚洲欧美日韩成人高清在线一区| 亚洲欧洲日韩综合二区| 成人在线二区| 国产精品天美传媒| 日韩影院一区| 97视频在线观看网站| 国产亚洲人成网站| 欧美视频1区| 你懂的在线免费观看| 91日韩在线专区| 韩日午夜在线资源一区二区| 手机在线观看毛片| av网站一区二区三区| 国产精品视频福利| 日本波多野结衣在线| 成人黄色在线看| 国产亚洲一区二区三区在线播放| 成人久久精品人妻一区二区三区| 国产很黄免费观看久久| 国产精品对白刺激久久久| 亚洲毛片欧洲毛片国产一品色| 成人综合婷婷国产精品久久免费| 国产精品一 二 三| 日韩av免费观影| 国产精品网站在线播放| 一区二区精品在线观看| dj大片免费在线观看| 一区二区三区加勒比av| 久久在线中文字幕| 伊人色综合一区二区三区影院视频| 色综合久久天天综合网| 99热这里只有精品在线播放| 亚洲毛片在线免费| 欧美精品一区二| 久久精品成人av| 久久中文字幕av| 久久99精品久久久久久琪琪| 欧美videossex极品| 秋霞午夜鲁丝一区二区老狼| 亚洲一区二区三区在线视频 | 精品一区二区三区四区| 国产破处视频在线观看| 中文字幕免费一区二区| 韩国三级日本三级少妇99| 91黑人精品一区二区三区| 精品一区中文字幕| 精品1区2区| 999国产在线视频| 亚洲一区二区精品视频| 无人在线观看的免费高清视频 | 欧美日韩国产高清一区二区三区 | 内射国产内射夫妻免费频道| 日韩漫画puputoon| 日韩欧美中文一区二区| 全黄一级裸体片| 一区二区电影| 国产精品1区2区在线观看 | 国产综合久久久久久鬼色| 国产美女精品在线观看| eeuss影院www在线播放| 亚洲国产日韩一级| 天天综合网日韩| 欧美一级二级三级视频| 久久精品中文字幕一区| 日韩人妻精品中文字幕| 国产白丝网站精品污在线入口| 色噜噜狠狠色综合网| 超碰在线最新网址| 欧美精品久久久久久久多人混战 | 欧美电影免费网站| 久久精品国产69国产精品亚洲| 亚洲天堂av片| 国产sm精品调教视频网站| 一区二区三区视频在线播放| 亚洲精品mv| 精品国产欧美一区二区| 中文字幕求饶的少妇| 久久久久网站| 激情小说网站亚洲综合网 | 日本成人精品在线| 免费观看毛片网站| 亚洲精品视频一区| 特黄视频免费观看| 欧美一区2区| 国产91色在线|| 日韩在线视频免费| 亚洲一区二区在线免费看| 91精产国品一二三产区别沈先生| 欧美一二区在线观看| 奇米成人av国产一区二区三区| 狠狠躁夜夜躁av无码中文幕| 亚洲一区影音先锋| 无码人妻久久一区二区三区蜜桃| 国产精品99一区二区三区| 国产精品人人做人人爽| 岛国最新视频免费在线观看| 色呦呦日韩精品| 黄瓜视频污在线观看| 99精品视频免费| 国产一级精品aaaaa看| www.超碰在线| 日韩一区二区三区视频在线| 免费在线观看h片| 国内精品视频一区二区三区八戒| 亚洲日本精品国产第一区| 日本成人三级电影| 一本色道久久综合亚洲精品小说 | 欧美日韩高清一区二区不卡| 国产精品久久久视频| 蜜臀av国产精品久久久久| 亚洲福利av| 日韩国产大片| 久久成人在线视频| www夜片内射视频日韩精品成人| 亚洲品质自拍视频| 少妇熟女视频一区二区三区 | av中文在线观看| 亚洲在线中文字幕| 国产熟女高潮一区二区三区| 久久精品人人做人人爽电影蜜月| 热re99久久精品国产99热| 日韩精品影院| 久久影院资源网| 成人毛片在线精品国产| 欧美日韩国产限制| 精品亚洲aⅴ无码一区二区三区| 精品一区二区三区在线观看| 国产欧美精品aaaaaa片| 久久99国产精品久久99大师| 人人澡人人澡人人看欧美| 91高清在线| 67194成人在线观看| 久久精品国产亚洲av高清色欲| 94色蜜桃网一区二区三区| 三级在线免费看| 最新国产精品| 麻豆91蜜桃| 日韩一级特黄| 97久久精品在线| av在线播放网站| 日韩欧美的一区| 国产又大又粗又爽| 亚洲欧美视频在线观看视频| 伊人网综合视频| 毛片不卡一区二区| aa视频在线播放| 欧美日韩在线播放视频| 91手机在线视频| 亚洲国产尤物| 国内精品在线一区| 日本激情在线观看| 国产视频精品免费播放| 国产乱淫a∨片免费观看| 五月婷婷激情综合| 日本成人免费在线观看| 成人精品鲁一区一区二区| 2025韩国理伦片在线观看| 99香蕉国产精品偷在线观看| 亚洲视频小说| 精品在线手机视频| 国产精品美女黄网| sis001欧美| 欧美富婆性猛交| 婷婷免费在线视频| 亚洲欧美国产另类| 国内爆初菊对白视频| 欧美精品在欧美一区二区少妇| 国产成人在线播放视频| 亚洲乱码国产乱码精品精98午夜| 亚洲v国产v欧美v久久久久久| 成人黄色综合网站| 18禁一区二区三区| 久久99国产精品久久| 日韩中文字幕二区| 99热精品在线观看| 999久久欧美人妻一区二区| 天天影视欧美综合在线观看| 日韩欧美三级电影| 久久不见久久见中文字幕免费| 国产视频一区二区不卡| 亚洲天堂中文字幕在线观看| 成人福利视频在线观看| 日本美女久久| 国产精品第100页| 竹内纱里奈兽皇系列在线观看 | 韩国女主播一区二区| 91国产视频在线播放| 蜜臀av在线| 欧美激情xxxx性bbbb| 国产激情小视频在线| 久久精品这里热有精品| 黄色av电影在线播放| 精品国产一区二区在线| 中文日本在线观看| 在线观看日韩av| 在线免费黄色| 色视频www在线播放国产成人| 91精品国产91久久久久游泳池 | 国模一区二区三区私拍视频| 爱高潮www亚洲精品| 国产伦精品一区二区三区高清版 | 日韩欧美国产精品| 99在线无码精品入口| 日韩欧美不卡在线观看视频| wwwxxxx国产| 亚洲电影在线看| 午夜国产在线视频| 亚洲女人天堂色在线7777| 蜜桃视频在线入口www| 亚洲人成在线观看| 伊人在线视频| 欧美xxxx18性欧美| 女人天堂av在线播放| 午夜精品久久久久久久99热| 国产无遮挡裸体视频在线观看| 2019中文在线观看| 欧美日韩激情电影| 国产一区在线播放| 亚洲一二三区视频| 极品校花啪啪激情久久| 国产精品羞羞答答在线观看| 天堂资源在线亚洲资源| 亚洲美女视频| 免费看日本毛片| 日韩精品国产欧美| 久久久精品视频国产| 99视频精品在线| 在线观看国产精品一区| 亚洲日本一区二区| 日本午夜小视频| 色94色欧美sute亚洲线路一久| 伊人免费在线观看| 精品福利在线导航| 国产永久免费高清在线观看视频| 日韩中文字幕网站| 国产高清视频色在线www| 国产精品盗摄久久久| 伊人久久大香线蕉av超碰| 久久综合久久综合这里只有精品| 日韩夫妻性生活xx| 亚洲熟妇无码av在线播放| 久久五月激情| 永久免费黄色片| 久久免费电影网| 欧美福利在线视频| 午夜欧美一区二区三区在线播放| 日韩精品成人免费观看视频| 7777精品伊人久久久大香线蕉的| 午夜成人免费影院| 久久国产精品久久国产精品| 忘忧草在线影院两性视频| 91麻豆国产语对白在线观看| 欧美综合自拍| 老司机午夜网站| 日韩av不卡一区二区| 国产艳妇疯狂做爰视频| 国产精品萝li| 五月婷婷亚洲综合| 日韩三级免费观看| 在线日本中文字幕| 日本亚洲欧美成人| 国产精东传媒成人av电影| 亚洲图片在线观看| 久久综合九色| 亚洲视频在线播放免费| 一区二区三区中文字幕| 这里只有久久精品视频| 精品爽片免费看久久| 午夜成年人在线免费视频| 国产精品入口夜色视频大尺度| 猫咪成人在线观看| 今天免费高清在线观看国语| 麻豆免费看一区二区三区| 丰满少妇一区二区三区| 一区二区三区欧美视频| 国产精品美女一区| 一本色道久久综合狠狠躁篇的优点 | 99久久99久久久精品棕色圆| 亚洲午夜久久久久久久| 中文字幕在线视频网站| 久久草.com| 在线观看视频日韩| 9.1在线观看免费| 亚洲欧美国产三级| 国产美女www爽爽爽视频| 日韩在线精品一区| 精品176极品一区| 色一情一乱一伦一区二区三区丨| 巨乳诱惑日韩免费av| 亚洲成人av免费在线观看| 亚洲国产精品久久久男人的天堂| www男人的天堂| 色综合久久久888| 日韩免费成人| 国产精品日韩三级| 国产盗摄视频一区二区三区| www青青草原| 日韩欧美视频一区| 日韩激情av| 99九九视频| 亚洲午夜一区| 懂色av粉嫩av蜜乳av| 丁香五六月婷婷久久激情| 四虎影视在线播放| 日韩av电影国产| 精品久久久久久久| 污片在线免费看| 亚洲欧洲美洲综合色网| 国产乱码精品一区二区| 欧美高清自拍一区| 露出调教综合另类| 欧美 日本 亚洲| 欧美国产日韩一二三区| 亚洲一区 中文字幕| 欧美成人全部免费| 国产精品白浆| 波多野结衣家庭教师视频| 国产欧美一区二区精品久导航| 成人黄色免费网| 欧美人成在线视频| 欧美人妖在线观看| 激情五月婷婷久久| 中文字幕一区二区三区不卡| www.精品久久| 91a在线视频| 欧美一区三区| 久久久久亚洲av片无码v| 亚洲不卡在线观看| 粉嫩av在线播放| 亚洲xxxx在线| 中文精品在线| 久久久久99精品成人| 日韩美女在线视频| 欧美日韩免费看片| 免费观看国产视频在线| 99热精品国产| 在线视频 中文字幕| 欧美国产日韩一区二区| 伊人久久大香线蕉| 99国产精品免费视频| 日韩欧美中文免费| 精品麻豆一区二区三区| 精品亚洲欧美日韩| 老司机免费视频一区二区| 久久亚洲AV无码| 在线观看视频99| 久久视频在线观看| 老司机久久精品| 狠狠躁18三区二区一区| 麻豆影视在线观看_| 久久人人九九| 国产白丝网站精品污在线入口| 国产主播第一页| 亚州精品天堂中文字幕|