一、项目简介
- 项目使用线程池 + 阻塞/非阻塞SOCKET+ EPOLL(ET和LT均实现)+ 事件处理模式(Reactor与同步I/O模拟的Proactor均实现)。
- 访问服务器数据库实现WEB端用户注册、登录功能,可以请求服务器图片和视频资源。
二、项目模块
一、日志系统
(1)懒汉式单例模式创建日志系统。
(2)实现按天分类,超行分文件功能。
(3)日志分四级
- Debug:调试代码时使用。
- Warn:调试代码时使用。
- Info:报告系统当前的状态。
- Error:输出系统的错误信息。
(5)实现同步/异步写入方式。
- 同步写入方式:利用互斥锁实现工作线程互斥地访问日志文件,并写入日志内容。
- 异步写入方式:将其抽象为生产者-消费者模型,将工作线程产生的日志内容存入缓冲区,写日志线程从缓冲区中取出内容,写入日志。缓冲区是循环数组实现的队列,利用互斥锁实现线程互斥地访问缓冲区,利用条件变量实现“生产”与“消费”之间的同步。同时利用互斥锁实现写线程互斥地访问日志文件,并写入日志内容。
二、数据库连接池
(1)懒汉式单例模式创建数据库连接池。
(2)链表实现数据库连接池。
(3)数据库连接的获取与释放通过RAII机制封装,避免手动释放。
(4)利用互斥锁实现工作线程互斥地访问数据库连接池,利用信号量实现“获取”与“释放”之间的同步,信号量初始化为最大连接数。
三、HTTP
(1)使用状态机解析HTTP请求报文,从状态机负责读取报文的一行,主状态机负责对该行数据进行解析。
(2)仅支持HTTP1.1,支持解析GET和POST请求。
四、定时器处理非活动连接
(1)统一事件源。捕捉定时器信号与程序结束信号,信号处理函数往管道的写端写入信号值,主循环使用I/O复用系统调用监听管道读端的可读事件与其他文件描述符,从而实现统一处理。设置超时时间15s,如果检测到超时信号,就删除非活动连接在EPOLL上的注册事件、关闭文件描述符等,释放完连接资源后,重新开始定时。如果文件描述符发生了数据的交换,调整该定时器的位置,定时器重新计时。
(2)带头尾结点的升序双向链表管理定时器。
五、线程池
(1)链表实现任务队列。
(2)利用互斥锁实现工作线程互斥地访问任务队列(存放HTTP连接),利用信号量实现“生产”与“消费”之间的同步,信号量初始化为0。
(3)子线程做线程分离,不需要主线程阻塞地回收资源。
三、项目框架
四、压力测试
1 vCPU 2 GiB (I/O优化) ecs.n4.small 1Mbps
1. Reactor + LT + ET
并发连接总数为100,访问服务器时间为5s,所有访问均成功。
2. Proeactor + LT + ET
并发连接总数为100,访问服务器时间为5s,所有访问均成功。
五、各模块记录
【C++实现HTTP服务器项目记录】日志系统
【C++实现HTTP服务器项目记录】数据库连接池
【C++实现HTTP服务器项目记录】线程同步类
【C++实现HTTP服务器项目记录】线程池
【C++实现HTTP服务器项目记录】定时器处理非活动连接
【C++实现HTTP服务器项目记录】HTTP报文处理
【C++实现HTTP服务器项目记录】服务器