引言:
本文是本人学习网络编程以来第一次系统的总结《高性能网络服务器》这一高深的论题,可能所写的地方存在诸多问题,欢迎大家留言指点、探讨。随着我的学习深入我也会不断完善本文。
一、什么是高性能服务器
如果要写出高性能的网络服务器,那必须就得对高性能的概念有一定的了解,并指导主要影响服务器高性能的主要因素。所谓高效服务器就是能够同时(宏观上)处理巨大数量的链接IO数据处理。对于影响服务器性能的因素,让我从一个个服务器设计方案中慢慢挖掘出来。
1、最简单的网络服务器模式。
可能我们学习网络通信时候写的第一个最简单的服务器的模型都是一个while循环中不断的accpet链接,然后读取链接上的数据然后再将服务器结果发送回去然后关闭链接。
对于这种服务器模型其特点是,并非能力弱,只能处理短连接。在这里面影响性能的主要是socket阻塞操作、业务逻辑所占用的时间。
2、升级服务器一。
为了解决上面服务器模型性能上面的缺点,也许第一时间想到的就是用多线程解决。设计结构就是用若干个的线程负责accpet,然后每得到一个链接就创建一个线程服务,一般这个线程里面就是一个死循环不断等待连接上的数据到来然后处理。
对于这种服务器模型,解决了方案一中并发处理和只能处理短连接的问题,但其主要缺点也很突出,首先如果链接一多那么就会存在大量的线程,那么我们的服务器将会存在大量线程的切换消耗,同时线程的创建也是主要消耗性能的关键因素。那么我们就要想办法解决这个线程太多和线程创建所占的时间。
3、升级网络服务器二。
为了解决方案二中的问题,我们可以使用一个socket提供的事件模型比如 select、epoll、iocp 等。假设在方案三中我们使用iocp作为我们的socket事件模型,再加上多线程实现我们的服务器。那么其设计结构为:
用一个线程专门专门accpet,然后创建若干线程循环监视iocp事件队列,创建若干工作线程处理数据业务逻辑。当我们有新链接来临的时候,将建立链接的socket绑定到iocp端口上(告诉iocp关心这个socket的事件)并向iocp投递recv事件让iocp等待socket上的recv事件。当iocp等待到了关心socket的recv事件就会在监视iocp事件队列的线程中反馈然后我们将socket和读取到的数据打包成一个io任务给工作线程,让其在合适的时候将io数据处理完成,如果需要反馈则直接向iocp投递socket的send事件。
往往来说一般性能的服务器用方案三的模式都足以处理。在这个模型中我们性能影响的因素有,逻辑处理时间、多线程共享资源互斥访问消耗的时间。虽然看上去本方案性能不错了,但是如果遇到性能要求更高,并非超大,逻辑复杂的服务器还是难以招架,因为单服务器的cpu执行效率有限,单服务器能够处理的并发socket链接有限。
4、升级服务器三(本人没有写过,只是了解过,看过类似的源码)。
到了方案三我们已经发掘出了服务器的比较可观的性能。但是如果我们还有更高的需求。那么我们就得用到分布式服务器集群的方案了。这种方案的设计结构为: 用若干服务器做网关服务器(网关服务器只负责链接建立,和数据分发),用若干服务器做逻辑服务器(逻辑服务器负责处理服务器的业务逻辑)、用若干服务器做数据服务器(专门负责服务器数据库中数据的读写,如果对速度要求很高的话可能还要用到key-value内存数据库(个人用语))。这些服务器间通过局域网络的socket网络通信进行通信。
二、到此影响高性能的因素我归纳如下:
1、使用阻塞的socket操作。
2、复杂的业务逻辑,导致逻辑处理时间过长。
3、庞大的数据库导致读写数据库慢。
4、计算机cpu利用率和cpu性能有限性。
5、如果存在多线程,就有线程切换,线程创建,线程之间共享资源访问所花费的时间。
三、解决影响性能问题的方案。
通过上面的分析我们得出了影响服务器性能的因素,并在几个服务器模型中解决的一些因素,现在归纳解决方案如下.
1、通过使用系统提供的socket 事件模型解决socket阻塞操作的问题。
2、通过服务器集群,多个逻辑服务器减少业务逻辑复杂导致逻辑处理时间长导致的大量排队逻辑任务。
3、通过服务器集群,key-value内存数据等方案解决数据库读写慢的问题。
4、通过多线程充分利cpu的多核性能解决cpu利用率问题,服务器集群解决cpu性能有限的问题。
5、通过线程池解决线程创建导致的消耗。
四、服务器性能其它问题:
1、使用内存池解决服务器长期运行内存碎片问题和提升服务器的稳定性。
未完待完善。。。。。。