簡體   English   中英

了解 go 通道處理/緩沖區溢出

[英]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的容量是多少,但這是您應該期望的一般工作流程:

  1. Go 將檢查handler中是否有空間,如果有,則將msg寫入通道。
  2. 如果沒有空間,則將記錄錯誤消息。

你實際上對緩沖區溢出所做的事情有點棘手。

首先,作為權宜之計,您可以增加handler的容量,以便它可以容納更多消息。 如果問題是間歇性的(即流量高峰),這可能代表一個實際的解決方案。 否則,您所做的只是將問題推遲一段時間。

其次,您可以水平擴展處理程序另一端的handler以處理更多消息,從而確保通道不會溢出。 但是,這樣做的問題是,您必須擔心管理各種容量級別的處理程序,然后您才能進入自動縮放之類的事情。

第三,您可以查看處理程序中handler消息的代碼,看看是否可以重新設計它以更有效地處理消息。 當您的代碼的原始設計假設不再成立時,這種重新設計非常普遍。

最后,您可以完全放棄使用渠道作為基礎設施,並使用基於雲的發布/訂閱(包括 memory)替換該組件。 這樣做的好處是,這將允許您根據需要擴展您的應用程序,而不必擔心溢出,但它會產生額外的成本並需要更改基礎架構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM