通過SOFAMosn瞭解goroutine只能在一定併發量級上降低併發編程的難度(goroutine內存佔用2kb+)。 高併發的場景還是NIO比較適合。
jiankunking
GoLang 的轉發性能比起 C++ 肯定是稍有遜色的,爲了儘可能的提高 MOSN 的轉發性能,我們在線程模型上進行優化,當前 MOSN 支持兩種線程模型,用戶可根據場景選擇開啓適用的模型。
模型一
如下圖所示,使用 GoLang 默認的 epoll 機制,對每個連接分配獨立的讀寫協程進行阻塞讀寫操作,proxy 層做轉發時,使用常駐 worker 協程池負責處理 Stream Event
此模型在 IO 上使用 GoLang 的調度機制,適用於連接數較少的場景,例如:mosn 作爲 sidecar、與 client 同機部署的場景
模型二
如下圖所示,基於 Netpoll 重寫 epoll 機制,將 IO 和 PROXY 均進行池化,downstream connection 將自身的讀寫事件註冊到 netpoll 的 epoll/kqueue wait 協程,epoll/kqueue wait 協程接受到可讀事件,觸發回調,從協程池中挑選一個執行讀操作。
使用自定義 Netpoll IO 池化操作帶來的好處是:
當可讀事件觸發時,從協程池中獲取一個 goroutine 來執行讀處理,而不是新分配一個 goroutine,以此來控制高併發下的協程數量
當收到鏈接可讀事件時,才真正爲其分配 read buffer 以及相應的執行協程。這樣 GetBytes() 可以降低因爲大量空閒鏈接場景導致的額外協程和 read buffer 開銷
此模型適用於連接數較多、可讀連接數量受限的情況,例如:mosn 作爲 api gateway 的場景