<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      詳解tomcat的連接數(shù)與線程池

      前言

      在使用tomcat時(shí),經(jīng)常會(huì)遇到連接數(shù)、線程數(shù)之類的配置問題,要真正理解這些概念,必須先了解Tomcat的連接器(Connector)。

      在前面的文章 詳解Tomcat配置文件server.xml 中寫到過:Connector的主要功能,是接收連接請(qǐng)求,創(chuàng)建Request和Response對(duì)象用于和請(qǐng)求端交換數(shù)據(jù);然后分配線程讓Engine(也就是Servlet容器)來處理這個(gè)請(qǐng)求,并把產(chǎn)生的Request和Response對(duì)象傳給Engine。當(dāng)Engine處理完請(qǐng)求后,也會(huì)通過Connector將響應(yīng)返回給客戶端。

      可以說,Servlet容器處理請(qǐng)求,是需要Connector進(jìn)行調(diào)度和控制的,Connector是Tomcat處理請(qǐng)求的主干,因此Connector的配置和使用對(duì)Tomcat的性能有著重要的影響。這篇文章將從Connector入手,討論一些與Connector有關(guān)的重要問題,包括NIO/BIO模式、線程池、連接數(shù)等。

      根據(jù)協(xié)議的不同,Connector可以分為HTTP Connector、AJP Connector等,本文只討論HTTP Connector。

      目錄

      一、Nio、Bio、APR

          1、Connector的protocol

          2、如何選擇protocol

          3、BIO/NIO有何不同

      二、3個(gè)參數(shù):acceptCount、maxConnections、maxThreads

          1、acceptCount

          2、maxConnections

          3、maxThreads

          4、參數(shù)設(shè)置

      三、線程池Executor

      四、查看當(dāng)前狀態(tài)

          1、連接數(shù)

          2、線程

      參考文獻(xiàn)

      一、Nio、Bio、APR

      1、Connector的protocol

      Connector在處理HTTP請(qǐng)求時(shí),會(huì)使用不同的protocol。不同的Tomcat版本支持的protocol不同,其中最典型的protocol包括BIO、NIO和APR(Tomcat7中支持這3種,Tomcat8增加了對(duì)NIO2的支持,而到了Tomcat8.5和Tomcat9.0,則去掉了對(duì)BIO的支持)。

      BIO是Blocking IO,顧名思義是阻塞的IO;NIO是Non-blocking IO,則是非阻塞的IO。而APR是Apache Portable Runtime,是Apache可移植運(yùn)行庫,利用本地庫可以實(shí)現(xiàn)高可擴(kuò)展性、高性能;Apr是在Tomcat上運(yùn)行高并發(fā)應(yīng)用的首選模式,但是需要安裝apr、apr-utils、tomcat-native等包。

      2、如何指定protocol

      Connector使用哪種protocol,可以通過<connector>元素中的protocol屬性進(jìn)行指定,也可以使用默認(rèn)值。

      指定的protocol取值及對(duì)應(yīng)的協(xié)議如下:

      • HTTP/1.1:默認(rèn)值,使用的協(xié)議與Tomcat版本有關(guān)
      • org.apache.coyote.http11.Http11Protocol:BIO
      • org.apache.coyote.http11.Http11NioProtocol:NIO
      • org.apache.coyote.http11.Http11Nio2Protocol:NIO2
      • org.apache.coyote.http11.Http11AprProtocol:APR

      如果沒有指定protocol,則使用默認(rèn)值HTTP/1.1,其含義如下:在Tomcat7中,自動(dòng)選取使用BIO或APR(如果找到APR需要的本地庫,則使用APR,否則使用BIO);在Tomcat8中,自動(dòng)選取使用NIO或APR(如果找到APR需要的本地庫,則使用APR,否則使用NIO)。

      3、BIO/NIO有何不同

      無論是BIO,還是NIO,Connector處理請(qǐng)求的大致流程是一樣的:

      在accept隊(duì)列中接收連接(當(dāng)客戶端向服務(wù)器發(fā)送請(qǐng)求時(shí),如果客戶端與OS完成三次握手建立了連接,則OS將該連接放入accept隊(duì)列);在連接中獲取請(qǐng)求的數(shù)據(jù),生成request;調(diào)用servlet容器處理請(qǐng)求;返回response為了便于后面的說明,首先明確一下連接與請(qǐng)求的關(guān)系:連接是TCP層面的(傳輸層),對(duì)應(yīng)socket;請(qǐng)求是HTTP層面的(應(yīng)用層),必須依賴于TCP的連接實(shí)現(xiàn);一個(gè)TCP連接中可能傳輸多個(gè)HTTP請(qǐng)求。

      在BIO實(shí)現(xiàn)的Connector中,處理請(qǐng)求的主要實(shí)體是JIoEndpoint對(duì)象。JIoEndpoint維護(hù)了Acceptor和Worker:Acceptor接收socket,然后從Worker線程池中找出空閑的線程處理socket,如果worker線程池沒有空閑線程,則Acceptor將阻塞。其中Worker是Tomcat自帶的線程池,如果通過<Executor>配置了其他線程池,原理與Worker類似。

      在NIO實(shí)現(xiàn)的Connector中,處理請(qǐng)求的主要實(shí)體是NIoEndpoint對(duì)象。NIoEndpoint中除了包含Acceptor和Worker外,還使用了Poller,處理流程如下圖所示(圖片來源:http://gearever.iteye.com/blog/1844203)。

       

      Acceptor接收socket后,不是直接使用Worker中的線程處理請(qǐng)求,而是先將請(qǐng)求發(fā)送給了Poller,而Poller是實(shí)現(xiàn)NIO的關(guān)鍵。Acceptor向Poller發(fā)送請(qǐng)求通過隊(duì)列實(shí)現(xiàn),使用了典型的生產(chǎn)者-消費(fèi)者模式。在Poller中,維護(hù)了一個(gè)Selector對(duì)象;當(dāng)Poller從隊(duì)列中取出socket后,注冊(cè)到該Selector中;然后通過遍歷Selector,找出其中可讀的socket,并使用Worker中的線程處理相應(yīng)請(qǐng)求。與BIO類似,Worker也可以被自定義的線程池代替。

      通過上述過程可以看出,在NIoEndpoint處理請(qǐng)求的過程中,無論是Acceptor接收socket,還是線程處理請(qǐng)求,使用的仍然是阻塞方式;但在“讀取socket并交給Worker中的線程”的這個(gè)過程中,使用非阻塞的NIO實(shí)現(xiàn),這是NIO模式與BIO模式的最主要區(qū)別(其他區(qū)別對(duì)性能影響較小,暫時(shí)略去不提)。而這個(gè)區(qū)別,在并發(fā)量較大的情形下可以帶來Tomcat效率的顯著提升:

      目前大多數(shù)HTTP請(qǐng)求使用的是長連接(HTTP/1.1默認(rèn)keep-alive為true),而長連接意味著,一個(gè)TCP的socket在當(dāng)前請(qǐng)求結(jié)束后,如果沒有新的請(qǐng)求到來,socket不會(huì)立馬釋放,而是等timeout后再釋放。如果使用BIO,“讀取socket并交給Worker中的線程”這個(gè)過程是阻塞的,也就意味著在socket等待下一個(gè)請(qǐng)求或等待釋放的過程中,處理這個(gè)socket的工作線程會(huì)一直被占用,無法釋放;因此Tomcat可以同時(shí)處理的socket數(shù)目不能超過最大線程數(shù),性能受到了極大限制。而使用NIO,“讀取socket并交給Worker中的線程”這個(gè)過程是非阻塞的,當(dāng)socket在等待下一個(gè)請(qǐng)求或等待釋放時(shí),并不會(huì)占用工作線程,因此Tomcat可以同時(shí)處理的socket數(shù)目遠(yuǎn)大于最大線程數(shù),并發(fā)性能大大提高。

      二、3個(gè)參數(shù):acceptCount、maxConnections、maxThreads

      再回顧一下Tomcat處理請(qǐng)求的過程:在accept隊(duì)列中接收連接(當(dāng)客戶端向服務(wù)器發(fā)送請(qǐng)求時(shí),如果客戶端與OS完成三次握手建立了連接,則OS將該連接放入accept隊(duì)列);在連接中獲取請(qǐng)求的數(shù)據(jù),生成request;調(diào)用servlet容器處理請(qǐng)求;返回response

      相對(duì)應(yīng)的,Connector中的幾個(gè)參數(shù)功能如下:

      1、acceptCount

      accept隊(duì)列的長度;當(dāng)accept隊(duì)列中連接的個(gè)數(shù)達(dá)到acceptCount時(shí),隊(duì)列滿,進(jìn)來的請(qǐng)求一律被拒絕。默認(rèn)值是100。

      2、maxConnections

      Tomcat在任意時(shí)刻接收和處理的最大連接數(shù)。當(dāng)Tomcat接收的連接數(shù)達(dá)到maxConnections時(shí),Acceptor線程不會(huì)讀取accept隊(duì)列中的連接;這時(shí)accept隊(duì)列中的線程會(huì)一直阻塞著,直到Tomcat接收的連接數(shù)小于maxConnections。如果設(shè)置為-1,則連接數(shù)不受限制。

      默認(rèn)值與連接器使用的協(xié)議有關(guān):NIO的默認(rèn)值是10000,APR/native的默認(rèn)值是8192,而BIO的默認(rèn)值為maxThreads(如果配置了Executor,則默認(rèn)值是Executor的maxThreads)。

      在windows下,APR/native的maxConnections值會(huì)自動(dòng)調(diào)整為設(shè)置值以下最大的1024的整數(shù)倍;如設(shè)置為2000,則最大值實(shí)際是1024。

      3、maxThreads

      請(qǐng)求處理線程的最大數(shù)量。默認(rèn)值是200(Tomcat7和8都是的)。如果該Connector綁定了Executor,這個(gè)值會(huì)被忽略,因?yàn)樵揅onnector將使用綁定的Executor,而不是內(nèi)置的線程池來執(zhí)行任務(wù)。

      maxThreads規(guī)定的是最大的線程數(shù)目,并不是實(shí)際running的CPU數(shù)量;實(shí)際上,maxThreads的大小比CPU核心數(shù)量要大得多。這是因?yàn)椋幚碚?qǐng)求的線程真正用于計(jì)算的時(shí)間可能很少,大多數(shù)時(shí)間可能在阻塞,如等待數(shù)據(jù)庫返回?cái)?shù)據(jù)、等待硬盤讀寫數(shù)據(jù)等。因此,在某一時(shí)刻,只有少數(shù)的線程真正的在使用物理CPU,大多數(shù)線程都在等待;因此線程數(shù)遠(yuǎn)大于物理核心數(shù)才是合理的。

      換句話說,Tomcat通過使用比CPU核心數(shù)量多得多的線程數(shù),可以使CPU忙碌起來,大大提高CPU的利用率。

      4、參數(shù)設(shè)置

      (1)maxThreads的設(shè)置既與應(yīng)用的特點(diǎn)有關(guān),也與服務(wù)器的CPU核心數(shù)量有關(guān)。通過前面介紹可以知道,maxThreads數(shù)量應(yīng)該遠(yuǎn)大于CPU核心數(shù)量;而且CPU核心數(shù)越大,maxThreads應(yīng)該越大;應(yīng)用中CPU越不密集(IO越密集),maxThreads應(yīng)該越大,以便能夠充分利用CPU。當(dāng)然,maxThreads的值并不是越大越好,如果maxThreads過大,那么CPU會(huì)花費(fèi)大量的時(shí)間用于線程的切換,整體效率會(huì)降低。

      (2)maxConnections的設(shè)置與Tomcat的運(yùn)行模式有關(guān)。如果tomcat使用的是BIO,那么maxConnections的值應(yīng)該與maxThreads一致;如果tomcat使用的是NIO,maxConnections值應(yīng)該遠(yuǎn)大于maxThreads。

      (3)通過前面的介紹可以知道,雖然tomcat同時(shí)可以處理的連接數(shù)目是maxConnections,但服務(wù)器中可以同時(shí)接收的連接數(shù)為maxConnections+acceptCount 。acceptCount的設(shè)置,與應(yīng)用在連接過高情況下希望做出什么反應(yīng)有關(guān)系。如果設(shè)置過大,后面進(jìn)入的請(qǐng)求等待時(shí)間會(huì)很長;如果設(shè)置過小,后面進(jìn)入的請(qǐng)求立馬返回connection refused。

      三、線程池Executor

      Executor元素代表Tomcat中的線程池,可以由其他組件共享使用;要使用該線程池,組件需要通過executor屬性指定該線程池。

      Executor是Service元素的內(nèi)嵌元素。一般來說,使用線程池的是Connector組件;為了使Connector能使用線程池,Executor元素應(yīng)該放在Connector前面。Executor與Connector的配置舉例如下:

      <Executor name="tomcatThreadPool" namePrefix ="catalina-exec-" maxThreads="150" minSpareThreads="4" />
      <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" acceptCount="1000" />

      Executor的主要屬性包括:

      • name:該線程池的標(biāo)記
      • maxThreads:線程池中最大活躍線程數(shù),默認(rèn)值200(Tomcat7和8都是)
      • minSpareThreads:線程池中保持的最小線程數(shù),最小值是25
      • maxIdleTime:線程空閑的最大時(shí)間,當(dāng)空閑超過該值時(shí)關(guān)閉線程(除非線程數(shù)小于minSpareThreads),單位是ms,默認(rèn)值60000(1分鐘)
      • daemon:是否后臺(tái)線程,默認(rèn)值true
      • threadPriority:線程優(yōu)先級(jí),默認(rèn)值5
      • namePrefix:線程名字的前綴,線程池中線程名字為:namePrefix+線程編號(hào)

      四、查看當(dāng)前狀態(tài)

      上面介紹了Tomcat連接數(shù)、線程數(shù)的概念以及如何設(shè)置,下面說明如何查看服務(wù)器中的連接數(shù)和線程數(shù)。

      查看服務(wù)器的狀態(tài),大致分為兩種方案:(1)使用現(xiàn)成的工具,(2)直接使用Linux的命令查看。

      現(xiàn)成的工具,如JDK自帶的jconsole工具可以方便的查看線程信息(此外還可以查看CPU、內(nèi)存、類、JVM基本信息等),Tomcat自帶的manager,收費(fèi)工具New Relic等。下圖是jconsole查看線程信息的界面:

       

      下面說一下如何通過Linux命令行,查看服務(wù)器中的連接數(shù)和線程數(shù)。

      1、連接數(shù)

      假設(shè)Tomcat接收http請(qǐng)求的端口是8083,則可以使用如下語句查看連接情況:

      netstat –nat | grep 8083

      結(jié)果如下所示:

      可以看出,有一個(gè)連接處于listen狀態(tài),監(jiān)聽請(qǐng)求;除此之外,還有4個(gè)已經(jīng)建立的連接(ESTABLISHED)和2個(gè)等待關(guān)閉的連接(CLOSE_WAIT)。

      2、線程

      ps命令可以查看進(jìn)程狀態(tài),如執(zhí)行如下命令:

      ps –e | grep java
      

      結(jié)果如下圖:

      可以看到,只打印了一個(gè)進(jìn)程的信息;27989是進(jìn)程id,java是指執(zhí)行的java命令。這是因?yàn)閱?dòng)一個(gè)tomcat,內(nèi)部所有的工作都在這一個(gè)進(jìn)程里完成,包括主線程、垃圾回收線程、Acceptor線程、請(qǐng)求處理線程等等。

      通過如下命令,可以看到該進(jìn)程內(nèi)有多少個(gè)線程;其中,nlwp含義是number of light-weight process。

      ps –o nlwp 27989
      

      可以看到,該進(jìn)程內(nèi)部有73個(gè)線程;但是73并沒有排除處于idle狀態(tài)的線程。要想獲得真正在running的線程數(shù)量,可以通過以下語句完成:

      ps -eLo pid ,stat | grep 27989 | grep running | wc -l

      其中ps -eLo pid ,stat可以找出所有線程,并打印其所在的進(jìn)程號(hào)和線程當(dāng)前的狀態(tài);兩個(gè)grep命令分別篩選進(jìn)程號(hào)和線程狀態(tài);wc統(tǒng)計(jì)個(gè)數(shù)。其中,ps -eLo pid ,stat | grep 27989輸出的結(jié)果如下:

       圖中只截圖了部分結(jié)果;Sl表示大多數(shù)線程都處于空閑狀態(tài)。

      參考文獻(xiàn)

      Tomcat 7.0官方文檔

      Tomcat 8.0官方文檔

      Tomcat 8.5官方文檔

      Tomcat maxThreads maxConnections acceptCount參數(shù)說明

      tomcat架構(gòu)分析(connector BIO 實(shí)現(xiàn))

      tomcat架構(gòu)分析 (connector NIO 實(shí)現(xiàn))

      Why is the tomcat default thread pool size so large?

      Howto find Tomcat current thread count

       

      創(chuàng)作不易,如果文章對(duì)你有幫助,就點(diǎn)個(gè)贊、評(píng)個(gè)論唄~

      創(chuàng)作不易,如果文章對(duì)你有幫助,就點(diǎn)個(gè)贊、評(píng)個(gè)論唄~

      創(chuàng)作不易,如果文章對(duì)你有幫助,就點(diǎn)個(gè)贊、評(píng)個(gè)論唄~

       

       

      posted @ 2017-11-09 08:51  編程迷思  閱讀(114770)  評(píng)論(37)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久青青草原亚洲AV无码麻豆| 亚洲中文字幕第二十三页| 精品免费看国产一区二区| 一级女性全黄久久生活片| 日本丰满熟妇videossexhd| 亚洲综合成人av在线| 久久国产乱子精品免费女| 蜜桃网址| 精品亚洲国产成人| 欧美一级黄色影院| 欧美人成精品网站播放| 国产免费午夜福利在线播放| 国产国语毛片在线看国产| 繁昌县| 婷婷色香五月综合缴缴情香蕉| 中文字幕亚洲制服在线看| 少妇高清一区二区免费看| 久久久久久亚洲精品成人| 国产成人最新三级在线视频| 婷婷五月综合丁香在线| 精品国产午夜福利在线观看| 国产视频一区二区三区四区视频| 亚洲欧洲日产国码无码久久99| 日本九州不卡久久精品一区| 欧美人与禽2o2o性论交| 国产AV福利第一精品| 国产色悠悠综合在线观看| 无码电影在线观看一区二区三区| 欧美日韩亚洲国产| 丁香五香天堂网| 加勒比无码专区中文字幕| 不卡免费一区二区日韩av| 韩产日产国产欧产| 亚洲精品一区二区二三区| 丰满少妇高潮无套内谢| 狠狠色噜噜狠狠狠狠7777米奇| 久久97超碰色中文字幕| 精品无码一区在线观看| 国内自拍视频在线一区| 国产中文字幕日韩精品| 国产精品无码无需播放器|