想着探討nginx負載均衡的做用html
服務器A 4核 B 8核前端
nginx 部署在A,tomcat1 tomcat2部署在B(由於沒第三臺機器了,只能先這樣看看效果)mysql
nginx worker_connections 51200 後臺worker process進程的最大併發連接數 worker_connections 1024; # 併發總數是 worker_processes 和 worker_connections 的乘積linux
nginx worker_process auto (=4)nginx
nginx 配置長鏈接 keepalive 1000(每一個worker process進程初始長鏈接數,設置越大,內存佔用越多)redis
tomcat配置 算法
<Connector port="8088" protocol="HTTP/1.1" maxThreads="5" minSpareThreads="2" acceptCount="2" connectionTimeout="1000" maxConnections="1000" keepAliveTimeout="300000" maxKeepAliveRequests="1000" redirectPort="8443" />
關鍵參數說明:sql
maxThreads -線程池中最大的活躍線程數,默認值200,不要過高,線程切換有開銷 minSpareThreads-保持存活的最小線程數,默認值25 acceptCount -當tomcat起動的線程數達到最大時,接受排隊的請求個數。默認值爲100,超出的會拒絕請求
maxKeepAliveRequests: 最大長鏈接個數(1表示禁用,-1表示不限制個數,默認100個。通常設置在100~200之間)nginx動態的轉給tomcat,nginx是不能keepalive的(錯),而tomcat默認開啓keepalive,會等待keepalive的timeout,默認不設置就是使用connectionTimeout。因此必須設置tomcat的超時時間,並關閉tomcat的keepalive。不然會產生大量tomcat的socket timewait。maxKeepAliveRequests="1"表示每一個鏈接只響應一次就關閉,這就不會等待timeout了,可避免tomcat產生大量TIME_WAIT鏈接,從必定程度上避免tomcat假死。
第一次測試,20併發2分鐘,nginx-》B,tps 1500,總事務數 20w,數據庫
第二次測試,20併發2分鐘,nginx-》2*B,tps 1500後端
猜想?
1)nginx與tomcat鏈接太多,致使nginx端口占滿後阻塞
2)nginx工做線程滿了
3)壓力還不夠
————————————————————————————
互聯網常見架構接口壓測性能分析及調優手段建議
https://www.cnblogs.com/dimmacro/p/4849729.html
1N1T和1N10T的tps同樣,都爲5000,增大併發時錯誤數增多,應用cpu耗費70%,db無壓力,nginx單臺經過ss –s 發現端口占滿,即nginx到tomcat之間轉發的鏈接端口time-wait狀態6萬多。Nginx存在瓶頸。
調優nginx參數,將短鏈接改成長鏈接
1N3T的tps能到17376,tomat的cpu壓力84%,db的qps18000,cpu69%,應用的資源基本使用到量。
————————————————————————————————————————————
看了這個帖子後,就一直往長鏈接去靠,查閱了不少資料
————————————————————————————————————————————
記一次壓力測試和對nginx/tomcat配置的調整
https://www.cnblogs.com/AloneSword/p/4119928.html
批註:nginx改keepalive ,無果——tomcat keepalive放大
緣由我的分析:tomcat默認打開keepalive功能,而其maxKeepAliveRequests參數默認值爲100,tomcat只接受100個長鏈接,假設nginx發了1000個長鏈接,還有900個長鏈接tomcat直接當短連接處理,發出關閉信號,進入time_wait狀態,nginx只得再開鏈接
在咱們壓測的過程當中, 經過netstat命令能夠看到有不少nginx向tomcat發起的鏈接。 這些鏈接都是短鏈接,每次用完即關閉。因而想到nginx向後端源服務器可否創建長鏈接的問題。查看了一下文檔,nginx從1.1.4版本開始,支持proxy_pass的時候向後端源服務器創建長鏈接。
經過tcpdump抓包發現, 首先發出 Fin 包的是tomcat。 也就是說, tomcat主動關閉的鏈接。
原來在tomcat的配置文件中, 有關於keepalive的幾個參數。 包括每個鏈接完成多少個http請求以後就關閉等。
對tomcat的connector進行了一些調整(包括maxKeepAliveRequests和keepAliveTimeout兩個參數,都設置成-1)以後, 再看鏈接,已經不會頻繁斷開並重建了。 QPS也提高到了900+.(待驗證)
——————————————————————————————
Nginx upstream性能優化
https://www.cnblogs.com/shengs/p/4701905.html
批註:keepalive參數表示每一個工做進程所能保持的最大長鏈接,且不會限制鏈接總數,新長鏈接會建立
激活對上游服務器的鏈接進行緩存。connections參數設置每一個worker進程與後端服務器保持鏈接的最大數量。這些保持的鏈接會被放入緩存。若是鏈接數大於這個值時,最久未使用的鏈接會被關閉。須要注意的是,keepalive指令不會限制Nginx進程與上游服務器的鏈接總數。 新的鏈接總會按需被建立。connections參數應該稍微設低一點,以便上游服務器也能處理額外新進來的鏈接。
1) 對於HTTP代理,proxy_http_version指令應該設置爲「1.1」,同時「Connection」頭的值也應被清空。
2) 另一種選擇是,HTTP/1.0協議的持久鏈接也能夠經過發送「Connection: Keep-Alive」頭來實現。不過不建議這樣用。
3) 對於FastCGI的服務器,須要設置 fastcgi_keep_conn 指令來讓鏈接keepalive工做。當使用的負載均衡方法不是默認的輪轉法時,必須在keepalive 指令以前配置。
——————————————————————————————————————
nginx配置長鏈接---keepalive相關
http://blog.csdn.net/senlin1202/article/details/54617635
# 批註:鏈接到上游服務器的最大併發空閒keepalive長鏈接數(默認是未設置,建議與Tomcat Connector中的maxKeepAliveRequests值同樣) # 當這個數被超過期,使用"最近最少使用算法(LUR)"來淘汰並關閉鏈接。 keepalive 768;
——————————————————————————————————————
關於 Nginx upstream keepalive 的說明
https://www.cnblogs.com/kabi/p/7123354.html
批註(重要):若是併發請求超過keepalive值,nginx啓用新鏈接,且默認發送長鏈接,後端tomcat收到keepalive信號,不主動關閉,由nginx來發送關閉信號,由此產生nginx 得time-wait狀態鏈接,且佔用端口
1. 默認狀況下 Nginx 訪問後端都是用的短鏈接(HTTP1.0),一個請求來了,Nginx 新開一個端口和後端創建鏈接,請求結束鏈接回收。若是像上面的配置同樣設置了長鏈接,Nginx 會接受客戶端的請求,處理完成以後 Nginx 會「繼續保持和後端的長鏈接」,若是併發請求超過了 keepalive 指定的最大鏈接數,Nginx 會啓動新的鏈接 來轉發請求,新鏈接在請求完畢後關閉,並且新創建的鏈接是長鏈接,這可能會形成額外的問題,最後再說。
2. keepalive 指定的 數值 是 Nginx 每一個 worker 鏈接後端的最大長鏈接數,而不是整個 Nginx 的。 並且這裏的後端指的是「全部的後端」,而不是每個後端(已驗證)。
先說一個現象,我發現當 keepalive 設置小的時候,好比1,那麼併發請求上去以後 Nginx 會出現大量的 TIME_WAIT,而若是把 keepalive 關掉(proxy_http_version 1.1 和 proxy_set_header Connection 「」 指令也去掉),那麼 TIME_WAIT 就會出如今後端服務器了,後端用的是 tornado,相信 jetty 和 tomcat 也是同樣。(這個現象我親自驗證)
# tcpdump -i em2 -A host 10.0.11.12 -n
看到:
00:22:53.252039 IP 10.0.31.84.53915 > 10.0.11.12.ddi-tcp-1: Flags [P.], seq 81:161, ack 275, win 123, length 80
@.@.].
..T
…..」…p%8|..P..{>…GET / HTTP/1.1
Host: http_backend
User-Agent: ApacheBench/2.3
Accept: */*
可是若是把 pxe1.hy01 的長鏈接設置都去掉的話,抓包以下:
00:23:58.111974 IP 10.0.31.84.54051 > 10.0.11.12.ddi-tcp-1: Flags [P.], seq 1:100, ack 1, win 115, length 99
E…..@.@.Z=
..T
….#」…O…SUP..s>…GET / HTTP/1.0
Host: http_backend
Connection: close
User-Agent: ApacheBench/2.3
Accept: */*
那麼上面出現的現象就好解釋了,是這樣:
Nginx 和後端的長鏈接不夠用時 Nginx 會新建鏈接來處理新的請求,而咱們的配置已經配置死了 HTTP1.1,創建鏈接後,後端認爲是「長鏈接」而不會主動關閉鏈接(通常有個空閒超時),關閉鏈接由 Nginx 來作了,因此 Nginx 會出現大量的 TIME_WAIT。
而默認狀況下,Nginx 用 HTTP1.0 請求後端,後端處理完成後就主動關閉鏈接,因此 TIME_WAIT 在後端。
那麼如今有新的問題了,若是開啓了長鏈接,而長鏈接又大量不夠用,此時 Nginx 存在的 TIME_WAIT 可能會大量佔用端口,致使端口用盡,若是用盡,後果很嚴重。
————————————————————————————————————————
Nginx與upstream(後端)長鏈接的問題?
https://www.zhihu.com/question/30682780?sort=created
批註:nginx長鏈接消耗內存,可是少了,就會產生不少time-wait鏈接佔用端口
這個數量確實有的聊,如何根據實際狀況定量呢
多了浪費資源,少了,等於把time_wait轉嫁給了ng,顯然這風險要更大
推薦先作一下估算,根據QPS和響應時間計算出須要的長鏈接量。好比10000 QPS和100毫秒響應時間能夠推算出的長鏈接數大概是1000. 將keepalive設置爲這個長鏈接數的10%到50%。固然不考慮資源消耗的話,直接設置爲keepalive=1000也OK
——————————————————————————————————————
[備忘]nginx開啓長鏈接,減小TIME_WAIT數量
http://www.mytju.com/classcode/news_readnews.asp?newsid=935
批註:本文就在說nginx和tomcat在長鏈接得數量上要一致
keepalive 200;表示nginx與後端tomcat最多維持200個長鏈接。
注意,tomcat的connector有個參數maxKeepAliveRequests,是說最大保持長鏈接的數量,
默認是100。總之,nginx和tomcat要配合。
proxy_http_version 1.1; nginx與後端使用HTTP1.1協議,默認是1.0的
proxy_set_header Connection ""; 覆蓋head頭吧
-------------------------------------------------
不按以上設置的話,nginx默認和後端使用短鏈接,
數據傳輸完後,後端發起關閉,因此致使後端服務器有不少TIME_WAIT的鏈接,
保持5000(多少是跟一個linux設置有關),下不來。
打開長鏈接後,TIME_WAIT的值只有幾百。
——————————————————————————————————————
https://www.cnblogs.com/yjf512/p/5327886.html
批註:主要思想-TIMEWAIT是主動斷開方纔會出現,通常狀況下,nginx默認不開長鏈接,tomcat開且容許100個長鏈接,但無聊tomcat的狀況是怎麼樣的,nginx發出的請求告訴tomcat你執行完了就關閉請求,因此tomcat端出現不少timewait
回到上面的問題,go寫了一個HTTP服務,壓測發現TIME_WAIT過多。
首先判斷是否是壓測程序放在服務的同一臺機器...固然不會犯這麼低級的錯誤...
那麼這個感受就有點奇怪了,HTTP服務並無依賴外部mysql或者redis等服務,就是一個簡單的Hello world,而TIME_WAIT的是主動斷開方纔會出現的,因此主動斷開方是服務端?
答案是是的。在HTTP1.1協議中,有個 Connection 頭,Connection有兩個值,close和keep-alive,這個頭就至關於客戶端告訴服務端,服務端你執行完成請求以後,是關閉鏈接仍是保持鏈接,保持鏈接就意味着在保持鏈接期間,只能由客戶端主動斷開鏈接。還有一個keep-alive的頭,設置的值就表明了服務端保持鏈接保持多久。
HTTP默認的Connection值爲close,那麼就意味着關閉請求的一方几乎都會是由服務端這邊發起的。那麼這個服務端產生TIME_WAIT過多的狀況就很正常了。
雖然HTTP默認Connection值爲close,可是如今的瀏覽器發送請求的時候通常都會設置Connection爲keep-alive了。因此,也有人說,如今沒有必要經過調整參數來使TIME_WAIT下降了。
——————————————————————————————————————
四、採用Tomcat集羣能夠最大程度的發揮服務器的性能,能夠在配置較高的服務器上部署多個Tomcat,也能夠在多臺服務器上分別部署Tomcat,Apache和Tomcat整合的方式仍是JK方式。通過驗證,系統對大用戶量使用的響應方面,Apache+3Tomccat集羣> Apache+2Tomcat集羣 > Apache集成Tomcat > 單個Tomcat。而且採用Apache+多Tomcat集羣的部署方式時,若是一個Tomcat出現宕機,系統能夠繼續使用,因此在硬件系統性能足夠優越的狀況下,須要儘可能發揮軟件的性能,能夠採用增長Tomcat集羣的方式。
5. 打開KeepAlive支持
KeepAlive on, KeepAliveTimeout 15 MaxKeepAliveRequests 1000
根據實際經驗,經過Apache和Tomcat集羣的方式提升系統性能的效果十分明顯,這種方式能夠最大化的利用硬件資源,經過多個Tomcat的處理來分擔單Tomcat時的壓力。
——————————————————————————————————————————
Linux下查看Nginx等的併發鏈接數和鏈接狀態
http://www.linuxidc.com/Linux/2012-07/65411.htm
批註:查看timewait的兩個命令
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}'
————————————————————————————————————————
記一次壓測引發的nginx負載均衡性能調優
http://xiaorui.cc/2016/06/26/%E8%AE%B0%E4%B8%80%E6%AC%A1%E5%8E%8B%E6%B5%8B%E5%BC%95%E8%B5%B7%E7%9A%84nginx%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98/
批註:nginx設置keepalive-發現仍然不少短連接-nginx版本不行,換版本
nginx發送短連接-tomcat關閉timewait
nginx發送超出最大鏈接數的長鏈接-nginx關閉timewait
這一點很重要,也是最基本的要求,若是nginx worker鏈接數過少的化,你的請求鏈接就算沒有被阻塞到backlog隊列外,nginx worker也會由於過載保護不會處理新的請求。nginx的最大鏈接數是worker num *worker_connections, 默認worker_connections是1024, 直接幹到10w就能夠了。
——這是對客戶端的,增長nginx對外併發能力
簡單描述下nginx upstream keepalive是個怎麼一回事?
默認狀況下 Nginx 訪問後端都是用的短鏈接(HTTP1.0),一個請求來了,Nginx 新開一個端口和後端創建鏈接,請求結束鏈接回收。
如過配置了http 1.1長鏈接,那麼Nginx會以長鏈接保持後端的鏈接,若是併發請求超過了 keepalive 指定的最大鏈接數,Nginx 會啓動新的鏈接 來轉發請求,新鏈接在請求完畢後關閉,並且新創建的鏈接是長鏈接。
若是你的鏈接池的數控制在128,但由於你要應對更多的併發請求,因此臨時又加了不少的鏈接,但這臨時的鏈接是短鏈接和長鏈接要看你的nginx版本,我這1.8是長鏈接,那他如何被收回,兩地保證,一點是他會主動去釋放,另外一點是keepalive timeout的時間。
————————————————————————————————————————
tcpdump抓取HTTP包
http://blog.csdn.net/kofandlizi/article/details/8106841
批註:tcp 3次握手 4次握手
1. http數據包抓取 (直接在終端輸出package data)
tcpdump tcp port 80 -n -X -s 0 指定80端口進行輸出
tcpdump tcp port 80 -n -s 0 -w /tmp/tcp.cap
————————————————————————————————————————————
http://blog.csdn.net/shi1122/article/details/50411885
批註:如何用wireshark查看鏈接是不是長短鏈接
抓包之後用wireshark看看目標請求的head,發現有connection:close,說明鏈接並不是長鏈接。
——————————————————————————————————————————
學習了一圈後,將nginx與tomcat 的keepalive選項調整測試:
首先分析nginx 未設置keepalive狀況,nginx發出短連接,後端tomcat收到connection:close信號關閉鏈接,不管tomcat如何設置,存在5000+個timewait,抓包後發現 顯式存在 Connection:close標籤,且先後三個請求端口不同,證實是短連接
分析第2種狀況,nginx keepalive 1000,tomcat 100,nginx發出1000個長鏈接請求,tomcat只接受100個,其它900個給你直接當短連接處理,故後端tomcat存在不少timewait,鏈接不夠請求用,前端nginx只得再多開線程,且以默認長鏈接的形式發送,tomcat不作主返回nginx關閉,故前端也存在一些timewait,且當nginx keepalive設置爲128時,前端存在大量timewait;
抓包後發現無Connection,且3次請求端口不一致,說明是存在短連接狀態的
分析第3中狀況,nginx keepalive 1000,tomcat 1000,兩邊基本對等,兩邊的timewait少了不少,tomcat當短連接處理的timewait少了,nginx則長鏈接夠用,也更少的申請多開線程,故timewait也少了,抓包後發現無Connection,但3次請求端口一致,說明使用的同一個鏈接
好了,再作測試,1n1t 1n2t 20併發下qps仍然同樣,暈了,那麼排除長鏈接的可能
考慮第2個緣由,nginx工做線程滿了,頂不住,這個基本開到機器的峯值了,因此沒法更進一步了
考慮第3個緣由,壓力還不夠,看上去也夠了,tomcat maxthread 5,實際壓力有20併發,應當不存在一臺tomcat直接解決問題致使qps一直同樣的狀況,是哪裏錯了?
發現tomcat有個參數:maxConnections,(BIO模式下默認最大鏈接數是它的最大線程數(缺省是200,同maxthreads),NIO模式下默認是10000)
有些地方說這個參數在bio模式下與maxthreads一致,因此就沒管,一直是1000
http://blog.csdn.net/yy3097/article/details/50978410
maxThreads是指Tomcat線程池作多能起的線程數,而 maxConnections 則是Tomcat一瞬間作多可以處理的併發鏈接數。好比maxThreads=1000,maxConnections=800,假設某一瞬間的併發時1000,那麼最終Tomcat的線程數將會是800,即同時處理800個請求,剩餘200進入隊列「排隊」,若是acceptCount=100,那麼有100個請求會被拒掉。
注意:根據前面所說,只是併發那一瞬間Tomcat會起800個線程處理請求,可是穩定後,某一瞬間可能只有不多的線程處於RUNNABLE狀態,大部分線程是TIMED_WAITING,若是你的應用處理時間夠快的話。 因此真正決定Tomcat最大可能達到的線程數是maxConnections這個參數和併發數,當併發數超過這個參數則請求會排隊,這時響應的快慢就看你的程序性能了。
acceptCount -當tomcat起動的線程數達到最大時,接受排隊的請求個數。默認值爲100,超出的會拒絕請求
當tomcat起動的且在用的線程數(或最大鏈接數)達到最大時,接受排隊的請求個數。默認值爲100,超出的會拒絕請求http://blog.csdn.net/kaka20099527/article/details/53285348 這個帖子裏也有引用:
理解:
咱們能夠把tomcat比作一個電影院,流程是取號、買票、觀影,acceptCount比做前廳(容納取到號的人)、maxConnections比做大廳(容納買到票的人)、maxThreads比做影廳(能夠理解一個影廳只容納一我的,由於一個線程同時只處理一個請求),如下場景是針對已達到maxConnections最大值來討論的
1)取號:若是前廳人數已達到acceptCount,則拿號失敗,會獲得Connection refused connect的回覆信息。反之則會進入前廳,等待買票。
2)買票:當大廳人數小於maxConnections時,前廳的人就能夠進入大廳
3)觀影:當影廳的人離開時,大廳的部分人能進入影廳,通常來說大廳的容量要遠大於影廳的數量。
tomcat會處理acceptCount+maxConnections的請求,說明只要取到號,有足夠的耐心,就確定可以看到電影
因此試着將這個參數縮小到與maxthreads同樣是5,作一次單機測試:
(1)max_connection小了以後,事務數大幅度下降
(2)1n2t總算>>1n1t了
anyway,這是一次嘗試,tps與
帶寬 硬件 lvs nginx tomcat jvm 業務代碼 cache db
都有關係,很複雜且非線性,沒有經驗豐富的運維和架構師比較難研究,僅作一次嘗試吧