Skip to content

Greetlist/xgt_trader_example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

86 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

module

  1. epoll server [Main Epoll + Logic Epoll]
  2. [Ring | Vec] buffer [Read | Write]
  3. TcpConnection [Client]

src

  1. buffer 每个tcp连接的用户层缓冲buffer,会从socket buffer里面拷贝数据到用户层,后面TcpConnection类会来取数据 如何取解析buffer里面的流数据,也是TcpConnection需要做的事情
  2. common 错误码定义、一些全局变量
  3. epoll_server epoll总的实现,包括对TcpConnection类的管理
  4. interface 客户端的实现,包括组装请求,发送请求,获取服务端的相应并调用相关的回调函数
  5. logger 日志收集,开额外线程写日志文件
  6. queue multi-producer + multi-consumer lock-free queue,用来存用户的请求,工作线程消费请求
  7. tcp tcp连接的实现,需要实现解析tcp流的函数
  8. handler 处理解析出来的请求,并把结果回写到socket里面

graph

架构图

  1. 每当有一个连接过来,主要listen的epoll会accept这个连接,并且把socket fd 以Round Robin的形式转发到每个线程的epoll里面,所以MainEpoll只用来处理连接

  2. Clild Thread Epoll的作用是用来监听socket fd上面的可写事件的发生,如果有可写 事件,那么就会从socket fd里面读取数据到TcpConnection里面的ReadBuffer里面,然后再 尝试把Buffer里面的stream数据按照协议解析出来。解析出来的请求会放到MPMC Queue里面。

  3. 其他真实处理请求的线程会尝试从MPMC Queue里面取请求出来,并实例化Handler来处理 请求,并回写回复。

为什么这样设计

  1. 不想让接收连接的主线程堵塞。
  2. 对于接收数据的线程来说:如果一个请求的处理时间很长[代码有问题或者类似于查询持仓这样的请求],那么会影响后面的请求处理,所以接收数据的线程只接收并尝试解析数据,并把请求放到请求队列里面
  3. 对于真实处理请求的线程:这些线程就可以从队列里面拿请求出来,慢慢处理。但是也不能太慢,太慢的话,队列里面的消息处理不完,会让每个TcpConnection的ReadBuffer膨胀,在高压情况下(CPU全部打满),每个TCP连接的ReadBuffer会达到125MB以上,进而可能会OOM掉.(在服务很多连接的时候)

性能测试

在CPU全部打满、正确处理完所有请求、正确回写所有请求的情况下,QPS大概是13-15W/s. 启动了10个client。全部都在一台机器上测试,如果分机器测试,QPS应该会更高一些.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published