最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

goroutine?泄漏和避免泄漏實戰(zhàn)示例

 更新時間:2022年12月22日 15:00:12   作者:山與路  
這篇文章主要為大家介紹了goroutine?泄漏和避免泄漏實戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

goroutine 泄漏和避免泄漏的最佳實踐

Go的奇妙之處在于,我們可以使用goroutines和channel輕松地執(zhí)行并發(fā)任務(wù)。如果在生產(chǎn)環(huán)境中使用goroutines和channel,但是不了解它們的行為方式,會造成一些嚴(yán)重的影響。

好吧,我們就面臨著這樣的影響,我們在goroutines中出現(xiàn)了泄漏,導(dǎo)致應(yīng)用服務(wù)器隨著時間的推移而膨脹,消耗了大量的CPU和頻繁的GC,影響了多個服務(wù)的SLA。

從本文中可以看到什么

理解什么是goroutine泄露。 理解goroutine泄漏的多種方式。 詳細(xì)了解造成goroutine泄露的一個真實場景。 我們是如何找到goroutine泄漏原因? 阻止goroutine泄漏的最佳實踐是什么?

正如你在上面所附的指標(biāo)中所看到的,goroutines開始隨著時間的推移成倍地飆升。唯一的一次下降是當(dāng)我們的一個正在運行的實例被AWS調(diào)度走,新的實例被啟動,或者有一個新的版本,殺死了現(xiàn)有的容器并產(chǎn)生了新的容器。

如果你觀察GC暫停的時間,它會隨著活動的goroutine的數(shù)量不斷增加。GC暫停的次數(shù)越多,CPU利用率就越高,響應(yīng)時間也越來越長。

什么是goroutine泄漏?

goroutine泄漏是指客戶端生成一個goroutine來做一些異步任務(wù),并在任務(wù)完成后將一些數(shù)據(jù)寫入一個channel,但是

沒有監(jiān)聽程序消耗該channel的數(shù)據(jù)寫入。

在上述情況下,代碼成功地完成了執(zhí)行,好像根本就沒有問題。但這里發(fā)生的情況是,會有一個沒有被管理的goroutine駐留在內(nèi)存中,占用CPU和RAM。

原因分析

主要原因是第3行,我們正在向一個通道寫入數(shù)據(jù),但根據(jù)Go原則,一個未緩沖的通道會阻止向通道的寫入,直到消費者從該channel取走信息。

所以在這種情況下,第4行的返回將永遠(yuǎn)不會被執(zhí)行,并且newgoroutine函數(shù)在整個應(yīng)用程序生命周期中都被卡住,因為這個channel沒有消費者。

在goroutine啟動和channel監(jiān)聽器之間有一些條件邏輯。

在這個案例中,有一個小小的改進(jìn)。我們有一個消費者從dataChan中消費數(shù)據(jù),但是從我們生成goroutine開始,到我們開始從通道中消費數(shù)據(jù)之前,有大量的應(yīng)用程序代碼駐留在那里,這些代碼可以在一些處理錯誤|DB錯誤|無指針異常|panic的情況下退出主函數(shù),由于這些原因,channel的數(shù)據(jù)可能從未被執(zhí)行。

這就是一個goroutine看似正常,實際可能導(dǎo)致泄漏的情況。

我們不能在應(yīng)用處理之前將channel中的值提前消費,因為消費者會阻止剩下業(yè)務(wù)邏輯的處理,直到它收到數(shù)據(jù),從而消除了并發(fā)任務(wù)的執(zhí)行。

發(fā)送完成立刻返回 以上兩種情況是當(dāng)goroutine因為沒有channle的消費者而被阻塞,或者消費者從channel中消費數(shù)據(jù)的代碼塊被跳過。

當(dāng)我們把一個channel傳遞給goroutine去消費時,當(dāng)發(fā)送者向通道發(fā)送數(shù)據(jù)時出現(xiàn)了問題,這是否也是同樣的情況?

好吧,95%的goroutine泄露都是因為這3種情況中的一種,在我們的案例中,是由于情景-2。我們在GoIbibo-Makemytrip的工作是折扣和便利費服務(wù)。

