最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot應用啟動內(nèi)置Tomcat的過程源碼分析

 更新時間:2021年07月15日 12:03:43   作者:JavaEdge.  
這篇文章主要介紹了SpringBoot應用啟動內(nèi)置Tomcat的過程分析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

Connector啟動過程

Connector是Tomcat提供的類。

// 通過此 Connector 開始處理請求
@Override
protected 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 {
    	// 核心動作
        protocolHandler.start();
    } catch (Exception e) {
        throw new LifecycleException(
                sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);
    }
}

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

而 protocolHandler 又進一步將請求處理工作交給 NioEndpoint 完成。

AbstractProtocol

@Override
public void start() throws Exception {
    if (getLog().isInfoEnabled()) {
        getLog().info(sm.getString("abstractProtocolHandler.start", getName()));
        logPortOffset();
    }

    endpoint.start();
    monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
            new Runnable() {
                @Override
                public void run() {
                    if (!isPaused()) {
                        startAsyncTimeout();
                    }
                }
            }, 0, 60, TimeUnit.SECONDS);
}

調(diào)用鏈 :

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

start成員變量endpoint,一個 NioEndpoint 實例。Http11NioProtocol 類實例也并非最終處理請求,具體這些請求的處理都委托給了 NioEndpint endpoint 來完成

AbstractEndpoint

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

可見 tomcat 的三種模式,默認使用 NIO 模式。

@Override
public void bind() throws Exception {
    initServerSocket();

    setStopLatch(new CountDownLatch(1));

    // Initialize SSL if needed
    initialiseSsl();

    selectorPool.open(getName());
}
protected void initServerSocket() throws Exception {
    if (!getUseInheritedChannel()) {
    	// 建立服務套接字
        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 OS
        Channel ic = System.inheritedChannel();
        if (ic instanceof ServerSocketChannel) {
            serverSock = (ServerSocketChannel) ic;
        }
        if (serverSock == null) {
            throw new IllegalArgumentException(sm.getString("endpoint.init.bind.inherited"));
        }
    }
    // 設置 serverSock 為阻塞模式
    serverSock.configureBlocking(true); //mimic APR behavior
}

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

其實處理連接的操作不必放在后臺線程,因為后臺線程很可能會處理連接建立不及時,不如將其置于主線程,增加并發(fā)度(雖然優(yōu)勢并不是特別明顯)。
重點關心的是連接建立后獲得的與客戶端交互的那個socket,它的操作必須是非阻塞的,這很顯然。因為在處理長連接時,我們關心的是在本次連接之內(nèi)數(shù)據(jù)的讀寫。

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

正如作者指出的那樣,使 ServerSocketChannel 成為非阻塞的將導致忙讀取,即一個線程將不斷輪詢有無傳入的連接,因為在非阻塞模式下 accept() 可能返回 null。

APR 代表 Apache Portable Runtime

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


參考

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

到此這篇關于SpringBoot應用啟動內(nèi)置Tomcat的過程分析的文章就介紹到這了,更多相關SpringBoot 內(nèi)置Tomcat啟動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java如何將pdf轉換成image

    java如何將pdf轉換成image

    這篇文章主要為大家詳細介紹了java如何將pdf轉換成image,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • JMeter 實現(xiàn)Java請求步驟及原理詳解

    JMeter 實現(xiàn)Java請求步驟及原理詳解

    這篇文章主要介紹了JMeter 實現(xiàn)Java請求步驟及原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • java面試題之try中含return語句時代碼的執(zhí)行順序詳解

    java面試題之try中含return語句時代碼的執(zhí)行順序詳解

    這篇文章主要介紹了關于java中的一道面試題,這套題就是在try中含return語句時代碼的執(zhí)行順序,這個問題看似簡單,卻暗藏殺機??!文中通過一個個例子詳細介紹了其中玄機,需要的朋友可以參考學習,下面來一起看看吧。
    2017-04-04
  • 在IntelliJ IDEA中使用gulp的方法步驟(圖文)

    在IntelliJ IDEA中使用gulp的方法步驟(圖文)

    這篇文章主要介紹了在IntelliJ IDEA中使用gulp的方法步驟(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 使用Java實現(xiàn)簽字功能的示例代碼

    使用Java實現(xiàn)簽字功能的示例代碼

    這篇文章主要為大家詳細介紹了如何使用Java實現(xiàn)簽字功能,同時支持將簽字圖像保存為PNG格式和將簽字添加到PDF文檔中,感興趣的可以了解下
    2024-02-02
  • 使用SpringBoot自定義starter的完整步驟

    使用SpringBoot自定義starter的完整步驟

    這篇文章主要給大家介紹了關于使用SpringBoot自定義starter的完整步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • IDEA2022.2的簡介、下載與安裝、配置教程

    IDEA2022.2的簡介、下載與安裝、配置教程

    IDEA是JetBrains公司推出一個集成開發(fā)工具,是Java開發(fā)工具中的翹楚,基于這個開發(fā)工具可以快速開發(fā)我們的Java相關項目,本文重點給大家介紹IDEA2022.2的簡介、下載與安裝、初步配置,感興趣的朋友一起看看吧
    2022-11-11
  • Gson之toJson和fromJson方法的具體使用

    Gson之toJson和fromJson方法的具體使用

    Gson是Google的一個開源項目,可以將Java對象轉換成JSON,也可能將JSON轉換成Java對象。本文就詳細的介紹了toJson和fromJson方法的具體使用,感興趣的可以了解一下
    2021-11-11
  • Java Condition類案例詳解

    Java Condition類案例詳解

    這篇文章主要介紹了Java Condition類案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • JAVA多線程處理for循環(huán)數(shù)據(jù)詳細講解

    JAVA多線程處理for循環(huán)數(shù)據(jù)詳細講解

    這篇文章主要給大家介紹了關于JAVA多線程處理for循環(huán)數(shù)據(jù)的相關資料,我們在代碼中經(jīng)常需要使用for循環(huán)這個操作來達到目的,而當for循環(huán)的次數(shù)過多時我們會發(fā)現(xiàn)執(zhí)行效率會變的很低,整體耗時非常多,需要的朋友可以參考下
    2023-07-07

最新評論

和田市| 武强县| 新邵县| 贵定县| 黄山市| 南通市| 武川县| 衡东县| 五华县| 白水县| 岳普湖县| 莒南县| 旬阳县| 全州县| 噶尔县| 邵武市| 伊金霍洛旗| 四川省| 大方县| 聂荣县| 万全县| 游戏| 张家口市| 榆社县| 休宁县| 托克托县| 昆山市| 伊宁县| 额济纳旗| 西畴县| SHOW| 沙田区| 正定县| 密云县| 威海市| 晋州市| 百色市| 陆丰市| 桃江县| 杨浦区| 博客|