模块图.png

1. 日志模块

Log.h``Log.cpp
日志模块是每个框架必不可少的模块,不管从调试分析还是后面的数据统计分析都非常的重要。产品上线后的BUG定位、复现和解决都有不可或缺的作用。

支持流式日志输出、自定义格式日志输出、多日志多地点输出等功能
KIT_LOG_DEBUG([日志器]) << "输出内容";
KIT_LOG_FMT_DEBUG([日志器], "输出内容, %s", "this a log!");

支持时间、线程id、线程名称、日志级别、日志名称、文件名、行号等固定格式内容的灵活配置
默认配置:"[%p]%T<%f:%l>%T%d{%Y-%m-%d %H:%M:%S}%T%t(%tn)%T%c%T%g%T%m%n"

  1. %n-------换行符 '\n'
  2. %m-------日志内容
  3. %p-------level日志级别
  4. %r-------程序启动到现在的耗时
  5. %%-------输出一个'%'
  6. %t-------当前线程ID
  7. %T-------Tab
  8. %tn------当前线程名称
  9. %d-------日期和时间
  10. %f-------文件名
  11. %l-------行号
  12. %g-------日志器名字
  13. %c-------当前协程ID

框架功能模块总结 - 图2

2. 配置模块

config.h``config.cpp
能够实现内存配置<——->Yaml文件的相互转换。
支持基本数据类型、STL容器、自定义类型。(配置数据的序列化与反序列化)
支持配置变更触发回调通知的功能

  • 指定key值映射配置项"logs",指定数据存储类型std::set<LogDefine>(),还能添加对该条配置项的具体描述"logs configs" ```cpp kit_server::ConfigVar >::ptr g_log_defines = kit_server::Config::LookUp(“logs”, std::set(), “logs configs”);
  1. - 配置项key`logs`,配置了两个日志器,日志器名称分别是`root、system`,对日志器级别`level`、日志器格式`formatter`、日志输出器`appender`等也作出了配置指定
  2. ```cpp
  3. logs:
  4. - name: root
  5. level: debug
  6. formatter: "%d%T%m%n"
  7. appender:
  8. - type: FileLogAppender
  9. file: log1.txt
  10. - type: StdoutLogAppender
  11. - name: system
  12. level: info
  13. formatter: "%d%T%m%n"
  14. appender:
  15. - type: FileLogAppender
  16. file: log2.txt
  17. formatter: "[%p]%T%d%T%m%n"
  18. - type: StdoutLogAppender

框架功能模块总结 - 图3

3. 线程模块

thread.cpp``thread.h``mutex.h``mutex.cpp
通过pthread库自己进行了线程的一层,并对信号量Samaphore、互斥锁Mutex、读写锁RWMutex、自旋锁SpinMutex等也进行了封装。
直接使用C++11已经实现好的thread库也不是不行,只是该库没有对线程同步需要高频使用的这些工具有封装,于是选择自己封装。

在这里弱化线程的作用,只是将线程作为协程的容器

4. 协程模块

协程就是”用户级”的线程,也可以理解为”线程中的线程”。协程的切换比线程更加轻量,并发量也是线程的百千倍。协程切换只会涉及到用户态层面,仅仅不同代码序列间的切换,不会进入内核态;线程属于系统资源,线程的切换会从用户态进入到内核态,并且不同线程间的内核资源也会发生切换(内核栈等)。

采用对称协程。每一个线程中有一个母协程init_co_sp,其他协程的交互是基于这个母协程来实现
以同步的编程方式来实现异步操作
这一套协程依赖<ucontext.h>库文件API来实现的
框架功能模块总结 - 图4

5. 协程调度模块

分配有多个线程,一个线程又有分配多个协程。 N个线程对M个协程。支持协程在多个线程中切换,充分利用每一个线程

  1. schedule 是一个线程池,分配一组线程。
  2. schedule 是一个协程调度器,将协程指定到相应的线程去执行目标代码
    1. 方式一:协程随机选择一个空闲的任意的线程上执行
    2. 方式二:给协程指定一个线程去执行

框架功能模块总结 - 图5

5. IO协程调度模块

继承自协程调度器Schduler,封装了epoll操作,利用epoll实现IO的异步回调。(基本原理:当一个IO要请求读写的时候会陷入epoll中,把整个协程挂起,当数据回来时候通过epoll_wait带回相关的IO,再把协程唤醒去处理IO上的数据。)

通过epoll_wait还实现了定时器功能(精度ms级别),支持对定时器的添加/删除/刷新/重置时长/取消。支持一次性定时器、循坏定时器、条件定时器等。
框架功能模块总结 - 图6
框架功能模块总结 - 图7

6. HOOK 模块

HOOK系统底层和socket相关的API,socket IO相关的API,以及sleep类的API。本次开发的HOOK是线程级别的,可以在线程中选择是否开启HOOK。通过HOOK技术,可以使一些原本不具异步功能的API,展现出异步的性能,更加高效。

7. Socket模块

对socket API进行了一层封装,提供所有socket API功能。
统一封装了通信地址类Address,将IPv4,IPv6,Unix地址在API层面统一起来,屏蔽一些细节差异,能够使得API调用在逻辑上更加的平滑。并且提供域名、IP地址、网卡解析功能。
框架功能模块总结 - 图8
框架功能模块总结 - 图9

8. 数据序列与反序列化模块

是一个二进制序列化模块,提供对二进制数据的常用操作。读写基本数据类型int8_tint16_tint32_tint64_t等,还支持varintstd::string的读写。能够支持网络字节序转化、支持内存到文件相互读写等功能

9. TcpServer模块

基于Socket类封装了一个通用性的TCP类型服务器,提供基础的TCP API。可以快速绑定一个或多个地址,启动TCP服务,监听端口,accpet接收连接,处理和客户端通信等功能。具体业务功能依赖具体服务器实现,只需要继承该类就可以快速实现。
框架功能模块总结 - 图10

10. HTTP 模块

  • 使用Ragel(有限状态机模型),实现了对HTTP1.0/1.1简单协议和URI统一资源标识符的解析。
  • 通过SocketStream类再一次对Socket类进行一层封装,实现了HttpSession类(HTTP客户端连接)和HttpConnection类(HTTP服务器端连接)。提供了完整的HTTP客户端API请求功能,HTTP服务器API基础功能。
  • 基于TcpServer类实现了HttpServer类,能实现基本的报文收发,和服务分发功能。

SocketStream

框架功能模块总结 - 图11

HTTP Session

框架功能模块总结 - 图12

HTTP Connection

框架功能模块总结 - 图13

HTTP Connection Pool

框架功能模块总结 - 图14

HTTP Server

框架功能模块总结 - 图15

11. Servlet模块

仿照Java中servlet的概念,实现了一套Servlet接口,实现了服务分发类ServletDispatch,函数服务类FunctionServlet等。支持URI的精准匹配、模糊匹配等功能。和HTTP模块一起配合提供HTTP服务器的基础功能。
框架功能模块总结 - 图16