跳转至

服务器程序常见范式

经过前面大量基础知识的介绍,你已经对服务器程序中常见的编程工具有了一定了解。本章将整合前面的知识,带你了解一个服务器程序的基本结构以及模板代码。

通常,一个服务器程序的运行过程有以下几个主要步骤:

  • 读取配置
  • 验证配置
  • 根据配置初始化不同的服务组件
  • 启动必要的后台服务线程
  • 注册信号处理函数
  • 注册请求处理器
  • 开启监听端口
  • 进入主循环,处理客户端连接,不断接收并解析请求,将请求派发给对应的请求处理器进行处理
  • 如果在运行过程中收到退出信号,退出循环,进行必要的清理并结束进程

而在主循环中,一般遵循以下几种不同的范式:

每个请求创建一个线程

  • 每当有新的客户端连接到服务器,就创建一个线程负责接受并处理这个连接
  • 新创建的线程同样进入循环,不断接收解析请求,调用处理函数
  • 连接断开后,线程退出

这样的范式编写起来比较简单,但是由于线程的创建与销毁是开销很大的,而且如果连接数较多,开启的线程太多,会给操作系统带来巨大的资源消耗。另外,由于切换线程需要进入内核切换上下文,切换的开销也比较大,线程数过多的情况下可能大部分 CPU 时间都用来处理上下文切换了。

所以,这种方式适合连接数不会太多的情况,最好是连接不会频繁建立和断开。

网络与计算分离

  • 预先启动网络 IO 线程,负责处理连接
  • 当有新的客户端连接到服务器的时候,由网络线程接受并处理这个连接
  • 网络 IO 线程负责读写连接上的数据,等请求完整到达后,放入工作队列
  • 处理线程不断从工作队列中获取请求,进行解析并处理,响应交给网络线程写到客户端

这种编程范式比简单一个线程对应一个连接要复杂不少。一般会借助库来实现这种范式。


最后更新: 2021-07-14 17:42:23
本页作者: Howard Lau