知識(shí)補(bǔ)充:
同步 : 自己親自出馬持銀行卡到銀行取錢(使用同步IO時(shí),Java自己處理IO讀寫)。
異步 : 委托一小弟拿銀行卡到銀行取錢,然后給你(使用異步IO時(shí)肾砂,Java將IO讀寫委托給OS處理,需要將數(shù)據(jù)緩沖區(qū)地址和大小傳給OS(銀行卡和密碼)宏悦,OS需要支持異步IO操作API)镐确。
阻塞 : ATM排隊(duì)取款,你只能等待(使用阻塞IO時(shí)饼煞,Java調(diào)用會(huì)一直阻塞到讀寫完成才返回)源葫。
非阻塞 : 柜臺(tái)取款,取個(gè)號(hào)砖瞧,然后坐在椅子上做其它事息堂,等號(hào)廣播會(huì)通知你辦理,沒(méi)到號(hào)你就不能去块促,你可以不斷問(wèn)大堂經(jīng)理排到了沒(méi)有荣堰,大堂經(jīng)理如果說(shuō)還沒(méi)到你就不能去(使用非阻塞IO時(shí),如果不能讀寫Java調(diào)用會(huì)馬上返回竭翠,當(dāng)IO事件分發(fā)器會(huì)通知可讀寫時(shí)再繼續(xù)進(jìn)行讀寫振坚,不斷循環(huán)直到讀寫完成)。
一.線程池的介紹
線程池作為提高程序處理數(shù)據(jù)能力的一種方案斋扰,應(yīng)用非常廣泛渡八。大量的服務(wù)器都或多或少的使用到了線程池技術(shù)啃洋,不管是哪種語(yǔ)言實(shí)現(xiàn),線程池都有如下的特點(diǎn):
1.線程池一般有三個(gè)重要參數(shù):
最大線程數(shù)呀狼。在程序運(yùn)行的任何時(shí)候,線程數(shù)總數(shù)都不會(huì)超過(guò)這個(gè)數(shù)损离。如果請(qǐng)求數(shù)量超過(guò)最大數(shù)時(shí)哥艇,則會(huì)等待其他線程結(jié)束后再處理。
最大共享線程數(shù)僻澎,即最大空閑線程數(shù)貌踏。如果當(dāng)前的空閑線程數(shù)超過(guò)該值,則多余的線程會(huì)被殺掉窟勃。
最小共享線程數(shù)祖乳,即最小空閑線程數(shù)。如果當(dāng)前的空閑數(shù)小于該值秉氧,則一次性創(chuàng)建這個(gè)數(shù)量的空閑線程眷昆,所以它本身也是一個(gè)創(chuàng)建線程的步長(zhǎng)。?
2.線程池有兩個(gè)概念:
Worker線程:工作線程主要是運(yùn)行執(zhí)行代碼汁咏,有兩種狀態(tài):空閑狀態(tài)和運(yùn)行狀態(tài)亚斋。在空閑狀態(tài)時(shí),類似“休眠”攘滩,等待任務(wù)帅刊;處理運(yùn)行狀態(tài)時(shí),表示正在運(yùn)行任務(wù)(Runnable)漂问。
輔助線程:主要負(fù)責(zé)監(jiān)控線程池的狀態(tài):空閑線程是否超過(guò)最大空閑線程數(shù)或者小于最小空閑線程數(shù)等赖瞒。如果不滿足要求,就調(diào)整之蚤假。
二.線程池的原理(類似于操作系統(tǒng)中緩存的概念):
先啟動(dòng)若干數(shù)量的線程栏饮,并讓這些線程都處于睡眠 狀態(tài),當(dāng)客戶端有一個(gè)新請(qǐng)求時(shí)磷仰,就會(huì)喚醒線程池中的某一個(gè)睡眠線程抡爹,讓它來(lái)處理客戶端的這個(gè)請(qǐng)求,當(dāng)處理完這個(gè)請(qǐng)求后芒划,線程又處于睡眠狀態(tài)冬竟。
為什么要搞得這么麻煩,如果每當(dāng)客戶端有新的請(qǐng)求時(shí)民逼,我就創(chuàng)建一個(gè)新的線程不就完了泵殴?這也許是個(gè)不錯(cuò)的方法,因?yàn)樗苁沟媚憔帉懘a相對(duì)容易一些拼苍,但 你卻忽略了一個(gè)重要的問(wèn)題??性能笑诅!高峰期每秒的客戶端請(qǐng)求并發(fā)數(shù)超過(guò)100调缨,如果 為每個(gè)客戶端請(qǐng)求創(chuàng)建一個(gè)新線程的話,那耗費(fèi)的CPU時(shí)間和內(nèi)存將是驚人的吆你,如果采用一個(gè)擁有200個(gè)線程的線程池弦叶,那將會(huì)節(jié)約大量的的系統(tǒng)資源,使得更 多的CPU時(shí)間和內(nèi)存用來(lái)處理實(shí)際的商業(yè)應(yīng)用妇多,而不是頻繁的線程創(chuàng)建與銷毀伤哺。?
三.tomcat線程池的配置(使用線程池,用較少的線程處理較多的訪問(wèn)者祖,提高tomcat的處理能力):
1.vim tomcat/conf/server.xml
將注釋的線程池打開(kāi):
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
? ? ? ? maxThreads="500" minSpareThreads="5" maxIdleTime="60000" prestartminSpareThreads="true" maxQueueSize="100"?/>
參數(shù)詳情介紹:
name: 線程名稱
namePrefix: 線程前綴
maxThreads : 最大并發(fā)連接數(shù),不配置時(shí)默認(rèn)200,一般建議設(shè)置500~ 800 ,要根據(jù)自己的硬件設(shè)施條件和實(shí)際業(yè)務(wù)需求而定立莉。?
minSpareThreads:Tomcat啟動(dòng)初始化的線程數(shù),默認(rèn)值25
maxSpareThreads:最多備用線程數(shù)七问,一旦創(chuàng)建的線程超過(guò)這個(gè)值蜓耻,Tomcat就會(huì)關(guān)閉不再需要的socket線程
prestartminSpareThreads:在tomcat初始化的時(shí)候就初始化minSpareThreads的值,不設(shè)置為true
maxQueueSize: 最大的等待隊(duì)列數(shù),超過(guò)則拒絕請(qǐng)求
maxIdleTime:默認(rèn)線程最大空閑時(shí)間60秒。?如果一個(gè)線程在60秒以內(nèi)沒(méi)有活躍械巡,則終止運(yùn)行并從線程池中移除刹淌。除非線程池?cái)?shù)量小于或等于minSpareThreads數(shù)量
2.<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
? ? ? ? ? ? ? connectionTimeout="20000"?enableLookups="false"? ??acceptCount="100"? ?maxPostSize="10485760"??compression="on"??compressionMinSize="2048"??
????????noCompressionUserAgents="gozilla, traviata"??
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript"??
? ? ? ? ? ? ? redirectPort="8443" />
1)需要添加線程池的名稱-----executor="tomcatThreadPool"
以上線程池配置修改成功,需要重新啟動(dòng)tomcat讥耗。
Tomcat的并發(fā)請(qǐng)求處理數(shù)量=maxThreads + acceptCount
參數(shù)介紹:
executor:線程池的名稱
port:連接端口
protocol:協(xié)議 --->bio,nio,apr(下面會(huì)詳細(xì)介紹)
enableLookups:禁止DNS查詢
acceptCount:指定當(dāng)所有可以使用的處理請(qǐng)求的線程數(shù)都被使用時(shí)芦鳍,可以放到處理隊(duì)列中的請(qǐng)求數(shù),超過(guò)這個(gè)數(shù)的請(qǐng)求將不予處理葛账,默認(rèn)設(shè)置 100?
maxPostSize:限制 以FORM URL 參數(shù)方式的POST請(qǐng)求的內(nèi)容大小柠衅,單位字節(jié),默認(rèn)是 2097152(2兆)籍琳,10485760 為 10M菲宴。?
緩存優(yōu)化:
?compression:壓縮傳輸,壓縮會(huì)增加Tomcat負(fù)擔(dān)趋急,最好采用Nginx + Tomcat 或者 Apache + Tomcat 方式喝峦,壓縮交由Nginx/Apache 去做
compressionMinSize:壓縮的大小
noCompressionUserAgents:不啟用壓縮的瀏覽器 ,gozilla, traviata
compressableMimeType:壓縮文件類型
URIEncoding URL統(tǒng)一編碼
壓縮小計(jì):Tomcat 的壓縮是在客戶端請(qǐng)求服務(wù)器對(duì)應(yīng)資源后呜达,從服務(wù)器端將資源文件壓縮谣蠢,再輸出到客戶端,由客戶端的瀏覽器負(fù)責(zé)解壓縮并瀏覽查近。相對(duì)于普通的 瀏覽過(guò)程 HTML眉踱、CSS、Javascript和Text霜威,它可以節(jié)省40% 左右的流量谈喳。更為重要的是,它可以對(duì)動(dòng)態(tài)生成的戈泼,包括CGI婿禽、PHP赏僧、JSP、ASP扭倾、Servlet,SHTML等輸出的網(wǎng)頁(yè)也能進(jìn)行壓縮淀零,壓縮效率也很高。
四.tomcat3種運(yùn)行模式(即配置文件中的協(xié)議):
1.bio---------配置的內(nèi)容:HTTP/1.1
同步阻塞IO(JAVA BIO):同步并阻塞膛壹,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程(one connection one thread 想想都覺(jué)得恐怖,線程可是非常寶貴的資源)驾中,當(dāng)然可以通過(guò)線程池機(jī)制改善.默認(rèn)模式,性能非常低下恢筝,沒(méi)有經(jīng)過(guò)任何優(yōu)化處理
BIO方式適用于連接數(shù)目比較小且固定的架構(gòu)哀卫,這種方式對(duì)服務(wù)器資源要求比較高巨坊,并發(fā)局限于應(yīng)用中撬槽,JDK1.4以前的唯一選擇,但程序直觀簡(jiǎn)單易理解
2.nio
是Java SE 1.4及后續(xù)版本提供的一種新的I/O操作方式(即java.nio包及其子包)趾撵。Java nio是一個(gè)基于緩沖區(qū)侄柔、并能提供非阻塞I/O操作的Java API,因此nio也被看成是non-blocking I/O的縮寫占调。它擁有比傳統(tǒng)I/O操作(bio)更好的并發(fā)運(yùn)行性能
nio---->org.apache.coyote.http11.Http11NioProtocol
JAVA NIO:又分為同步非阻塞IO,異步阻塞IO 與BIO最大的區(qū)別one request one thread.可以復(fù)用同一個(gè)線程處理多個(gè)connection(多路復(fù)用)
NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu)暂题,比如聊天服務(wù)器,并發(fā)局限于應(yīng)用中究珊,編程比較復(fù)雜薪者,JDK1.4開(kāi)始支持
nio2---->org.apache.coyote.http11.Http11Nio2Protocol
異步非阻塞IO(Java NIO2又叫AIO) 主要與NIO的區(qū)別主要是操作系統(tǒng)的底層區(qū)別.可以做個(gè)比喻:比作快遞,NIO就是網(wǎng)購(gòu)后要自己到官網(wǎng)查下快遞是否已經(jīng)到了(可能是多次)剿涮,然后自己去取快遞言津;AIO就是快遞員送貨上門了(不用關(guān)注快遞進(jìn)度)。
AIO方式使用于連接數(shù)目多且連接比較長(zhǎng)(重操作)的架構(gòu)
3.apr-------->Http11AprProtocol:
?APR是從操作系統(tǒng)級(jí)別來(lái)解決異步的IO問(wèn)題,大幅度的提高性能.
APR(Apache Portable Runtime)是一個(gè)高可移植庫(kù),它是Apache HTTP Server 2.x的核心.能更好地和其它本地web技術(shù)集成取试,總體上讓Java更有效率作為一個(gè)高性能web服務(wù)器平臺(tái)而不是簡(jiǎn)單作為后臺(tái)容器.
在產(chǎn)品環(huán)境中悬槽,特別是直接使用Tomcat做WEB服務(wù)器的時(shí)候,應(yīng)該使用Tomcat Native來(lái)提高其性能.如果不配APR瞬浓,基本上300個(gè)線程狠快就會(huì)用滿初婆,以后的請(qǐng)求就只好等待.但是配上APR之后,并發(fā)的線程數(shù)量明顯下降猿棉,從原來(lái)的300可能會(huì)馬上下降到只有幾十磅叛,新的請(qǐng)求會(huì)毫無(wú)阻塞的進(jìn)來(lái).
在局域網(wǎng)環(huán)境測(cè),就算是400個(gè)并發(fā)萨赁,也是一瞬間就處理/傳輸完畢宪躯,但是在真實(shí)的Internet環(huán)境下,頁(yè)面處理時(shí)間只占0.1%都不到位迂,絕大部分時(shí)間都用來(lái)頁(yè)面?zhèn)鬏?如果不用APR访雪,一個(gè)線程同一時(shí)間只能處理一個(gè)用戶详瑞,勢(shì)必會(huì)造成阻塞。所以生產(chǎn)環(huán)境下用apr是非常必要的.
4.apr連接器的安裝:
軟件安裝:
apr 安裝
tar zxf apr-1.5.2.tar.gz -C /usr/local/src/
cd /usr/local/src/apr-1.5.2/
./configure --prefix=/usr/local/apr && make && make install
apr-utils 安裝
tar zxf apr-util-1.5.4.tar.gz -C /usr/local/src/
cd /usr/local/src/apr-util-1.5.4/
./configure --with-apr=/usr/local/apr/ --prefix=/usr/local/apr-utils && make && make install
tomcat-native安裝
cd /usr/local/apache-tomcat-7.0.65/bin/
tar zxf tomcat-native.tar.gz
cd tomcat-native-1.1.33-src/jni/native
./configure --with-apr=/usr/local/apr --with-java-home=/usr/local/java/ && make && make install
安裝完后記得在 /etc/profile 的JAVA變量后面多加一條APR的環(huán)境變量:
export? PATH=$PATH:/usr/loacl/apr/lib
配置修改:
<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
? ? ? ? ? ? ? connectionTimeout="20000"? ?redirectPort="8443" />
5.連接器的比較