當(dāng)客戶應(yīng)用一個促銷代碼時,我們有一套規(guī)則要執(zhí)行,以找出正確的折扣。我們有另一個微服務(wù),我們稱之為實時動態(tài)折扣器(DD),它試圖根據(jù)一些算法(黑盒子)來計算折扣。

這個動態(tài)折扣是一個A/B實驗,只有10%的用戶會參與其中。只有當(dāng)我們的靜態(tài)規(guī)則中存在有效的折扣時,我們才會覆蓋DD折扣。

偽代碼

我們只有在處理完靜態(tài)規(guī)則后才需要DD的響應(yīng)。所以來自ddChan的消費將在最后進(jìn)行。

如果靜態(tài)規(guī)則的評估有問題|如果沒有滿足請求的有效規(guī)則|如果用戶應(yīng)用了一些假的促銷活動,我們從ddChan中消耗數(shù)據(jù)的代碼將無法到達(dá),這導(dǎo)致loadDDDiscount函數(shù)成為一個無法控制的goroutine。

有什么方法可以解決這個問題?

方法-1 方法 -> 從我們啟動goroutine開始,到我們從退出channel的消耗數(shù)據(jù)為止,我們識別每一個錯誤條件,并在每一個返回語句前放置一個接收者,以解除對生成的goroutine的封鎖。

陷阱 -> 我們必須手動找到所有的邊緣情況,并且在將來,如果我們必須處理更多的錯誤情況,我們需要記住在返回之前我們需要消耗哪些channel的數(shù)據(jù)。

方法-2 方法 -> 與其在每個錯誤的情況下放置一個接收者,為什么不設(shè)置一個可以從channel中接收數(shù)據(jù)的延遲函數(shù)。

陷阱 -- 在成功的情況下,數(shù)據(jù)將在處理完靜態(tài)規(guī)則后從通道中讀取。因此,如果我們在defer函數(shù)中開始接收通道中的數(shù)據(jù),那么在成功的情況下就會阻塞主goroutine。

方法-3 沒有完美的方法。在上述所有場景中,我們創(chuàng)建了一個無緩沖的通道,阻止發(fā)送者向該通道發(fā)送數(shù)據(jù),直到接收者收到數(shù)據(jù)。這里的主要問題是我們不確定由于我們的應(yīng)用處理,接收方是否會被執(zhí)行。那么,簡單的解決方案是創(chuàng)建一個上限為1的緩沖通道。有了這個,即使沒有消費者,或者消費者代碼沒有達(dá)到,發(fā)送者也不會被阻止寫一次數(shù)據(jù)。 圖片 陷阱 -> 絕對是零。這與非緩沖通道的工作原理完全相同,但為我們提供了一個額外的能力,即發(fā)送者在發(fā)送數(shù)據(jù)時不會受到阻礙,而消費者可以在任何時候消費它,而且生成的goroutine也不會等待消費者的到來。 我們用第三種方法將變化帶入生產(chǎn)環(huán)境,你可以看到顯著的影響。

圖片 以前是線性增長的goroutine數(shù)量,現(xiàn)在下降到150個,我們的GC暫停頻率也是如此。

整個事情中最痛苦的部分是,如何找到代碼中存在goroutine泄漏的部分?

所以我的方法是這樣的。

當(dāng)服務(wù)器啟動時,使用debug.SetGCPercent(-1)禁用垃圾收集器。 現(xiàn)在運行代碼中每一個使用Go程序的流程(Dev Env)。 在每個API的入口處,打印在開始和執(zhí)行API之前和之后運行的goroutines的數(shù)量。

