高性能服务器系列-第五章 高并发服务器架构
前言
高性能大并发服务器是一个系统工程,服务器硬件(CPU、内存、磁盘、网络)和服务器软件系统(应用队列、连接池,缓存计算、网络通信技术、数据库、分布式技术)都至关重要。本文不讨论12306、淘宝等超高性能、超大规模的服务器,仅分析百万级QPS服务器技术。
一、高并发服务器架构-消息处理机制
服务器一个核心任务就是消息处理,消息处理包括网络消息接收、消息处理。下图展示套高效的消息处理机制:
1.网络消息接收
- 网络消息传输协议选择
传输控制协议(TCP)和用户数据报协议(UDP)是两种最常用的网络传输协议。对服务器而言,使用TCP协议时,服务器需要管理大量的TCP连接,包括连接的建立与释放,TCP需要通过“三次握手”过程建立连接。在数据传输结束后,还需通过“四次挥手”过程来终止连接。这将消耗不少的服务器资源。因此高并发服务器选择更高效的UDP协议无疑是比较合适的,当然需要采取措施确保数据传输的可靠性。
- IO复用模型选择
Linux系统网络消息接收比较好的方案是采用epoll IO多路复用技术,epoll 与select、poll相比,能明确知道哪个流发生了怎样的I/O事件,时间复杂度O(1),能提高程序在大量并发连接情况下的系统CPU利用率。
2.消息处理
高效的消息处理有几个关键点:1、尽量少地拷贝消息内容;2、避免消息处理阻塞;3、消息分类处理,尽量最短流程处理。下面逐条分析一下:
-
1、尽量少地拷贝消息内容
网络消息从内核区拷贝至用户区后,尽量不再进行消息拷贝,一个方法是开辟一块合适大小的全局内存,用于从内核区读取网络消息,该区域循环使用,消息处理时只传递消息的在该区域的偏移地址。 -
2、避免消息处理阻塞
避免消息处理阻塞要做到如下几点:
a、消息接收与消息处理分离,采用线程池技术进行消息接收和消息处理,创建四个线程池:udp消息接收线程池、udp消息处理线程池、广播消息处理线程池、透传消息转发线程池。
MSGRECVPORTNUM 为消息接收端口数,可根据业务需求在多个端口接收消息。
MSGRECVTHREADNUM 为消息接收线程数,最好是MSGRECVPORTNUM的倍数。
MSGPROTHREADRATE 为每个消息接收线程对应的消息处理线程数
b、消息处理线程池线程数要足够多,但要解决线程空闲时的CPU消耗问题,当消息处理线程空闲时必须完全不占用CPU资源,比较好的方式是采用pipe管道通知消息处理线程进行消息处理,当无消息处理时,消息处理线程处于读管道阻塞状态,不占用CPU资源。 -
3、消息分类处理,尽量最短路径处理。
对网络消息进行分类,转发消息采用独立线程池处理,不需要经过管道,消息接收后直接转发;对大量客户端请求的数据提前进行预编码处理,采用RawServerData方式发送。
二、高性能服务架构-分层数据存储与处理
采用分级数据存储和处理技术,提高系统性能:
- 1、需要持久化的数据存入mysql数据库
mysql数据库封装请查看如下链接:
高性能服务器系列-第二章 Mysql C++ 封装 - 2、长期有效的数据加载到内存,加载时对数据进行Protobuf编码,按设定key存入map中,客户端请求数据时直接通过udp发生,避免多客户端多次查询重复编码。
Protobuf封装请查看如下链接:
高性能服务器系列-第三章 Protobuf封装(C++/C#/Go) - 3、需要周期失效的数据或需要进行搜索的数据加载到redis数据库,为提高redis处理性能,将redis内置到服务端主程序,作为服务端的一个线程运行,进程内存redis比独立运行redis性能提升10+倍,同时还能减少redis对网络的影响。
进程内置redis详细信息请查看如下链接:
高性能服务器系列-第一章 进程内置redis,性能提升11倍,QPS可达210万次/秒 - 4、客户端与服务器通信交互大数据时,采用滑动窗口的udp协议,滑窗大小自适应调节,传输效率和可靠性相对普通udp有较大提升
滑动窗口UDP详细信息请查看如下链接:
高性能服务器系列-第四章 滑动窗口UDP
三、示例工程编译及运行
1.目录说明
解压HighConcurrencyServer.zip,可得到如下目录结构:
HighConcurrencyClient: 测试客户(c#)
HighConcurrencyServer:测试服务端(c++)
ProtoGen:Protobuf编译目录
test.mp4 : 测试用视频文件
2.客户端编译
- 编译工具
Client_c#编译工具Microsoft Visual Studio Professional 2022
- 编译后运行HighConcurrencyClient.exe文件,界面如下:
3.服务端编译
- 编译环境
LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 8.5.2111
protobuf-3.13.0
gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4)
g++ (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4)
mysql Ver 8.0.24 for Linux on x86_64 (Source distribution)
redis-cli 7.0.4
cmake version 3.20.2
$PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/go/bin:/usr/local/lib/:/usr/local/bin/:/root/bin
$LD_LIBRARY_PATH :/usr/local/lib/:/tools/redis-7.0.4/deps/hiredis/
- 编译方法
代码如下(示例):
将文件上传至centos系统,以”/xxfw/HighConcurrencyServer/”目录为例
cd /xxfw/HighConcurrencyServer/
ls
make
``
编译完成后执行./HighConcurrencyServer.out
四、资源下载
- 获取示例工程资源
链接:https://pan.baidu.com/s/1icRltnzQHQzk-10B19pfXg?pwd=uzb7
提取码:uzb7 - 获取解压密码
- 链接:http://jiajiatong.store/target.html?id=2
- 上一章:
- 链接:高性能服务器系列-第四章 滑动窗口UDP