av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程源碼分析

瀏覽:73日期:2023-02-25 09:23:38
Connector啟動(dòng)過(guò)程

Connector是Tomcat提供的類(lèi)。

// 通過(guò)此 Connector 開(kāi)始處理請(qǐng)求@Overrideprotected void startInternal() throws LifecycleException { // Validate settings before starting if (getPortWithOffset() < 0) {throw new LifecycleException(sm.getString('coyoteConnector.invalidPort', Integer.valueOf(getPortWithOffset()))); } setState(LifecycleState.STARTING); try { // 核心動(dòng)作protocolHandler.start(); } catch (Exception e) {throw new LifecycleException(sm.getString('coyoteConnector.protocolHandlerStartFailed'), e); }}

springboot默認(rèn)會(huì)在8080端口提供 HTTP 服務(wù),所以這里是一個(gè)處理HTTP協(xié)議請(qǐng)求的 Http11NioProtocol 實(shí)例,使用 NIO 方式處理 HTTP 協(xié)議。Connector 對(duì)HTTP請(qǐng)求的接收和處理并非親自完成,而是委托該 Http11NioProtocol protocolHandler 完成

SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程源碼分析

而 protocolHandler 又進(jìn)一步將請(qǐng)求處理工作交給 NioEndpoint 完成。

AbstractProtocol

@Overridepublic void start() throws Exception { if (getLog().isInfoEnabled()) {getLog().info(sm.getString('abstractProtocolHandler.start', getName()));logPortOffset(); } endpoint.start(); monitorFuture = getUtilityExecutor().scheduleWithFixedDelay( new Runnable() {@Overridepublic void run() { if (!isPaused()) {startAsyncTimeout(); }} }, 0, 60, TimeUnit.SECONDS);}

調(diào)用鏈 :

Connector.start() startInternal() Http11NioProtocol protocolHandler.start(); Http11NioProtocol 的 start方法,由基類(lèi) AbstractProtocol 提供實(shí)現(xiàn)。它們都是tomcat提供的類(lèi)。 NioEndpoint endpoint.start()

start成員變量endpoint,一個(gè) NioEndpoint 實(shí)例。Http11NioProtocol 類(lèi)實(shí)例也并非最終處理請(qǐng)求,具體這些請(qǐng)求的處理都委托給了 NioEndpint endpoint 來(lái)完成

SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程源碼分析

AbstractEndpoint

public final void start() throws Exception { if (bindState == BindState.UNBOUND) {bindWithCleanup();bindState = BindState.BOUND_ON_START; } startInternal();}

可見(jiàn) tomcat 的三種模式,默認(rèn)使用 NIO 模式。SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程源碼分析

@Overridepublic void bind() throws Exception { initServerSocket(); setStopLatch(new CountDownLatch(1)); // Initialize SSL if needed initialiseSsl(); selectorPool.open(getName());}

protected void initServerSocket() throws Exception { if (!getUseInheritedChannel()) { // 建立服務(wù)套接字serverSock = ServerSocketChannel.open();socketProperties.setProperties(serverSock.socket());InetSocketAddress addr = new InetSocketAddress(getAddress(), getPortWithOffset());// 綁定到指定端口serverSock.socket().bind(addr,getAcceptCount()); } else {// Retrieve the channel provided by the OSChannel ic = System.inheritedChannel();if (ic instanceof ServerSocketChannel) { serverSock = (ServerSocketChannel) ic;}if (serverSock == null) { throw new IllegalArgumentException(sm.getString('endpoint.init.bind.inherited'));} } // 設(shè)置 serverSock 為阻塞模式 serverSock.configureBlocking(true); //mimic APR behavior}

serverSocket配置的是阻塞模式,明明默認(rèn)使用NIO 模式,為何還要設(shè)置阻塞模式呢?為什么使用NIO,因?yàn)锽IO的accept是阻塞方法,write和read也都是阻塞的。只能當(dāng)新連接到來(lái)時(shí),去創(chuàng)建新線程去處理這個(gè)連接。如此,最大問(wèn)題是不能同時(shí)處理大量連接,因?yàn)榇罅窟B接帶來(lái)的是創(chuàng)建很多線程,大量線程很容易讓操作系統(tǒng)崩潰,而且雖然并發(fā)度很高,但是很多線程都在空轉(zhuǎn),很多時(shí)間都浪費(fèi)在線程空跑和線程切換上,效率也很差。于是誕生了NIO。

其實(shí)處理連接的操作不必放在后臺(tái)線程,因?yàn)楹笈_(tái)線程很可能會(huì)處理連接建立不及時(shí),不如將其置于主線程,增加并發(fā)度(雖然優(yōu)勢(shì)并不是特別明顯)。重點(diǎn)關(guān)心的是連接建立后獲得的與客戶(hù)端交互的那個(gè)socket,它的操作必須是非阻塞的,這很顯然。因?yàn)樵谔幚黹L(zhǎng)連接時(shí),我們關(guān)心的是在本次連接之內(nèi)數(shù)據(jù)的讀寫(xiě)。

NioEndpoint 正在使用阻塞模式的 ServerSocketChannel 以使其阻塞并等待連接傳入,并且只有在accept后,才以非阻塞方式處理此傳入的socket channel (見(jiàn)setSocketOptions 方法)。

正如作者指出的那樣,使 ServerSocketChannel 成為非阻塞的將導(dǎo)致忙讀取,即一個(gè)線程將不斷輪詢(xún)有無(wú)傳入的連接,因?yàn)樵诜亲枞J较?accept() 可能返回 null。

APR 代表 Apache Portable Runtime

Tomcat在接收到socket的時(shí)候做了如下操作:

SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程源碼分析SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程源碼分析SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程源碼分析

參考

https://blog.csdn.net/andy_zhang2007/article/details/78641974https://stackoverflow.com/questions/23168910/why-tomcats-non-blocking-connector-is-using-a-blocking-socket

到此這篇關(guān)于SpringBoot應(yīng)用啟動(dòng)內(nèi)置Tomcat的過(guò)程分析的文章就介紹到這了,更多相關(guān)SpringBoot 內(nèi)置Tomcat啟動(dòng)內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 亚洲精选一区二区 | 女人夜夜春 | 国内91在线 | 二区精品 | 成人免费在线观看 | 久久久久久国产 | 精品乱人伦一区二区三区 | 日韩一区二区三区在线 | 亚洲国产一区二区三区在线观看 | 成人免费视频网站在线看 | 国产91在线 | 欧美 | 成人精品在线 | 日本一区二区电影 | 草草影院ccyy| 国产精品免费视频一区 | 日韩一区中文字幕 | 欧美一级全黄 | 久草视频在线播放 | 国产高潮av | 久综合 | 性高湖久久久久久久久3小时 | 久久综合一区二区三区 | 中文字幕久久精品 | 国产女人与拘做视频免费 | 国产传媒毛片精品视频第一次 | 波多野结衣一区二区 | 免费成人高清在线视频 | 欧美精品一区二区在线观看 | 在线欧美视频 | 久久精品99 | 成人黄色电影免费 | 懂色一区二区三区免费观看 | 成人a免费 | 激情六月天 | 三级视频在线观看电影 | 亚洲不卡视频 | 国产精品成人一区 | 国产精品国产a级 | 免费99精品国产自在在线 | 国产成人小视频 | 91视频免费在观看 |