一次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

都有关系,很复杂且非线性,没有经验丰富的运维和架构师比较难研究,仅作一次尝试吧

相关文章
相关标签/搜索