精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

成人免费a**址| 韩日精品一区二区| 成人午夜免费av| 57pao精品| 黄色av免费播放| 日韩精品成人| 日韩欧美福利视频| 一区二区三区我不卡| 亚洲精品久久久久久无码色欲四季| 亚洲精品精选| 色悠悠久久88| 中文字幕一区二区久久人妻网站| 国产精品99| 亚洲国产精品久久艾草纯爱 | 精品免费久久久久久久| 五月激情六月婷婷| 国产一区二区伦理| 国产国产精品人在线视| 麻豆视频在线观看| 色爱综合网欧美| 亚洲精品理论电影| 久久精品亚洲天堂| 国精产品一区一区三区四川| 亚洲综合视频网| 亚洲午夜精品久久久久久浪潮| 亚洲成人一二三区| 久久99热狠狠色一区二区| 91地址最新发布| 欧美精品色哟哟| 热久久天天拍国产| 亚洲美女精品成人在线视频| 稀缺呦国内精品呦| 日本99精品| 欧美久久婷婷综合色| 欧美午夜性色大片在线观看| 92看片淫黄大片欧美看国产片 | 亚洲麻豆精品| 99久久综合狠狠综合久久| 成人一区二区电影| 中文字幕 人妻熟女| 国产手机视频一区二区| 欧美俄罗斯性视频| 中文字幕av播放| 欧美激情成人| 在线色欧美三级视频| 国产白袜脚足j棉袜在线观看| 巨大黑人极品videos精品| 欧美性xxxxx| 亚洲熟妇国产熟妇肥婆| 欧洲精品二区| 亚洲国产综合在线| 国产av熟女一区二区三区| h片在线免费| 亚洲人成影院在线观看| 综合色婷婷一区二区亚洲欧美国产| 国产在线自天天| 久久久久久久久久电影| 免费在线国产精品| 日韩三级电影网| 久久久综合网站| 欧美高清视频一区| www.久久热.com| 国产精品毛片大码女人| 一区二区三区四区国产| 麻豆网站在线看| 日韩美女啊v在线免费观看| 在线视频91| a免费在线观看| 亚洲最新在线观看| 3d动漫一区二区三区| 中文在线免费视频| 欧美性videosxxxxx| 国产日韩欧美久久| 精品国产亚洲一区二区三区在线| 日韩一级片在线观看| 丰满少妇xbxb毛片日本| 午夜欧洲一区| 中文字幕亚洲精品| caoporn91| 99日韩精品| 国产精品久久二区| 国产精品亚洲lv粉色| 国产成人精品在线看| 精品国产乱码久久久久久丨区2区 精品国产乱码久久久久久蜜柚 | 夜夜嗨av一区二区三区网页| 国产精品裸体瑜伽视频| 日韩av大片站长工具| 欧美丰满少妇xxxbbb| 欧美做受高潮中文字幕| 国模精品一区| 美乳少妇欧美精品| 成人精品免费在线观看| 六月婷婷色综合| 国产福利久久| 成人福利在线| 亚洲一区二区成人在线观看| 久久久久久久久久久久久国产精品 | 大香伊人久久精品一区二区| 亚洲免费人成在线视频观看| 日日操免费视频| 激情综合久久| 国产精品高潮呻吟久久av野狼| 国产乱码久久久久| 91影院在线免费观看| 亚洲午夜精品一区二区三区| 99thz桃花论族在线播放| 欧美色男人天堂| 亚洲の无码国产の无码步美| 久久视频国产| 欧美在线不卡区| 亚洲春色一区二区三区| 欧美韩国日本不卡| 日韩a∨精品日韩在线观看| 91成人短视频在线观看| 亚洲美女在线视频| 精品少妇久久久| 老司机午夜精品99久久| 久久综合一区二区三区| 男插女视频久久久| 欧美挠脚心视频网站| 日韩中文字幕电影| 欧美日韩国产精品一区二区亚洲| 国产精品电影网站| 五月天婷婷视频| 一区二区三区影院| 亚洲一二区在线观看| 成人免费a**址| 国产成人小视频在线观看| 婷婷av一区二区三区| 亚洲综合丝袜美腿| 国产chinesehd精品露脸| 99久久夜色精品国产亚洲96| 国产成人精品视频| 色就是色亚洲色图| 午夜精品久久久久久久久| 日本中文字幕精品| 欧美hd在线| 国产精品免费一区豆花| 成人午夜影视| 在线观看91精品国产入口| 国产传媒第一页| 日韩视频免费| 国产一区免费视频| 草草在线视频| 日韩成人在线视频| 麻豆久久久久久久久久| 91在线视频免费观看| 日本xxxxxxxxxx75| 国产精品毛片视频| 97在线观看视频| 性插视频在线观看| 大荫蒂欧美视频另类xxxx| 粉嫩av懂色av蜜臀av分享| 99热免费精品| 欧美另类高清视频在线| 国偷自产一区二区免费视频| 亚洲欧美资源在线| 日本成人一级片| 中文字幕在线视频一区| 天天操天天干天天做| 久久精品青草| www.成人三级视频| 丁香花在线影院| 日韩av影视在线| 中文字幕精品无码一区二区| 久久久91精品国产一区二区三区| 午夜精品久久久内射近拍高清| 亚洲精品蜜桃乱晃| 国产大片精品免费永久看nba| 黄色av网址在线免费观看| 欧美日韩国产123区| 国模无码国产精品视频| 成人动漫中文字幕| 日韩精品无码一区二区三区免费| 91欧美在线| 97在线中文字幕| 毛片在线网站| 中文字幕亚洲欧美日韩在线不卡 | 狠狠操一区二区三区| 亚洲人成在线观看| 91久久精品国产91性色69| 亚洲免费三区一区二区| 日韩精品一区二区三区高清免费| 日精品一区二区| 亚洲区成人777777精品| 香蕉久久精品| 成人午夜黄色影院| 成年男女免费视频网站不卡| 最近2019年好看中文字幕视频 | 狠狠色丁香九九婷婷综合五月| 日韩亚洲欧美一区二区| 综合亚洲色图| 亚洲999一在线观看www| 中文不卡1区2区3区| 久久国产精品电影| 日韩午夜影院| 日韩视频免费观看高清在线视频| 国产无遮挡呻吟娇喘视频| 中文字幕一区二区三中文字幕| 老司机午夜免费福利| 美女www一区二区| 国产精品无码人妻一区二区在线| 日韩电影在线视频| 国内精品一区二区| 999精品视频在线观看| 96精品视频在线| 成人video亚洲精品| 亚洲精品乱码久久久久久金桔影视 | 蜜臀av性久久久久av蜜臀妖精| 久久人人爽人人爽人人av| 日韩精品久久| 免费看国产精品一二区视频| 高清不卡一区| 国产精品丝袜视频| 亚洲色图官网| 97精品国产91久久久久久| 成人三级网址| 中文字幕日韩精品有码视频| 五月婷婷久久久| 欧美成人精品高清在线播放| 91成年人视频| 欧美调教femdomvk| 秋霞av一区二区三区| 亚洲h在线观看| 久久国产在线观看| 亚洲欧美激情一区二区| 国产调教在线观看| 久久香蕉国产线看观看99| 在线中文字日产幕| 国产电影一区在线| 日韩av片免费观看| 另类综合日韩欧美亚洲| 欧美日韩在线免费播放| 亚洲综合社区| 日本免费不卡一区二区| 一区在线视频| 久久男人资源站| 欧美日韩三级| 激情六月天婷婷| 最新欧美人z0oozo0| 中文字幕不卡每日更新1区2区| 国产一区日韩| 视频一区视频二区视频| 国产一区二区在线| 日韩欧美99| 日韩精品一区二区三区免费观影 | 亚洲电影影音先锋| 中文字幕精品一区日韩| 久久精品国产亚洲夜色av网站| 日韩高清三级| 国产精品88久久久久久| 伊人婷婷久久| 欧美精品激情| 野外做受又硬又粗又大视频√| 正在播放日韩欧美一页| 欧美精品在欧美一区二区| 欧美一区成人| 黄色片网址在线观看| 久久精品系列| 亚洲77777| 国产专区综合网| 国产精品19p| www.成人网.com| 精品少妇人妻一区二区黑料社区| 久久久噜噜噜久噜久久综合| 欧美三级视频网站| 亚洲欧美日韩小说| 久久精品免费在线| 欧美日韩精品中文字幕| www.日韩一区| 欧美久久久久久久久久| 精品人妻无码一区二区色欲产成人 | 亚洲欧美另类动漫| 久国产精品韩国三级视频| 污视频在线观看免费网站| 成人三级伦理片| av网在线播放| 亚洲精品老司机| 欧美一区二区激情视频| 欧美日韩高清一区二区| 午夜免费福利视频| 亚洲人精品午夜在线观看| 美女免费久久| 91黄色8090| 国产一区影院| 国产精品免费在线| 欧美在线观看视频一区| 中文字幕の友人北条麻妃| 亚洲免费在线| 精品人妻一区二区三| 91麻豆免费在线观看| 美国黄色片视频| 欧美性xxxxhd| 国产www免费观看| 亚洲欧美成人网| 午夜dj在线观看高清视频完整版| 国产91对白在线播放| 成人污版视频| 日本不卡一区二区三区视频| 欧美日韩国产欧| 亚州精品一二三区| av一区二区三区黑人| 午夜国产福利视频| 欧美性猛交xxxx偷拍洗澡 | 日韩精品在线视频| av在线免费观看网址| 国产精品88a∨| 国产成人福利av| 自拍偷拍亚洲色图欧美| 久久久久久9| 精品熟女一区二区三区| 亚洲三级久久久| 性色av一区二区三区四区| 亚洲国产精品高清久久久| 久草资源在线观看| 国产成人精品一区二区三区| youjizzjizz亚洲| 91手机视频在线| 免费在线观看成人| 中文字幕国产专区| 亚洲成a人v欧美综合天堂下载| 国产又粗又黄又爽的视频| 亚洲美女在线看| 欧亚在线中文字幕免费| 国产a一区二区| 91精品国产麻豆国产在线观看| 免费大片在线观看| 99这里只有精品| 国产在线观看免费视频今夜| 在线91免费看| 又爽又大又黄a级毛片在线视频| 奇门遁甲1982国语版免费观看高清| 中文字幕视频精品一区二区三区| 椎名由奈jux491在线播放| 久久电影网电视剧免费观看| www亚洲色图| 欧美亚日韩国产aⅴ精品中极品| 人成在线免费视频| 欧美性视频网站| 日韩欧美四区| 成人在线免费观看av| 99精品桃花视频在线观看| 日本少妇在线观看| 亚洲第一av网站| av男人的天堂在线观看| 国产一区在线观| 亚洲免费观看| 日韩精品卡通动漫网站| 色婷婷精品久久二区二区蜜臀av | 欧美第一黄网免费网站| 视频一区视频二区欧美| 国产精品视频一二三四区| 国产自产2019最新不卡| 欧美精品乱码视频一二专区| 欧美xxxxxxxxx| 超碰在线99| 欧美一区少妇| 美女视频免费一区| 精品无码久久久久成人漫画 | 青青色在线视频| 欧美在线视频观看免费网站| 九色精品国产蝌蚪| 亚洲最大成人在线观看| 亚洲丝袜另类动漫二区| 亚洲精品久久久久avwww潮水| 国内精品一区二区三区| 夜夜春成人影院| 911福利视频| 亚洲午夜久久久久中文字幕久| 熟妇人妻av无码一区二区三区| 日本亚洲欧美三级| 天天射天天综合网| 97人妻精品一区二区三区免费| 日韩欧美一区视频| 尤物视频在线免费观看| 成人免费视频网站入口| 久久电影一区| www日韩在线| 亚洲国产日韩欧美综合久久 | 96pao国产成视频永久免费| 亚洲一本视频| 国产黄色大片免费看| 日韩一区二区免费视频| 在线看片福利| 一本—道久久a久久精品蜜桃| 成人午夜伦理影院| 亚洲欧美日韩一区二区三区四区| 久久久97精品| 欧美亚洲大陆| 亚洲无在线观看| 欧美日韩在线免费| 黄色免费在线观看网站| 精品欧美日韩| 国产一区二区三区黄视频| 91精品国产乱码久久久张津瑜| 中文字幕精品久久久久| 红杏一区二区三区| 人人爽人人爽av| 日本韩国欧美一区| 爱看av在线|