高性能服务器程序框架
服务器模型
C/S模型
即为client/server模型,所有的客户端都通过访问服务器来获取数据或资源
C/S模型非常适合资源相对集中的场合,缺点就是服务器是通信的中心,访问量过大时,可能所有客户都将得到很慢的响应。
P2P模型
每台主机都可看做服务器,没有中心,类似去中心化,每台机器地位相等。
服务器编程框架
基本框架可分为三个部分:I/O处理单元、逻辑单元、网络存储单元
I/O处理单元:处理客户连接,读写网络数据
逻辑单元: 处理业务逻辑,通常是进程或者线程
网络存储单元:本地数据库、文件或缓存,但网络存储不是必须有的,例如ssh、telnet等登录服务就没有网络存储单元
I/O模型
socket创建的时候默认是阻塞的,我们可以给socket系统调用的第2个参数设置SOCK_NONBLOCK标志,或者通过fcntl系统调用的F_SETFL命令,将其设置为非阻塞的。
针对阻塞I/O执行的系统调用可能因为无法立即完成而被操作系统挂起,直到等待事件发生为止。
可能被阻塞的系统调用包括accept、send、recv和connect,可能这几个系统调用都是需要在调用后另一方发送确认消息的,所以才会容易被阻塞。
还有一些非阻塞IO执行的系统调用,它们就是一些能够立即返回,不管事件是否发生。
I/O复用是最常用的I/O通知机制。它指的是,应用程序通过I/O复用函数(如select epoll epoll_wait等)向内核注册一组事件,内核通过IO复用函数把就绪的事件通知给应用程序。后面我会详细讲到几个IO复用函数。
阻塞IO、IO复用、信号驱动IO都是 同步IO模型,因为它们IO的读写在IO事件发生之后,且是由应用程序完成。
异步IO:用户可直接对IO进行读写操作,这些操作告诉内核用户读写缓冲区的位置以及IO操作完成之后内核通知应用程序的方式,异步IO总是立即返回,而不论IO是否阻塞。
两种高效的事件处理模式
服务器通常需要处理三类事件:IO事件、信号、定时事件,处理这些事件的两种高效的模式:Reactor和Proactor
Reactor模式
**what:**它要求主线程只负责监听文件描述上是否有事件发生,有的话就立即通知工作线程,主线程不用干任何其他的工作,读写,接受连接处理客户请求均在工作线程中完成。
Proactor模式
what : Proactor模式将所有的IO操作都交给主线程和内核处理,工作线程只负责业务逻辑,因此Proactor模式更适合我们之前讲到的服务器编程框架。