ginx并发模型:
nginx
的进程模型采用的是prefork方式,预先分配的worker子进程数量由配置文件指定,默认为1,不超过1024。master主进程创建监听套接口,fork子进程以后,由worker进程监听客户连接,每个worker子进程独自尝试accept已连接套接口,accept是否上锁可以配置,默认会上锁,如果操作系统支持原子整型,才会使用共享内存实现原子上锁,否则使用文件上锁。不使用锁的时候,当多个进程同时accept,当一个连接来的时候多个进程同时被唤起,会导致惊群问题。使用锁的时候,只会有一个worker阻塞在accept上,其他的进程则会不能获取锁而阻塞,这样就解决了惊群的问题。master进程通过socketpair向worker子进程发送命令,终端也可以向master发送各种命令,子进程通过发送信号给master进程的方式与其通信,worker之间通过unix套接口通信。
模型如下图:
Traffic server并发模型:多线程异步事件处理
traffic_cop和traffic_manager作为管理进程,工作进程为traffic_server,traffic_server负责listen和accept,为提高性能,traffic_server使用了异步I/O和多线程技术。Traffic
Server并不是为每个连接都建立一个线程,而是事先创建一组数量可配置的工作线程,每一个工作线程上都运行着独立的异步事件处理程序。traffic_server创建若干组Thread,并将Event按类型调度到相应的Thread的Event队列上,Thread通过执行Event对应的Continuation中的回调函数,来完成状态的迁移。从初始态到终止态的迁移代表了整个事件的执行过程,而Thread是永不退出的,等待着下一个事件的到来。模型如下图:
两种服务器都涉及到网络I/O操作,nginx使用的是linux的epoll模型,traffic server使用异步I/O,由于对于I/O不熟悉,这份就不做深入对比。都使用预分配机制,nginx预分配worker进程,traffic server 预分配工作线程。
对比分析:
1.并发度:
nginx使用的多进程并发模型,采用多进程监听新连接,为此它不需要分发操作,但是引入锁来保持同步,舍去了分发的开销,但是引入了锁的开销。实际中锁的开销比较小,如果系统支持原子整形,那么锁的开销会进一步降低;通过worker进程自己主动去accept,这也会让各个worker进程的负载量比较均衡,这依赖于系统内核对进程的公平的调度。worker进程也可以配置成使用线程进行事件处理工作,但模型上还是属于多进程并发,因为线程需要从进程这里取到事件。这种设计有一个缺陷,worker进程的数量不能太多,nginx设计的worker进程数量的最大值为1024,太多的worker进程会导致进程之间竞争资源频繁,使系统运行缓慢。可见nginx被设计成轻量级的web服务器,但是作为轻量级的web服务器,它有着非常好的性能表现,有报告表明能支持高达 50,000个并发连接数。nginx不愧是轻量级web反向代理服务器的首选。
而traffic server使用多线程异步事件处理模型:将多线程技术与异步事件处理技术结合在一起来提高并发和性能。多线程程序可以充分利用现代处理器多核的处理能力,使一个进程的多个任务可以并行执行,提高程序执行的效率。这种多线程的设计也让traffic server的性能与处理器的性能一直成正比,不会像nginx收到worker进程数目的约束。它不是作为轻量级的web服务器而设计的,它支持集群,Apache Traffic Server v.3.0.0基准测试的结果是每秒钟可以处理200,000多个请求,可见traffic server不愧是高性能的web服务器,个人认为这款服务器将会是以后的发展趋势。
2.响应时间
nginx采用的是worker进程独立accept而直接进行处理的方式处理客户请求,因此nginx的响应速度应该是很快的,个人觉得应该比traffic server服务器要更快。
traffic server是server进程接受请求,然后分发到请求队列中,再由处理线程进行处理,所以理论上响应时间没有nginx快。
网络上的测试文档有表明在请求静态网页的时候,响应速度时间约为5:7,(网上数据,本人没有测试),和分析相符。
3.稳定性
nginx由于是很多能够独立工作的worker进程在工作,当其中的某个或一些worker进程异常时不影响系统的正常工作。master进程在初始化worker进程以后就在循环体中检测信号,然后处理信号,由于master进程一直会比较稳定,当它发现worker进程异常时,又会去重启该worker进程,而且还会检查其他worker进程。可见nginx的这种设计容错性是很高的。
traffic server中由于server是工作进程,而且只有一个,因此系统要保障它的正常运行。为此系统添加了traffic_cop进程与traffic_manager进程来管理server进程,给server进程加上了双重的保障,当server异常时,traffic_manager进程会及时的重启它,而且在重启的过程中还会继续利用traffic_manager进程来接受客户请求,这是个不错的设计。当traffic_manager进程和sever进程同时异常结束的时候,traffic_cop又会重启它们,因此系统的稳定性也是很高的。
由于traffic server重启的过程中无法继续服务,因此稳定性上nginx要胜过traffic server。
4.峰值响应
web服务器都很关心当一小段时间内有大量的连接请求的时候服务器的响情况的。
nginx由于是多个worker进程工作,大量请求来的时候各个worker的负载会比较均匀分布,当峰值过高时,会导致worker进程调度延迟,也就会阻塞客户请求,说明服务器的处理能力会阻塞客户请求,它们之间会存在一个约束关系。另外而Nginx采取了分阶段资源分配技术,由cache manager进程和cache loader 进程处理,这种设计也会使得nginx在遇到峰值请求的时候不轻易的将内存耗尽,不容易造成系统在过载请求下异常结束。
traffic server使用server进程接收到大量的用户请求后会发送到请求队列,然后线程在处理的时候会造成数据量过大,容易内存耗尽,出现异常导致server进程也退出,虽然会很快的重启该进程(官方文档说重启只需要几秒钟),而且重启的过程中还会由manager进程继续接受请求,但是系统却在这段时间内无法处理请求,但是nginx不会停止处理请求。(traffic server没有集群的情况下)
分析说明在短时间爆发性访问的时候nginx的响应能力要优于traffic server。这里说的过载请求量是针对它们各自不同的请求量,比如nginx处理能力为50000连接,那么它的峰值就是50000,它们的反应仅是针对各自的峰值请求。但是traffic server支持集群,这将会很大程度的的提高其峰值响应能力。
5.安全性
nginx对于安全性做的工作不多,恶意连接攻击可能会导致worker进程耗尽系统资源而停止响应,虽然master进程会检测并尝试重启,如果master进程也是去响应,那么系统就需要重启。但是nginx采用分阶段资源分配技术,系统很难会耗尽全部的资源而是去响应,因此一般的dos攻击对于nginx是没什么效果的。总体来说安全性一般。
traffic server在安全性方面做了很多工作,系统会周期性调用heartbeat_manager函数和heartbeat_server函数来检查manager进程和server进程的健康状况,发现不正常时则会立即重启响应的异常进程。而且一旦server进程异常结束,也会很快被重启。因此当收到攻击的时候,traffic server会比较及时的作出反应,系统安全性比较高。
总结:个人认为nginx是多进程并发模型的典范,而traffic server是多线程异步事件处理模型的典范,各有其优缺点。nginx是一款优秀的轻量级web服务器,适合处理请求不多的情况;traffic server则是一款高性能web服务器,还支持集群,更适合处理大量请求连接的情况。