1. 背景
框架背景见上篇。
网络框架的设计参考了python的异步框架twisted。
笔者对同步和异步性能的认识源于还在爱立信的两个项目,第一个项目是同步的,2-3k的tps,性能压不上去,客户端您随便加压力,我服务端就不理你,就这种;第二个项目是异步的,1w的tps,实验室环境在瑞典,一直没机会玩玩。但笔者因为是研发中心支持,在一线人员配合下能直接登录上生成环境,最惨烈的一次是阿三的服务器,就看着内存一直在涨,5分钟一挂…您没听错,就是5分钟一挂,提单的严重级别是中级,要放国内早爆了…除了升级扩容别无他法。当时就感叹,异步没有压不爆的机器。
鉴于此,笔者当时看了挺多异步的设计,twisted是印象最深的一个。接着用python写一个自己的python测试框架pythontest, 但一直都没派上用场。framework-nd的网络模型其实就是pythontest的c++版。但笔者的python仅限于东拼西凑,答不出所以然。
2. 设计
写网络框架的人,应该都看过《unix网络编程》,也知道平台差异性。笔者选用libevent1(2的设计比较复杂,没用)去封装平台差异,socket的读写按边缘触发处理。
- Reactor 独占一线程,跑event_base_dispatch。提供接口,监听socket的事件。
- TcpServer 新建监听端口,将新连接和上层处理逻辑处理初始化成SocketConnection。
- SocketConnection 维护已连接的socket,负责异步读写socket,读写各维护一队列。并将网络事件上报给Protocol。
- IProtocol 负责TcpServer的配置和处理网络事件。其主要从网络流(SocketConnection的读缓存)中解析出消息体,或将消息体写入SocketConnection的写缓存。
- TcpClient负责connect之前的逻辑,connect之后生成SocketConnection,逻辑交由SocketConnection维护,连接断开后负责重连。TcpClient设想支持多个连接,但是没有这样的需求就没实现。
以上类除了Reactor,其他类初始化参数均包含一线程组引用,按调试需要,可以用不同的线程组初始化,也可以用相同的线程组初始化。通知事件跑在原线程,事件的处理跑在线程组socket fd对应线程。
恩, 好像完了?大的部分好像真的完了,但是细节都在代码里。例如做了流控,即接收缓存在高水位,则不再从socket读取,滑动窗口协议会导致客户端不再发送,知道接收队列被处理至正常水平,防止服务器被输入压垮了。
另外,这玩意还是很考验多线程调试技巧的。
3. 举个例子吧
EchoServer是这么启的,telnetServer是管理端口。
1 | Processor::BoostProcessor processor("NetProcessor", 4); |
4. 后记
putty-nd同步session数据到Google Drive,需要启一HttpServer配合Google账号的验证,对这套框架略有修改。加力之后代码段增加得不多,还是很小巧的。