上篇介绍了一个简单的 UDP 服务框架, 但是面对海量的请求, 同步框架显然有点力不从心. 于是在我接手好友系统的接口服务的时候, 就采用了一个强大的异步框架 --MCP 框架.
MCP 框架是一个多进程异步框架, 支持 UDP,TCP 和 http, 结构很灵活, 可以根据需要将各组件像搭积木一样组装. 下面是 MCP 最基础的进程结构. 分为 3 种进程: CCD,MCD 和 DCC.
CCD 是面向客户端的进程, 是服务的入口, 负责处理前端的请求, 维护连接, 收发数据, 并向 MCD 转发. 其内部使用线程池实现对 TCP 请求的 listen 和 accept. 服务器内部进程之间使用 flow(实际上是一个数字)来表示连接, 因此 CCD 负责维护前端请求句柄和 flow 之间的映射关系. CCD 一般根据端口和协议设置多个.
DCC 是面向后端的进程, 负责向其他服务发出请求. 使用跟 CCD 类似实现方法, 只是面向的是服务器. 在经过协程改造的 MCP 框架中, DCC 被去掉了, 因为 MCD 通过协程就可以实现与后端的交互了. DCC 跟后端的连接一般采用长连接, 避免频繁创建和释放连接导致大量 TIME_WAIT 的情况.
MCD 是服务器的核心进程, 负责处理业务逻辑, 通过 epoll 和回调函数实现异步.
进程之间通过 MQ 进行通信, MQ 采用共享内存队列传输数据, 而通过管道传输读写信号. 如下图所示, 进程首先把数据写入队列, 当队列中的数据达到一定长度 (避免每个请求都读取数据) 时, MQ 会通过管道传输一个字符. MQ 的使用者只要通过 epoll 监听管道句柄, 就可以及时地获得读写信号.
了解了 MCP 的基本原理, 就可以根据业务的需要进程个性化的定制. 例如因为 MCD 单进程可能有性能瓶颈, 我们对其进行了扩展, 改造成多 MCD 进程版本. 如图所示, MCD 后端派生出多个 SUBMCD 进程, SUBMCD 进程负责处理真正的业务逻辑; 而 MCD 进程退化成一个业务分发的程序, 同时负责一些公共的业务逻辑, 例如负责管理全局哈希表数据的超时清理(定期扫描超时节点, 表太大的情况可以分次扫描, 只要保持好扫描位置信息即可).
SUBMCD 直接跟 CCD 和 DCC 通信(图中省略了 SUBMCD 和 CCD 之间的 MQ), 通过配置文件设置, 在服务初始化的时候就在各个需要通信的进程间创建好共享内存 MQ. 这样可以避免 MCD 成为通信瓶颈.
另外还派生出一个 MONITOR 进程, 负责日志的收集和输出, 还可以做其他一些耗时的操作, 避免业务进程阻塞.
MCP 框架兼有功能强大和性能卓越的优点. 具体压测数据不太记得, 在一个数据包转发服务中, QPS 也在 30W+. 在使用上, 有一定的学习成本, 但是适用面非常广, 可以说一个框架走天下.
来源: https://www.cnblogs.com/htkfsy/p/11853467.html