C++11实现的高性能静态服务器

1 篇文章 0 订阅
1 篇文章 0 订阅

一、概述

以IO多路复用为核心,采取单Reactor模式,接受处理请求和发送响应(目前仅能处理静态文件请求)。用时间堆管理的定时器来处理超时链接。

项目大概2000行代码,只是我看完《Linux高性能服务器》来实践的项目,性能肯定和muduo这种网络库没法比,算是新手上路项目吧。最主要的逻辑在HttpServer部分,另外复杂点就是定时器的部分。通过了压测并且部署到了实际服务器上,有什么问题欢迎留言或者私信交流。

项目地址:https://github.com/MisakiOfScut/SingHttpServer

二、运行

mkdir build && cd build
cmake ..
make
./main

#由于设置成了守护进程,所以需要用kill命令去结束运行
kill -SIGINT `pid` #或者把main函数里面skeleton_daemon()注释掉

三、整体架构

采取单Reactor模式,一个主线程多个工作线程,主线程负责监听和接受链接,工作线程负责处理请求和读写任务。当fd有可读/写事件时,主线程将可调用对象放入工作队列,工作线程通过竞争条件获取任务执行。

features:

  • 使用 线程池 + epoll水平触发 +Reactor事件处理模式的并发模型
  • 使用状态机解析HTTP请求,支持解析GET请求
  • 支持HTTP长连接,使用最小堆管理的定时器处理超时链接
  • Webbench压力测试验证可以实现上万的并发链接的数据交换

更多细节:https://github.com/MisakiOfScut/SingHttpServer/blob/main/docs/intro.md

四、测试

准备

  1. 原版的Webbench是不支持长连接的,需要改写,我用了https://github.com/linyacool/WebBench这个大佬改写的
  2. ulimit查看系统允许打开的文件描述符、进程数量上限、core文件大小,我用的Ubuntu18.04默认值是不够的,直接改了个10万的文件描述符和进程数量无限制;不然用webbench并发数一多就会Resources temporarily unavailable

测试

先简单测测,可以用浏览器或者curl,看看功能是否正常;复杂一点可以用wireshark抓包看看生成的报文是否正确;这里就测测复杂页面、错误请求、传输大文件等功能是否正常

压力测试

多线程编程,很多问题一并发就凸显出来了,这也是最折磨人的部分,如果你的设计有问题不能保证线程安全,比如对容器不加锁并发地读写,那到一定并发数量后就会出现内存泄漏的问题。

并发测试不要连续进行,测试完用netstat -t可以查看系统的TCP链接,你会发现有很多TIME_WAIT状态的链接,这样会对下次测试的结果造成影响。

通过回环地址测试的,看了乐乎就好

长连接10000并发10s
短链接10000并发10s

五、有待改进

架构

最大能提升的地方是架构,项目采用单Reactor多线程模型,存在两个问题:

  1. 线程需要对工作队列频繁加锁,这是一个很浪费时间的操作
  2. 一个线程一次只能处理一个client的请求,当请求数量越来越多时,工作队列会堆积越来越多的任务对象,服务器对客户端的响应将会变慢;通过增加线程数并不能解决这个问题因为如果多于cpu核数的话线程间的切换也会限制性能

因此有主从Reactor模型来改进这个问题,主Reactor只负责监听listenfd,有链接时accept然后派给从Reactor,从Reactor有自己的epoll_wait来处理IO,这样一个线程可以处理多个请求。感兴趣的可以去看muduo

文件发送

目前文件发送采用了用mmap文件映射到内存然后往socket写的方式,需要DMA先把文件从磁盘拷贝到内核(第一次cp),进程通过内存映射能访问文件并把文件写到socket的发送缓冲区(第二次cp),内核把socket的数据发往网卡(第三次cp),一共需要三次copy

如果采用sendfile,那么需要DMA先把文件从磁盘拷贝到内核(第一次cp),内核直接将数据发到网卡(二次cp),cp次数更少

功能

  1. 日志功能(可以用syslog,但是自己写一个肯定更加分)
  2. 解析POST请求

编译

把文件置于一个目录下,makelist会好写点

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值