記一次Golang routine卡死

2022-04-28 09:49:03 字數 1171 閱讀 1751

go語言最方便的地方在於可以自由自在的起routine,並且不用自己維護佇列。

乙個很簡單的處理模型,針對於長連線活動平凡的鏈結獨立routine進行處理,方便同一連線上下文關聯,read routine a講接收到的訊息解包生成訊息丟到對應socket的routine b channel中進行處理,routine b在根據不同的任務丟到對應的routine b1或者 routine b2中進行處理,

我們需要乙個channel回寫routine b1 routine b2的退出訊號給你 b 以便b進行響應處理。

那麼這麼想的話 b 和b1 b2 需要兩個channel進行訊息通訊

偽**如下,未做友好處理。

var

b1 b1consumer

varb2 b2consumer

//statch 回寫子routine的狀態

statch := make(chan statmsg,1

)b1ch := make(chan msg,100

)b2ch := make(chan msg,100

)go b1(b1ch,statch)

go b2(b2ch,statch)

forelse

case statmsg := <-statch:

deal_state(msg)

}}

乍一看沒什麼問題,後面再測試過程中 偶爾發現呼叫介面沒有響應超時。

仔細排查後發現,b1 routine 在退出時回寫了乙個done的statmsg,然後就退出了。

此事bch還在寫資料如果此時b1ch寫滿了,那麼寫channel就會卡死,而b1退出的訊號已經傳送了 不在處理新資料了,那麼b routine就會一直卡死在

b1ch<-cmsg

此時已經b routine 已經無法進行下一次select的操作,進而等bch channel寫滿 卡死讀取routine,等多個讀取routine卡死,客戶端表現就是無響應了 超時了。

找到問題解決辦法就簡單了。

增加寫入channel超時 並且增加statch 的大小

statch :=make(chan statmsg,maxchannelsize) 

select

加大channel大小 避免多次觸發超時,如果一旦出現超時,將超時的任務釋放掉。

記一次除錯

這是我最近幾個月來遇到的最棘手的乙個問題 昨天花了4個小時找出第一層次的原因 這個糾結啊,本來和老婆說好準時下班回家吃飯的,結果被這個問題拖了老久。這是乙個gradle的plugin,用來resolve公司內部的dependency的,弄完了跑測試專案的,拋乙個npe,而且npe還不在自己的 裡面。...

記一次 EqualsAndHashCode的疑惑

lombok的使用真的是讓開發人員欲罷不能,乙個 data不管有多少屬性全部搞定,以後加字段也不用從新生成get和set方法。不過這裡還是有乙個小坑需要注意一下,舉個例子 public class equalsandhashcodetest data noargsconstructor access...

記一次除錯

這是我最近幾個月來遇到的最棘手的乙個問題 昨天花了4個小時找出第一層次的原因 這個糾結啊,本來和老婆說好準時下班回家吃飯的,結果被這個問題拖了老久。這是乙個gradle的plugin,用來resolve公司內部的dependency的,弄完了跑測試專案的,拋乙個npe,而且npe還不在自己的 裡面。...