一次qps測試實踐(續)

想着探討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

 

 

2.2      壓測現象:數據庫無壓力,應用增長多臺後tps不變

  2.2.1        問題分析:

 

    1N1T和1N10T的tps同樣,都爲5000,增大併發時錯誤數增多,應用cpu耗費70%,db無壓力,nginx單臺經過ss –s 發現端口占滿,即nginx到tomcat之間轉發的鏈接端口time-wait狀態6萬多。Nginx存在瓶頸。

  2.2.2        改進措施:

    調優nginx參數,將短鏈接改成長鏈接

  2.2.3        改進效果:

    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

批註: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鏈接佔用端口

 

這個keepalive 16就是每一個worker(進程?)和upstream保持的長鏈接數。
 
 

這個數量確實有的聊,如何根據實際狀況定量呢

多了浪費資源,少了,等於把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的值只有幾百。

——————————————————————————————————————

 

也說說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的併發能力

https://www.cnblogs.com/linjiqin/p/4430269.html
 
批註:主要思想-對多tomcat整合提升吞吐量提出主張和確定
 

四、採用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次握手

 

 

TCP三次握手(建立 OPEN)

  1. 客戶端發起一個和服務建立TCP連接的請求,這裏是SYN(J)  客戶端SYN_SEND
  2. 服務端接受到客戶端的建立請求後,返回兩個信息: SYN(K) + ACK(J+1)     服務端SYN_RECEIVED
  3. 客戶端在接受到服務端的ACK信息校驗成功後(J與J+1),返回一個信息:ACK(K+1)    客戶端ESTABLISHED
  4. 服務端這時接受到客戶端的ACK信息校驗成功後(K與K+1),再也不返回信息,後面進入數據通信階段

數據通信

  1. 客戶端/服務端 read/write數據包

TCP四次握手(關閉 finish)

  1. 客戶端發起關閉請求,發送一個信息:FIN(M)   客戶端FIN_WAIT1
  2. 服務端接受到信息後,首先返回ACK(M+1),代表本身已經收到消息。   服務端CLOSE_WAIT   客戶端FIN_WAIT2
  3. 服務端在準備好關閉以前,最後發送給客戶端一個 FIN(N)消息,詢問客戶端是否準備好關閉了 服務端LASK_ACK
  4. 客戶端接受到服務端發送的消息後,返回一個確認信息: ACK(N+1)         客戶端TIME_WAIT
  5. 最後,服務端和客戶端在雙方都獲得確認時,各自關閉或者回收對應的TCP連接。  
    1. keepAlive策略能夠有效的避免進行三次握手和四次關閉的動做

1. http數據包抓取 (直接在終端輸出package data)

 

tcpdump tcp port 80 -n -X -s 0 指定80端口進行輸出

 

2. 抓取http包數據指定文件進行輸出package

tcpdump tcp port 80 -n -s 0 -w /tmp/tcp.cap

————————————————————————————————————————————

 

nginx+tomcat的keepalive驗證、bio/nio鏈接比較

 

http://blog.csdn.net/shi1122/article/details/50411885

批註:如何用wireshark查看鏈接是不是長短鏈接

抓包之後用wireshark看看目標請求的head,發現有connection:close,說明鏈接並不是長鏈接。

 

抓nginx的的包,能夠看到有keepalive: 

 

——————————————————————————————————————————

 

 

 

學習了一圈後,將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和maxConnections這兩個參數:

maxThreads是指Tomcat線程池作多能起的線程數,而 maxConnections 則是Tomcat一瞬間作多可以處理的併發鏈接數。好比maxThreads=1000,maxConnections=800,假設某一瞬間的併發時1000,那麼最終Tomcat的線程數將會是800,即同時處理800個請求,剩餘200進入隊列「排隊」,若是acceptCount=100,那麼有100個請求會被拒掉。

注意:根據前面所說,只是併發那一瞬間Tomcat會起800個線程處理請求,可是穩定後,某一瞬間可能只有不多的線程處於RUNNABLE狀態,大部分線程是TIMED_WAITING,若是你的應用處理時間夠快的話。 因此真正決定Tomcat最大可能達到的線程數是maxConnections這個參數和併發數,當併發數超過這個參數則請求會排隊,這時響應的快慢就看你的程序性能了。

 
仍是不懂,無論了,網絡上也沒有說的比較清楚的,可能要深刻源碼,我的感受是,這個tomcat配置能夠同時接受1000個請求,因爲請求簡單很快就搞定了,因而5個線程也夠用,因此我認爲:
acceptCount -當tomcat起動的線程數達到最大時,接受排隊的請求個數。默認值爲100,超出的會拒絕請求
當tomcat起動的且在用的線程數(或最大鏈接數)達到最大時,接受排隊的請求個數。默認值爲100,超出的會拒絕請求
http://blog.csdn.net/kaka20099527/article/details/53285348 這個帖子裏也有引用:
Note that once the limit has been reached, the operating system may still accept connections based on the acceptCount setting.
其中maxConnections描述紅色部分說明當鏈接數達到最大值後,系統會繼續接收鏈接但不會超過 acceptCount的值。

 

 

理解:

咱們能夠把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

都有關係,很複雜且非線性,沒有經驗豐富的運維和架構師比較難研究,僅作一次嘗試吧

相關文章
相關標籤/搜索