我很好奇是否有人分析過這兩種范式之間的性能差異。有一個偵聽器 goroutine(可能是幾個),它偵聽套接字并生成一個新的 goroutine 來處理該信息并將其發送到它必須去的任何地方。在發送命令之后,例程將完成并被銷毀。每個請求都會創建一個例程,然后在完成后銷毀它。有一個偵聽器 goroutine(可能是幾個)來偵聽套接字并將數據傳遞到通道。許多 goroutine 阻塞在一個通道接收上,并且會輪流從通道中取出東西并處理它們。完成后,例程將在通道上等待以獲取更多信息。在這種范式中,例程永遠不會被破壞。幾個主例程在通道上接收套接字信息,其他例程在通道上等待處理信息。慣例永遠不會被破壞。我的問題是對于在接收中接收大量小信息的系統(每條消息 0.5-1.5kb)但同時有大量消息傳入(大容量,小尺寸)什么范式對速度和加工。有一堆例程坐著并使用頻道將它們分散到一堆聆聽例程中?或者,為每個請求創建一個路由并在每個請求后結束該例程?即使是基本的意識形態和猜想也很酷。
1 回答

白衣非少年
TA貢獻1155條經驗 獲得超0個贊
一般來說,我傾向于發現生成無數例程而不重用它們是浪費:即使 goroutines 便宜,但它們不是免費的,并且意味著調度成本。
現在,這兩種方法在高負載下都有缺點:生成例程會消耗您的內存、調度,并可能使您的程序停止運行,而使用通道時,您的請求將掛起,直到處理前一個。
我通常的方法是做一個基于批處理的管道(靈感來自優秀的Go Concurrency Patterns: Pipelines and cancels博客文章):
偵聽器在通道中發送請求
一個聚合例程將請求放入緩沖區
N 個處理例程在空閑時請求緩沖區塊
這樣您就可以精確控制管道的流程和行為,同時保持多個工作人員的優勢。如果緩沖區超過限制大小、產生或殺死新工作人員以適應負載等,您可以通過丟棄傳入請求來輕松實現溢出機制。
- 1 回答
- 0 關注
- 232 瀏覽
添加回答
舉報
0/150
提交
取消