欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

Connector啟動(dòng)過(guò)程

Connector是Tomcat提供的類。

// 通過(guò)此 Connector 開(kāi)始處理請(qǐng)求
@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 {
    	// 核心動(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 完成

而 protocolHandler 又進(jìn)一步將請(qǐng)求處理工作交給 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 提供實(shí)現(xiàn)。它們都是tomcat提供的類。
  • NioEndpoint endpoint.start()

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

AbstractEndpoint

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

可見(jiàn) tomcat 的三種模式,默認(rèn)使用 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()) {
    	// 建立服務(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 OS
        Channel 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)心的是連接建立后獲得的與客戶端交互的那個(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è)線程將不斷輪詢有無(wú)傳入的連接,因?yàn)樵诜亲枞J较?accept() 可能返回 null。

APR 代表 Apache Portable Runtime

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


參考

https://blog.csdn.net/andy_zhang2007/article/details/78641974
https://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)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Spring Boot和Feign中使用Java 8時(shí)間日期API(LocalDate等)的序列化問(wèn)題

    解決Spring Boot和Feign中使用Java 8時(shí)間日期API(LocalDate等)的序列化問(wèn)題

    這篇文章主要介紹了解決Spring Boot和Feign中使用Java 8時(shí)間日期API(LocalDate等)的序列化問(wèn)題,需要的朋友可以參考下
    2018-03-03
  • 如何使用Comparator比較接口實(shí)現(xiàn)ArrayList集合排序

    如何使用Comparator比較接口實(shí)現(xiàn)ArrayList集合排序

    這篇文章主要介紹了如何使用Comparator比較接口實(shí)現(xiàn)ArrayList集合排序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 深入學(xué)習(xí)java8?中的CompletableFuture

    深入學(xué)習(xí)java8?中的CompletableFuture

    本文主要介紹了java8中的CompletableFuture,CompletableFuture實(shí)現(xiàn)了CompletionStage接口和Future接口,前者是對(duì)后者的一個(gè)擴(kuò)展,增加了異步回調(diào)、流式處理、多個(gè)Future組合處理的能力,使Java在處理多任務(wù)的協(xié)同工作時(shí)更加順暢便利,下文需要的朋友可以參考一下
    2022-05-05
  • 深度剖析Java中的內(nèi)存原型及工作原理

    深度剖析Java中的內(nèi)存原型及工作原理

    這篇文章主要介紹了深度剖析Java中的內(nèi)存原型及工作原理,本文講解了java虛擬機(jī)內(nèi)存原型、常量池、Java內(nèi)存分配中的棧、Java內(nèi)存分配中的堆等內(nèi)容,需要的朋友可以參考下
    2015-01-01
  • SpringCloud創(chuàng)建多模塊項(xiàng)目的實(shí)現(xiàn)示例

    SpringCloud創(chuàng)建多模塊項(xiàng)目的實(shí)現(xiàn)示例

    ,Spring Cloud作為一個(gè)強(qiáng)大的微服務(wù)框架,提供了豐富的功能和組件,本文主要介紹了SpringCloud創(chuàng)建多模塊項(xiàng)目的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • 10分鐘帶你理解Java中的弱引用

    10分鐘帶你理解Java中的弱引用

    這篇文章將帶大家快速理解Java中弱引用,文章介紹的很詳細(xì),對(duì)大家學(xué)習(xí)Java很有幫助哦,有需要的可以參考借鑒。
    2016-08-08
  • 深入理解Java中的Properties類

    深入理解Java中的Properties類

    Properties類是Java中用于處理配置文件的工具類,它繼承自 Hashtable類,實(shí)現(xiàn)了Map接口,本文主要介紹了Java中的Properties類,感興趣的可以了解一下
    2024-01-01
  • java?System類和Arrays類詳解

    java?System類和Arrays類詳解

    這篇文章主要介紹了java?System類和Arrays類詳解,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • java中timer的schedule和scheduleAtFixedRate方法區(qū)別詳解

    java中timer的schedule和scheduleAtFixedRate方法區(qū)別詳解

    這篇文章主要為大家詳細(xì)介紹了java中timer的schedule和scheduleAtFixedRate方法區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 基于springboot實(shí)現(xiàn)數(shù)據(jù)可視化的示例代碼

    基于springboot實(shí)現(xiàn)數(shù)據(jù)可視化的示例代碼

    本文主要介紹了基于springboot實(shí)現(xiàn)數(shù)據(jù)可視化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2022-07-07

最新評(píng)論