命运的局限尽可永在,
不屈的挑战却不可须臾或缺。
— 史铁生 —
项目地址在这里: https://gitee.com/penggli_2_0/TcpServer
仿mudou的高并发服务器
- 1 项目介绍
- 2 模块组成
- 3 实现时间轮模块
-
- 3.1 设计思想
- 3.2 定时任务类
- 3.3 TimeWheel时间轮类
1 项目介绍
这是一个仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器项目。是对基于事件驱动Reactor模型的改良版!
通过实现的高并发服务器组件,可以简洁快速的完成⼀个⾼性能的服务器搭建。并且,通过组件内提供的不同应⽤层协议⽀持,也可以快速完成⼀个高性能应用服务器的搭建(当前为了便于项目的演⽰,项目中提供HTTP协议组件的支持)。在这里,要明确的是咱们要实现的是⼀个高并发服务器组件,因此当前的项目中并不包含实际的业务内容!
实现的是主从Reactor模型服务器!分为两个部分:主Reactor 与 子Reactor:
One Thread One Loop的思想就是把所有的操作都放到⼀个线程中进行,⼀个线程对应⼀个事件处理的循环。
当前实现中,因为并不确定组件使用者的意向,因此不提供业务层工作线程池的实现,只实现主从Reactor,而Worker工作线程池,可由组件库的使用者的需要自行决定是否使用和实现。
2 模块组成
在这项目中我们需要两大模块:
SERVER模块就是对所有的连接以及线程进⾏管理,让它们各司其职,在合适的时候做合适的事,最终完成高性能服务器组件的实现。具体的管理也分为三个方面:
- 监听连接管理:对监听连接进⾏管理。
- 通信连接管理:对通信连接进⾏管理。
- 超时连接管理:对超时连接进⾏管理。
基于以上的管理思想,将这个模块进⾏细致的划分⼜可以划分为以下多个子模块:
Buffer模块: Buffer模块是⼀个缓冲区模块,用于实现通信中用户态的接收缓冲区和发送缓冲区功能。先前的文章中我们使用string模拟过缓冲区,这里需要进行丰富功能!
Socket模块: Socket模块是对套接字操作封装的⼀个模块,主要实现的socket的各项操作。
Channel模块: Channel模块是对⼀个描述符需要进⾏的IO事件管理的模块,实现对描述符可读,可写,错误等事件的管理操作,以及Poller模块对描述符进⾏IO事件监控就绪后,根据不同的事件,回调不同的处理函数功能。
Connection模块: Connection模块是对Buffer模块,Socket模块,Channel模块的⼀个整体封装,实现了对⼀个通信套接字的整体的管理,每⼀个进⾏数据通信的套接字(也就是accept获取到的新连接)都会使用Connection进⾏管理。
Acceptor模块: Acceptor模块是对Socket模块,Channel模块的⼀个整体封装,实现了对⼀个监听套接字的整体的管理。
TimerQueue模块: TimerQueue模块是实现固定时间定时任务的模块,可以理解就是要给定时任务管理器,向定时任务管理器中添加⼀个任务,任务将在固定时间后被执行,同时也可以通过刷新定时任务来延迟任务的执行。这个模块主要是对Connection对象的⽣命周期管理,对非活跃连接进⾏超时后的释放功能
Poller模块: Poller模块是对多路转接epoll进⾏封装的⼀个模块,主要实现epoll的IO事件添加,修改,移除,获取活跃连接功能。
EventLoop模块: EventLoop模块可以理解就是我们上边所说的Reactor模块,进行事件派发。它是对Poller模块,TimerQueue模块,Socket模块的⼀个整体封装,进⾏所有描述符的事件监控。EventLoop模块必然是⼀个对象对应⼀个线程的模块,线程内部的目的就是运行EventLoop的启动函数。
TcpServer模块: 这个模块是⼀个整体Tcp服务器模块的封装,内部封装了Acceptor模块,EventLoopThreadPool模块。
3 实现时间轮模块
3.1 设计思想
时间轮思想:时间轮的思想来源于钟表,如果我们定了⼀个3点钟的闹铃,则当时针⾛到3的时候,就代表时间到了。
同样的道理,如果我们定义了⼀个数组,并且有⼀个指针,指向数组起始位置,这个指针每秒钟向后⾛动⼀步,⾛到哪⾥,则代表哪⾥的任务该被执⾏了,那么如果我们想要定⼀个3s后的任务,则只需要将任务添加到tick+3位置,则每秒中⾛⼀步,三秒钟后tick⾛到对应位置,这时候执⾏对应位置的任务即可。
3.2 定时任务类
这里先对时间轮模块进行一个简单实现: 首先需要设计一个TimeTask 定时任务类
- 任务ID uint64_t _id :用来标识任务
- 超时时间 uint32_t _timeout
- 回调任务 _task_cb void()类型
- 释放操作 _release :用于删除TimeWheel保存的定时器对象信息
- 构造函数
- 析构函数 :析构的时候执行定时任务,这样就可以通过释放空间实现定时实现!
- SetRelease函数设置 _release 任务
- DelayTime函数 返回延迟时间
评论前必须登录!
注册