[英]understanding go channel handling / buffer overflow
我繼承了一些我仍在嘗試理解的代碼。 它的核心是這樣的:
for msg := range this.out {
for i, handler := range this.handlers {
select {
case handler <- msg:
default:
this.logger.Printf("Buffer overflow occurred for handler %s", this.names[i])
}
}
}
out 是一個chan byte
處理程序是[]chan []byte
看起來這是從數組中讀取並寫入處理程序,默認情況是抱怨緩沖區溢出。 我認為。
但我需要細節。 我是 go 的新手,這是我第一次與 chan 打交道。 所以第一個問題,這真的是這里發生的事情嗎? 如果是這樣...如何防止緩沖區溢出?
在 Go 中,可以通過兩種方式創建通道:
c := make(chan []byte)
它創建了一個將同步發送方和接收方的通道。 這意味着接收方必須等待發送方發送數據,發送方必須等待接收方獲取數據。 但是,通過向通道添加緩沖區:
c := make(chan []byte, 100)
您正在有效地使發送者和接收者不同步。 在這種情況下,發送方會在緩沖區滿時阻塞,而接收方會在緩沖區空時阻塞。
現在,我不知道handler
的容量是多少,但這是您應該期望的一般工作流程:
handler
中是否有空間,如果有,則將msg
寫入通道。你實際上對緩沖區溢出所做的事情有點棘手。
首先,作為權宜之計,您可以增加handler
的容量,以便它可以容納更多消息。 如果問題是間歇性的(即流量高峰),這可能代表一個實際的解決方案。 否則,您所做的只是將問題推遲一段時間。
其次,您可以水平擴展處理程序另一端的handler
以處理更多消息,從而確保通道不會溢出。 但是,這樣做的問題是,您必須擔心管理各種容量級別的處理程序,然后您才能進入自動縮放之類的事情。
第三,您可以查看處理程序中handler
消息的代碼,看看是否可以重新設計它以更有效地處理消息。 當您的代碼的原始設計假設不再成立時,這種重新設計非常普遍。
最后,您可以完全放棄使用渠道作為基礎設施,並使用基於雲的發布/訂閱(包括 memory)替換該組件。 這樣做的好處是,這將允許您根據需要擴展您的應用程序,而不必擔心溢出,但它會產生額外的成本並需要更改基礎架構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.