func ApplyPromo() {
   fmt.Println(runtime.NumGoroutine())
   defer fmt.Println(runtime.NumGoroutine()
   // Process your application logic
}

現(xiàn)在,如果一個服務(wù)在前后返回不同的Goroutines數(shù)量,那么這個邏輯就存在泄漏。

我們有近20個API和大約35-40個地方使用了goroutines以改善并發(fā)性。幸運的是,我能夠在前3次迭代中找出泄漏問題,并發(fā)現(xiàn)了這個存在泄漏的邏輯。

以上就是goroutine 泄漏和避免泄漏實戰(zhàn)示例的詳細(xì)內(nèi)容,更多關(guān)于goroutine 泄漏避免泄漏的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang配置解析神器go?viper使用詳解

    Golang配置解析神器go?viper使用詳解

    viper是一個很完善的Go項目配置解決方案,很多著名的開源項目都在使用,比如Hugo,Docker都使用了該庫,使用viper可以讓我們專注于自己的項目代碼,而不用自己寫那些配置解析代碼,本文給大家介紹Golang配置解析神器go?viper使用,感興趣的朋友一起看看吧
    2022-05-05
  • Golang性能優(yōu)化的技巧分享

    Golang性能優(yōu)化的技巧分享

    性能優(yōu)化的前提是滿足正確可靠、簡潔清晰等質(zhì)量因素,針對?Go語言特性,本文為大家整理了一些Go語言相關(guān)的性能優(yōu)化建議,感興趣的可以了解一下
    2023-07-07
  • go循環(huán)依賴的最佳解決方案

    go循環(huán)依賴的最佳解決方案

    ? import cycle not allowed(循環(huán)依賴不被允許)相信作為每一個golang語言使用研發(fā),都遇到過這個令人頭痛的報錯,循環(huán)依賴是指兩個或多個模塊之間互相依賴,形成了一個閉環(huán)的情況,本文會結(jié)合部分案例對解決方案進(jìn)行講解,需要的朋友可以參考下
    2023-10-10
  • 淺析Go中關(guān)于零值和空值判斷的問題

    淺析Go中關(guān)于零值和空值判斷的問題

    這篇文章主要是對零值和空值判斷現(xiàn)狀進(jìn)行簡單的梳理和分享,文中的示例代碼講解詳細(xì),對我們深入了解go語言有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08
  • GO語言實現(xiàn)的http抓包分析工具pproxy介紹

    GO語言實現(xiàn)的http抓包分析工具pproxy介紹

    這篇文章主要介紹了GO語言實現(xiàn)的http抓包分析工具pproxy介紹,本文同時對比了Fiddler、Charles等抓包軟件,需要的朋友可以參考下
    2015-03-03
  • Golang打印復(fù)雜結(jié)構(gòu)體兩種方法詳解

    Golang打印復(fù)雜結(jié)構(gòu)體兩種方法詳解

    在?Golang?語言開發(fā)中,我們經(jīng)常會使用結(jié)構(gòu)體類型,如果我們使用的結(jié)構(gòu)體類型的變量包含指針類型的字段,我們在記錄日志的時候,指針類型的字段的值是指針地址,將會給我們?debug?代碼造成不便
    2022-10-10
  • 使用Go語言實現(xiàn)心跳機(jī)制

    使用Go語言實現(xiàn)心跳機(jī)制

    心跳最典型的應(yīng)用場景是是探測服務(wù)是否存活,這篇文章主要來和大家介紹一下如何使用Go語言實現(xiàn)一個簡單的心跳程序,感興趣的可以了解下
    2024-01-01
  • Golang中switch語句和select語句的用法教程

    Golang中switch語句和select語句的用法教程

    這篇文章主要給大家介紹了關(guān)于Golang中switch和select的用法教程,文中通過示例代碼將switch語句與select語句的使用方法介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-06-06
  • 詳解Go語言如何實現(xiàn)一個最簡化的協(xié)程池

    詳解Go語言如何實現(xiàn)一個最簡化的協(xié)程池

    這篇文章主要為大家詳細(xì)介紹了Go語言如何實現(xiàn)一個最簡化的協(xié)程池,文中的示例代碼講解詳細(xì),具有一定的參考價值,有需要的小伙伴可以了解一下
    2023-10-10
  • golang?run時報undefined錯誤的解決

    golang?run時報undefined錯誤的解決

    這篇文章主要介紹了golang?run時報undefined錯誤的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03

最新評論

新巴尔虎左旗| 钦州市| 六盘水市| 通山县| 特克斯县| 漾濞| 安福县| 庆安县| 荔波县| 抚远县| 内江市| 萨迦县| 阿鲁科尔沁旗| 辽源市| 平邑县| 哈巴河县| 肥乡县| 河津市| 全椒县| 永泰县| 穆棱市| 藁城市| 图们市| 河南省| 历史| 岳阳县| 寻乌县| 沧源| 岑巩县| 翁源县| 双城市| 新津县| 张北县| 遂宁市| 镇宁| 奉节县| 金门县| 岚皋县| 黑河市| 柳州市| 江津市|