8000 GitHub - HumbleHunger/Dserver
[go: up one dir, main page]

Skip to content

HumbleHunger/Dserver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 

Repository files navigation

介绍

Dserver是一个运行于 Linux 平台下的基于Reactor模式的多线程网络库,使用 C++11 进行编写,支持 TCP协议。

网络核心库使用了one loop per thread + 多线程模型,也就是基于事件驱动的多reactor模型。具体来讲,在网络IO模型上,使用了非阻塞IO + IO多路复用的组合。在并发模型上,设置了多个处理网络IO的线程,同时通过启用内核的reuseport套接字选项在每个IO线程中的epoll中加入一个监听套接字来实现一个多点的accept。用户只需在网络库中注册一个回调函数处理业务逻辑即可实现一个高性能的服务器。除了网络核心库之外,还提供了在编写网络程序中常用的一些组件,比如计算线程池和异步的日志库,以满足用户在不同场景下的需求。

技术点

并发模型

  • 使用one-loop-per-thread + thread-pool 模型,可使IO与计算任务分离。
  • 使用epoll条件触发的IO多路复用技术。
  • 使用socket的SO_REUSEADDR,SO_REUSEPORT选项,创建多个socket监听同一端口,并将每个socket分别加入到一个IO线程的epoll监听队列中提供服务。
  • 使用eventfd + vector实现IO线程loop间通信,可以很灵活地在线程间调配负载。

缓冲区

  • 为每个连接维护用户态InputBuffer与Ouputbuffer,以保证在非阻塞IO下的可用性。
  • 使用readv系统调用结合栈上建立的临时缓冲区,提高每次读取的数据量和减少read系统调用提高性能的同时避免了每个连接的初始buffer过大造成内存浪费。

对象生命周期管理

  • 所有内存分配操作使用智能指针,避免了内存泄露。
  • 使用 RAII 机制+智能指针将文件描述符封装成对象进行生命周期控制,避免出现文件描述符的读写操作出现串话。

处理定时事件

  • 使用 Linux 内核提供的 timerfd 将定时事件融入IO多路复用机制和 IO 事件统一处理。
  • 使用以红黑树为底层实现的std::set作为时间轮的数据结构,并在key上设法区分到期时间相同的定时器,避免使用不常见的multiset。

日志

  • 实现基于多缓冲区技术的异步日志库。
  • 使用单独的日志线程记录日志,通过多缓冲区与IO线程和计算线程通信。避免在IO和计算线程中进行磁盘IO,使磁盘IO与计算相互重叠,降低请求处理延迟。

其他

  • 使用gettid系统调用返回pid_t类型数据唯一标识线程,保证多个进程间的线程id唯一性,并使用__thread关键字为每个线程缓存pid_t,减小系统调用次数,提高性能。
  • 在全局预留一个文件描述符,以在当打开的文件描述符超过系统限制无法accept时可使用此文件描述符通知对端无法服务,并解决busy loop问题。

压测

运行环境

在这里插入图片描述

Dserver开启6个IO线程

测试工具为 webbench1.5,测试命令如下(100个客户端持续访问15秒)。

./webbench -c 100 -t 15 http://127.0.0.1:8000/

在这里插入图片描述

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0