Git Product home page Git Product logo

webserver's Introduction

Webserver

Build Status license

Introduction

本项目实现了一个基于Reactor模式的Web服务器,传输层采用I/O多路复用技术管理TCP连接,同时在应用层搭建了一个http服务器,用于响应Get请求,实现静态资源的访问。最后,本项目还可以在Web服务器的基础上自由扩展应用层服务。

Enjoy it,it's gonna be really fun!!!

Environment

  • OS: Ubuntu 16.04
  • Complier: g++ 5.4.0
  • Tools: CMake/VScode

Technical points

  • 基于Reactor模式构建网络服务器,编程风格偏向面向过程
  • 采用非阻塞IO,IO复用模式默认是ET,可在编译前通过指定参数切换为LT模式,通过编译期确定工作模式,可以减少运行期不断判断条件造成的负担
  • 线程间的工作模式: 主线程负责Accept请求,然后采用Round-bin分发的方式异步调用其他线程去管理请求端的IO事件
  • 利用AsyncWaker类(使用eventfd)实现线程间的异步唤醒
  • 实现LockFreeQueue用于任务的异步添加与移除,代替了常规的互斥锁管理临界区的方式 [这里的Lock free queue并没有解决ABA问题,但是针对这里单生产者单消费者模型,不会发生ABA问题]
  • 实现环形缓冲区作为Tcp读取数据和写入数据的缓冲类,使得数据被读取之后不需要移动其余元素的位置来在尾部腾出空间,针对环形缓冲区读或者写空间可能会出现不连续的情况,在Read和Write的处理上,使用了readv和writev系统调用读取不连续的内存(只需要一次系统调用),解决了系统调用和拷贝带来的开销
  • 采用智能指针管理对象的资源
  • 加入了TcpConnection对象的回收机制,用于回收Tcp Connection对象中的资源,避免多次创建的开销
  • ......

Develop and Fix List

  • 2019-12-19 Dev: 基本框架的实现
  • 2020-03-04 Dev: 临界区的保护机制增加自旋锁,用于与互斥锁做性能对比
  • 2020-03-14 Dev: 实现了Epoll ET模式 循环处理Accept、Read和Write事件
  • 2020-03-26 Dev: 定义宏使得WebServer编译时确定Epoll的工作模式(ET/LT)!通过宏定义切换,方便压测对比实验
  • 2020-04-04 Important Dev: 针对单生产者单消费者模型的特点,临界区的保护机制增加了Lockfree queue,用于与互斥锁做性能对比!目前的Lockfree queue,暂未解决CAS问题,后期会利用Hazard pointer解决。
  • 2020-04-10 Important Dev: 针对muduo原本的Buffer类实现内部挪滕,增加数据拷贝开销的问题,实现了环形缓冲区类!设计的RingBuffer类的接口与Muduo原本的vector<char>接口保持一致,目前使用编译期宏定义的方式切换,方便之后做压测对比。之后会考虑设计一个KBuffer纯虚类,然后将RingBuffer和Muduo的Buffer作为作为KBuffer子类,利用C++多态,使用基类的指针指向子类的对象,这样来切换真正所使用的Buffer类.
  • 2020-04-22 Dev: 针对每一个新来的连接都会创建一个Tcp Connection,连接断开后Tcp Connection的资源又会被全部回收的问题,采取了Tcp Connection的回收机制,使用vector存储Tcp Connection,再次新来连接时,只用修改Tcp Connection管理的连接对象,即可实现Tcp Connection的重用

Todo list

Update in 20-04-14

  • (Before ...) 添加tcp易产生粘包的解决方案
  • (Before ...) 查查负载均衡模式,与round-bin作对比
  • (Before ...) 异步唤醒机制采用管道 用于 与eventfd性能对比
  • (Before ...) 多线程日志
  • (Before ...) 实现定时器功能 (先小根堆试试,毕竟直接调库,然后写红黑树,可以参照Nginx,最后实现下淘宝Tengine中的四叉最小堆)

Model Architecture

本服务器采用了事件循环 + 非阻塞IO的主题架构,通过事件驱动和事件回调来实现业务逻辑。事件循环用于做事件通知,如果有新的连接被Accept,则把新连接的socket对象的管理工作转交给其他线程。模型的整体架构如下图所示,模型的架构发展过程可见History.

模型架构

Class Structure

模型架构

Server Performance

  • 使用Ringbuffer减少数据的拷贝拷贝次数,在一分钟内测试1000个并发连接,使用RingBuffer使得QPS提升10%

Simple Comparison

压力测试使用了Webench,来自linya,谢谢!!!压力测试的方法也来自linya,再次谢谢!!!

这里先做一个简要的对比,后期慢慢的详细对比,写一个更完整的文案

QPS(响应消息体为短字符串) QPS(响应消息体为长字符串)
Muduo 115111 ---
Mine 104644 ---

这里只对长连接进行测试,线程模型是1个主线程+3个IO线程,为了对比线性Buffer和RingBuffer,使用了不同长度的响应消息体(长字符串对应5000个字符,短消息体对应12个字符)。下图是响应消息体为短字符串的测试结果(长字符还未对比)

  • My Webserver 响应消息体为短字符串时测试结果和CPU负载

自己服务器的QPS数据

img

最近提炼了一下代码,MyWebserver的并发量有了很大提升,测试结果如下

自己服务器的QPS数据Improvement

  • Muduo 响应消息体为短字符串时测试结果和CPU负载

Muduo的QPS数据

img

Analysis

  • 测试结果表明,本项目所实现的服务器与muduo性能相近!
  • 在搭建这个服务器的过程中,我的基本框架还有代码的风格(甚至一些直接的代码都是来自Muduo那本书)!但是呢,在慢慢搭建的过程中,我修改了Epoll的工作模式(LT->ET),改进了缓冲区Buffer为环形缓冲区,还有线程间的异步任务调配我也为了避免锁的开销,改成了无锁结构,相比在这些做工作之前的服务器,我这个版本是有很大的性能提升的,这也是Muduo所没有的。

webserver's People

Contributors

importcpp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

webserver's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.