gitee:基于c++的高性能服务器
高性能web服务器
- **项目介绍:**基于Linux操作系统,利用多线程开发,网络编程等技术,构建的一个高并发服务器,解决了大文件传输和连接量负载的问题。经过Webbench压力测试,能够支持上万的并发连接量。
- **负责内容:**使用半同步/半反应堆线程池、epoll、非阻塞socket、事件处理的并发模型(同步I/O模拟proactor模式);基于状态转换机对HTTP的GET与POST请求处理;定时器处理非活动连接;数据库连接池;同步/异步日志系统;Webbench压力测试。
1 主程序
- 半同步半反应堆模型(同步I/O实现的Proactor模型)
- 主线程充当异步线程,负责监听、读写、放到任务队列
- 子线程(线程池)充当同步线程,负责处理逻辑
- 好处
- IO操作耗时,子线程快速处理逻辑后,还需要处理其他任务。
2 锁
- 信号量
- 互斥量
- 条件变量
3 线程池
-
组件
-
管理线程
- 线程多了,回收
- 线程少了,销毁
-
工作线程
- 通过work()函数完成逻辑处理。
- 当任务队列有数据时才取出来(信号量来判断)
-
任务队列
- 每次处理任务队列需要加锁
-
-
同步I/O模拟proactor模式
-
半同步/半反应堆并发模式
4 主从状态机解析HTTP请求
-
http报文处理流程
- 浏览器发出http连接请求,主线程创建http对象接收请求并将所有数据读入对应buffer,将该对象插入任务队列,工作线程从任务队列中取出一个任务进行处理。
- 工作线程取出任务,调用**process_read()**函数,通过主、从状态机对请求报文进行解析
- 解析完之后,跳转**do_request()函数生成响应报文,通过process_write()**写入buffer,返回给浏览器端
-
主状态机
- 主状态机初始状态是CHECK_STATE_REQUESTLINE
- process:
- process_read:处理http请求
- 从状态机通过parse_lineI()读取buffer中的数据
- process_request_line:处理请求行
- process_request_header:处理请求头
- do_request
- process_request_content:处理请求内容
- do_request
- process_write:处理http响应
- 响应头数据
- 文件数据
- 通过
io
向量机制iovec
,iovec[0]=响应头数据,iovec[1]=文件数据 - write:
- 循环发送
- process_read:处理http请求
- do_request:
- GET:直接拼接file_path,mmap提高效率
- POST:CGI登录注册校验,mmap提高效率
-
从状态机
- 负责读取buffer中的数据,将每行数据末尾的\r\n置为\0\0,并更新从状态机在buffer中读取的位置m_checked_idx,以此来驱动主状态机解析
- parse_line
5 定时器处理非活动连接
利用alarm
函数周期性地触发SIGALRM
信号,信号处理函数利用管道通知主循环,主循环接收到该信号后对升序链表上所有定时器进行处理,若该段时间内没有交换数据,则将该连接关闭,释放所占用的资源。
- 难点问题
- 信号处理时会屏蔽该信号,若信号处理函数逻辑处理太长,会屏蔽太久,因此信号处理函数仅仅发送信号通知程序主循环,将信号对应的处理逻辑放在程序主循环中,由主循环执行信号对应的逻辑代码。
6 日志系统
-
由服务器自动创建,并记录运行状态,错误信息,访问数据的文件
-
同步日志。日志写入函数与工作线程串行执行,由于涉及到I/O操作,当单条日志比较大的时候,同步模式会阻塞整个处理流程,服务器所能处理的并发能力将有所下降,尤其是在峰值的时候,写日志可能成为系统的瓶颈。
-
**异步日志。**将所写的日志内容先存入阻塞队列,写线程从阻塞队列中取出内容,写入日志
-
内容
- 单例模式
- 生产者消费者模型(条件变量),主线程生产,子线程消费
- 任务队列:push表示生产者,pop表示消费者