SpringBoot默認200個線程對於Websocket長連接夠用嗎?(一)

上篇推文從源碼剖析SpringBoot中Tomcat的默認最大連接數中我們知道,SpringBoot的內嵌Tomcat默認的最大連接數爲200。那麼,這個默認值對於項目中引入了WebSocket使用長連接後,是否足夠用呢?今天強哥就帶大家一起從源碼的角度來分析一下。

我們還是從上一篇推文給的代碼入手(需要源碼的小夥伴可後臺回覆:WebSocket獲取)。強哥想了想,要判斷200個線程是否夠,可能並不是那麼好量化,不如我們就先配置1個線程入手看看效果如何:

server.tomcat.max-threads=1

然後啓動項目,前端試試來5個WebSocket請求是否可以成功連上:

沒問題,都連上了。爲了節省篇幅,我們直接來Chrome瀏覽器最大限制的WebSocket個數256:

同樣也是可以,那麼問題來了,爲什麼這一個線程就可以處理這麼多個WebSocket長連接請求呢?

哈哈,想必有一些基礎的小夥伴應該能想到:會不會用的是Java NIO來處理的這些請求呢?那麼,我們就從源碼(本篇涉及的SpringBoot源碼版本爲:2.2.3.BUILD-SNAPSHOT)入手先來看看這個猜想是否正確。

對於Java NIO不熟悉的同學,今天的另一篇推文強哥也搜了一篇比較優質的科普文,想了解或是複習一下的可以跳過去看看哦。

可是,源碼又要從哪裏入手呢?當然還是我們上面的那個配置啦。上篇文章中我們知道,按住ctrl然後鼠標點擊該配置便能進入對應的ServerProperties配置類中該屬性對應的set方法:

然後,找到maxThreads使用的地方:

即在customize方法中調用:

我們進到customizeMaxThreads方法中:

我們在上篇文章中也見過這個方法,重點來了,AbstractProtocol protocol這個便是我們內嵌Tomcat使用的協議。我們在上圖位置打個斷點然後重啓項目試試:

通過Debug我們可以看出,AbstractProtocol的實現是:Http11NioProtocol,從這個類名稱我們便可以很明顯的看出確實使用的是NIO,從而也證明了我們前面的猜想。不過,這只是打斷點看到的,沒看到源碼心裏還是有點不痛快。怎麼從源碼裏找到這個Http11NioProtocol被設置到內嵌Tomcat中呢。

我們還是留意這個方法,方法是調用了factory的addConnectorCustomizers方法,而該方法的作用從名稱上便知道是爲了設置用戶自定義連接配置的。那麼這個factory是什麼呢,從類名ConfigurableTomcatWebServerFactory定義上,我們可以猜想,應該是生成內嵌Tomcat的工廠類。

那麼,我們就進入這個類一探究竟:

哦,原來是個接口,有兩個實現,用的會是哪個呢?不用多說,還是打斷點看一下吧:

用的是TomcatServletWebServerFactory類,那就進去看看。哈哈,我們在類結構中可以找到一個靜態屬性DEFAULT_PROTOCOL,其內容恰好是我們Debug的時候protocol顯示的內容:org.apache.coyote.http11.Http11NioProtocol。

而這個靜態屬性又被賦值給了protocol變量:

再看看這個protocol的調用:

我的天,我們看到了什麼?

Tomcat tomcat = new Tomcat();

這個不就是SpringBoot內嵌生成的那個Tomcat嗎?哈哈哈,原來是在這裏,真是有種發現新大陸的感覺。看看他的包路徑基本可以確認無疑(並不是我們上篇推文中映射自定義配置用的Tomcat類):

而那個protocol就是用在了這裏啦:

Connector connector = new Connector(this.protocol);

至此,我們就能夠證實只設置一個線程卻可以同時連接上多個WebSocket請求的原因是由於SpringBoot的內嵌Tomcat是用了Java NIO多路複用來處理請求的。同時,我們也“幸運”地發現了SpringBoot內嵌Tomcat生成的具體位置是在TomcatServletWebServerFactory類中。

不過,愛刨根問底的小夥伴可能又會有所疑問,既然使用的是Java NIO來處理請求,那麼一個線程能最多處理多少個請求呢?如果處理的不多的話,默認200個線程不是還是不夠用嗎?

由於篇幅問題,這些疑問就留在強哥的下一篇推文繼續和大家一起探討啦~

關注公衆號獲取更多內容,有問題也可在公衆號提問哦:

強哥叨逼叨

叨逼叨編程、互聯網的見解和新鮮事

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章