客户端连接服务端时,先随机分配一个端口去连接服务器的80端口,然后服务器会另外随机分配一个端口与客户端通信,该端口由一个socket持有。在程序上的表现就是:当这个socket还存在,就意味着客户端和服务端还在建立连接;反之,即断开连接。
通常情况下,连接会被很快的处理完,然后断开。当客户端再次需要请求服务器资源数,再重新经历上面的过程进行连接。这时客户端和服务端的通信端口还是会重新随机分配,每次连接可能都不一样。客户端在服务端是靠session唯一标识的,和端口没有关系。
所以,我们常说的服务器能够有多大的并发量,实际上就是指服务端能够同时处理多少socket对象。
当Tomcat接收的连接数达到maxConnections时,Acceptor线程不会读取accept队列中的连接;这时accept队列中的线程会一直阻塞着,直到Tomcat接收的连接数小于maxConnections。如果设置为-1,则连接数不受限制。
默认值与连接器使用的协议有关:NIO的默认值是10000,APR/native的默认值是8192,而BIO的默认值为maxThreads。
在windows下,APR/native的maxConnections值会自动调整为设置值以下最大的1024的整数倍;如设置为2000,则最大值实际是1024。
1. 线程池
executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS,taskqueue, tf);
2. 任务队列
taskqueue = new TaskQueue(maxQueueSize); //maxQueueSize = Integer.MAX_VALUE;
3. 部分代码
public boolean offer(Runnable o) {
//we can't do any checks
if (parent==null) return super.offer(o);
//we are maxed out on threads, simply queue the object
//如果线程数==maxThreads,把任务放入任务队列中排队
if (parent.getPoolSize() == parent.getMaximumPoolSize()) return super.offer(o);
//we have idle threads, just add it to the queue
//如果有空闲线程,就使用空闲线程
if (parent.getSubmittedCount()<(parent.getPoolSize())) return super.offer(o);
//if we have less threads than maximum force creation of a new thread
//如果没有空闲线程才新建线程,并且线程数还没有达到maxThreads就返回false,这会导致#############1
if (parent.getPoolSize()
思考:由此可见,用异常来控制逻辑,尽管很巧妙,但并不是一个好的设计 (←_←#)
在线用户数=连接数+静态用户数(已登录,但连接已断开,只是在浏览静态数据)(有session对象,没有socket对象)
连接数=已接受连接数+瞬时并发数(acceptCount:在连接队列里等待的socket对象数) //这个状态的客户端显示为浏览器显示“转圈”
已接受连接数=线程数(RUNNABLE状态)(正在处理)+任务队列中的任务数(已接受,待处理)
实际上,电脑在网卡上的硬件网络端口只有一个。我们所说的1-65535号端口,并不是真的有这么多个硬件端口,硬件端口实际上只有一个,访问所有端口的数据包都发往这个硬件端口。硬件端口接收到数据包之后进行解析,然后通知监听对应端口的socket对象来取数据。
1.业务并发用户数;2.最大并发访问数;3.系统用户数;4.同时在线用户数;
假设一个OA系统有1000用户,这是系统用户数;最高峰同时有500人在线,是“同时在线人数”,也称作“最大业务并发用户数”;500个同时使用系统用户中20%查看系统公告,不构成压力;20%填写表格(只在提交时才会请求,填写对服务器不构成压力);40%在发呆(什么都没做);20%用户不停从一个页面跳转另一个页面(只有这20%对服务器产生了压力)。
说明服务器实际压力,能承受的最大并发访问数,既取决于业务并发用户数,还取决于用户的业务场景,这些可以通过对服务器日志的分析得到。
一般只需要分析出典型业务(用户常用,最关注的业务操作)
给出一个估算业务并发用户数的公式(测试人员一般只关心业务并发用户数)
C=nL/T
C^=C+3×(C的平方根)
C是平均的业务并发用户数、n是login session的数量、L是login session的平均长度、T是指考察的时间段长度、C^是指业务并发用户数的峰值。
该公式的得出是假设用户的login session产生符合泊松分布而估算得到。
假设OA系统有1000用户,每天400个用户发访问,每个登录到退出平均时间2小时,在1天时间内用户只在8小时内使用该系统。
C=400×2/8=100
C^=100+3×(100的平方根)=100+3×10=130
另外,如果知道平均每个用户发出的请求数u,则系统吞吐量可以估算为u×C
请注意:精确估算,还要考虑用户业务操作存在一定的时间集中性(比如上班后1小时内是OA系统高峰期),采用公式计算仍然会存在偏差。针对例子OA系统可以把1小时设定为考察时间的粒度,将一天8小时划分为8个区间,这样可以解决业务操作存在集中性问题,更趋于精准,偏差更小。
系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间
QPS(TPS):每秒钟request/事务 数量
并发数: 系统同时处理的request/事务数
响应时间: 一般取平均响应时间
(很多人经常会把并发数和TPS理解混淆)
理解了上面三个要素的意义之后,就能推算出它们之间的关系:
QPS(TPS)= 并发数/平均响应时间
一个系统吞吐量通常由QPS(TPS)、并发数两个因素决定,每套系统这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。 决定系统响应时间要素
我们做项目要排计划,可以多人同时并发做多项任务,也可以一个人或者多个人串行工作,始终会有一条关键路径,这条路径就是项目的工期。
系统一次调用的响应时间跟项目计划一样,也有一条关键路径,这个关键路径是就是系统影响时间;
关键路径是有CPU运算、IO、外部系统响应等等组成。