09年12月12日,进京参加校内新员工见面会。我的部门在搞3G技术,做手机无线wap(具体什么是wap,还不懂),导师闫志东推荐几本相关书籍,让我入门,这是其中一本。会毕归来,眨眼间,一个多月一晃而过,由于实验室老师要求严格,规矩森严,在实验室阅读非混沌相关书籍为严打对象,加之期间又做了一个混沌加密软件,所以也就一直没抽出大把时间研读此书,只浏览了中间几章,便搁下了。时值寒假,又逢周末,实验室要求相对放松,我决定重拾本书,细细品味,虽一知半解,权作入门。开始之前,按以往风格,先料理一下前世,对浏览过的三、四、五、六、七章进行总结。
第三章 服务器并发处理能力
这里所说的服务器是指提供Http服务的服务器
1、吞吐率: Web服务器单位时间内处理请求的个数。吞吐率通过压力测试得到,吞吐率的前提包括以下条件:并发用户数、请求总数、请求资源描述。
并发用户总数: 是指在某一时刻同时向服务器发送请求的用户总数。
在含有较多变量的数据模型中求解最优化结果是非常困难的。
服务器和用户双方的矛盾: 服务器希望支持高并发率及吞吐率,而用户只希望等待较少的时间,双放不可能都彻底满足。
Web服务器
实际并发用户数可以理解为Web服务器当前维护的代表不同用户的文件描述数,也就是并发连接数,当然,不是同时来了多少用户请求就建立多少连接,Web服务器一般会限制同时服务的最多用户数,如Apache的MaxClients参数,所以,有时实际的并发用户数会大于服务器所维护的我呢间描述符的总数,这时,多出的用户请求,则在服务器内核的数据接收缓冲区中等待处理。
Web服务器所做的工作的本质是争取以最快的速度将内核缓冲区中的用户请求数据一个不剩的都拿回来,然后尽最大努力同时快速处理完这些请求,并将响应数据放到内核维护的另外一块用于发送数据的缓冲区中,接下来再继续处理下一拨请求。
用户平均请求等待时间: 主要用于衡量服务器在一定并发用户数的情况下,对于单个用户的服务质量。
服务器平均请求处理时间: 用户衡量服务器的整体服务质量,是吞吐率的倒数。
Apache的ab测试:ab.exe在Apache的bin目录下
命令行操作 C:\Program Files\Apache Software Foundation\Apache2.2\bin>ab –n 100 –c 10 http://zzqrj.iteye.com/blog/570951
-n 100表示请求总数,-c 100 表示并发用户数
结果:
This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking zzqrj.iteye.com (be patient).....done Server Software: lighttpd/1.4.20 /*被测试的Web服务器的软件名*/ Server Hostname: zzqrj.iteye.com /*请求的URL中主机部分的名称*/ Server Port: 80 /*被测试服务器软件的监听端口*/ Document Path: /blog/570951 /*请求URL中的根绝对路径*/ Document Length: 2095 bytes /*Http响应数据的正文长度*/ Concurrency Level: 10 /*并发用户数*/ Time taken for tests: 41.563 seconds /*所有请求处理完成所花费的时间*/ Complete requests: 100 /*请求总数*/ Failed requests: 0 Write errors: 0 Total transferred: 235300 bytes /*请求响应长度总和,包括Http响应头和正文*/ HTML transferred: 209500 bytes /*请求响应数据正文数据总和,不包括Http头*/ Requests per second: 2.41 [#/sec] (mean) /*吞吐率,即单位时间CPU处理请求的个数Complete requests/ Time taken for tests */ Time per request: 4156.250 [ms] (mean) /*用户平均请求等待时间 Time taken for tests /( Complete requests/ Concurrency Level)*/ Time per request: 415.625 [ms] (mean, across all concurrent requests) /*服务器平均请求处理时间,吞吐率的倒数 Time taken for tests / Complete requests */ Transfer rate: 5.53 [Kbytes/sec] received /*单位时间内从服务器获取的数据长度*/ Connection Times (ms) min mean[+/-sd] median max Connect: 328 405 414.2 344 3344 Processing: 344 3500 1311.0 3125 6125 Waiting: 344 2161 1424.1 2016 6109 Total: 688 3905 1357.3 3469 6484 Percentage of the requests served within a certain time (ms) 50% 3469 66% 3516 75% 3563 80% 6297 90% 6422 95% 6453 98% 6453 99% 6484 100% 6484 (longest request)
并发用户增多到一定数量时,服务器平均处理时间会大幅度增加,用户平均请求等待时间也会大幅度增加。
并发策略的设计就是在服务器同时处理较多请求的时候,如何合理协调并充分利用CPU计算和IO操作,使其在较大的并发用户数的情况下提供较高的吞吐率。
Apache的prefork模式和worker模式:
prefork模式: 这种多处理模块(MPM)实现了一个非线程型的、预派生的web服务器,这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。Prefork使用多个子进程,每个进程只有一个线程,适合没有线程安全库的系统。
worker模式: 此多路处理模块(MPM)使网络服务器支持混合的多线程多进程。它使用多个子进程,每个子进程有多个线程。
它们的配置在Apache的conf\extra\httpd-mpm.conf中。
2. CPU并发计算
IO的速度和CPU的速度相比,就像老牛漫步和超音速飞机一样相距甚远。
进程:每一个进程都有自己独立的内存地址空间和生命周期,每个进程都只能共享CPU寄存器。
线程:
上下文切换: 为了让所有进程可以轮流使用系统资源,进程调度器在必要的时候挂起正在运行的进程,同时恢复以前挂起的某个进程,这种行为成为进程切换。
一个进程被挂起的本质就是将它在CPU寄存器中的数据拿出来暂存在内核态堆栈中。
一个进程恢复工作的本质就是将它的数据重新装入CPU寄存器。
CPU切换(很好的例子): 一手画圆,一手画方,会很费劲,脑子转不过来,画的不流畅,这是因为画图需要大脑计算,当两只手同时画图时,为了保证两边都能流畅地进行,就得快速进行“上下文切换”,将画圆形和方形的规则不断地在大脑里装入和移出,这需要时间。
锁竞争: 锁的是资源,只要涉及抢手的资源,就必然会存在竞争。我们一般采用“锁”机制来控制资源的额占用,当一个任务占用资源时,就锁住资源,这时,其它任务就的等待锁的释放。
3. 系统调用
进程的用户态和内核态: 进程通常运行在用户态,这时候可以使用CPU和内存来完成一些任务,当进程需要对硬件外设进行操作时,就必须切换到内核态。内核提供一系列的系统调用。
用户态和内核态的分离,能提高系统底层安全性以及简化开发模型。系统调用涉及到进程从用户态到内核态的切换,这需要一定的内存空间交换,开销往往较大。
减少不必要的系统调用有助于Web服务器性能优化(如关闭times和gettimeofday调用)。
4. 内存分配
Apache是多进程模式,它使用基于内存池策略的内存管理方案。
Lighttpd是单进程模型。
Nginx(Engine X)是单进程模型,内存使用量很小。Nginx可以使用多线程来处理请求,这使得多个线程之间可以共享内存资源,从而令内存总体使用量大大减少。它使用分阶段的内存分配策略,按需分配,即使释放,使得内存使用量保持在很小的数量范围。
Lighttpd和Nginx其优势主要体现在网络IO模型上。
内存分配策略的设计是Web服务器并发处理能力的重要保证。
5. 持久连接(Keep-Alive)
持久连接: 长连接,是TCP通信的一种方式,在一次TCP连接中持续发送多分数据而不断开连接,与之相反的方式是短连接。
HTTP是无状态的,它不依赖于TCP长连接,通常是一次TCP连接处理一个HTTP请求。要建立长连接,需要Web浏览器和Web服务器共同协作。
浏览器支持长连接: 在发送的请求头中包含长连接的声明,Connection: Keep-Alive。
Web服务器支持长连接: Apache中conf\extra\httpd-default.conf里配置KeepAlive On即可。
对于长连接的有效使用,关键在于长连接超时设置,这需要浏览器和服务器共同设置,并以最小者为准。
持久连接的动机就是尽量减少连接次数,尽量重用连接通道。
6. 阻塞和非阻塞是指当进程访问的数据如果尚未就需,进程是否需要等待。阻塞指的是当前发起IO操作的进程被阻塞,并不是CPU被阻塞,CPU只会拼命的计算,永远不会被阻塞。
同步和异步是指访问数据的机制,同步一般指主动请求并等待IO操作完毕的方式,当数据就绪后在读写的时候必须阻塞,异步则指主动请求数据后便可以继续处理其他任务。
并发策略的目的是让IO操作和CPU计算尽量重叠进行。
看完这章,唤起我待补充的知识: Http、TCP协议需要深入了解(力求从整体上把握,改变现在一知半解的状态),多线程(间通信,内存分配)、多进程(间通信,内存分配)、CPU调度(调度算法,时间片,锁等概念)。