从零开始一个http服务器(六)-多路复用和压力测试
从零开始一个http服务器(六)-多路复用和压力测试
代码地址 : https://github.com/flamedancer/cserver
git checkout step6
运行:
make clean && make && ./myserver.out
测试
浏览器打开 http://127.0.0.1:9734/action/show_date
多路复用和压力测试
- 多路复用
- 压力测试
多路复用
多路复用意义
到目前为止,服务器的基本业务功能我们是实现了。但好的服务器不止要能完成业务逻辑,没有好的执行效率和高的并发数,根本无法在生成环境中使用。现在我们开始考虑优化我们的服务器使之接近能应付生成环境的水平。
提高服务器性能有很多方法,我们先来考虑第一个改进,采用多路复用。
我们之前的程序,当server_sockfd accpet 一个 client_sockfd 后,程序read等待client_sockfd发来的数据,
然后再解析request。然而如果client_sockfd迟迟不发送数据,我们的程序就卡在read上,后面客户端发的请求全部无法响应了。"多路复用"可以简单理解为“谁有事执行谁”, 运用多路复用可以解决上面这个问题。当accpet 一个 client_sockfd后,将client_sockfd放在一个事件池中,直到事件池察觉这个client_sockfd可以read了,才对这个client_sockfd进行read操作。
步骤可以总结为
1. 创建事件池
2. 创建事件,将事件加入到事件池
3. 事件池监测所有事件,若有事件被触发,执行被触发事件的后续逻辑
多路复用封装
由于mac和linux所用的事件复用库不一样,mac下为kqueue,linux下为epoll,为了兼容性,我们封装了一个事件库poll.h。
主要结构体和函数为:
1 . 事件池结构体
struct PollEvent {
int epfd;
void * eventItems;
int maxEventCnt;
};
epfd 为事件池句柄
eventItems 当前被触发的事件数组
maxEventCnt 为最大可容纳被触发事件数
2 . 添加事件
void updateEvents(struct PollEvent* event, int fd, int eventFLags, int modify, void* udata);
event 事件池
fd 需要监听的句柄
eventFLags 需要监听fd的什么事件 我们初略的只定义读和写事件
#define Readtrigger 1
#define Writetrigger 2
#define Emptytrigger 0
modify 如果为 0 时 为fd添加eventFLags事件, 为1时 修改fd的事件为eventFLags
3. 监听事件池
当有事件被触发时返回被触发的事件数,被触发的事件放在event->eventItems里
int doPoll(struct PollEvent* event);
修改main函数
- 创建事件池
- 将sever_socket read 事件加入事件池
- 监听事件池
- 当事件池发现有触发的事件时,判断触发的事件类型:
- 若为 sever_socket read 事件,创建client_socket, 将client_socket read 事件加入事件池
- 若为 client_socket read 事件, 解析reques,生成 response,并将client_socket write 事件加入事件池
- 若为 client_socket write 事件, 将response写入client_socket,关闭client_socket(事件池会清理关闭了的fd)
- 继续第4步
压力测试
ab -c 5 -n 2000 http://127.0.0.1:9734/action/show_date
Concurrency Level: 5
Time taken for tests: 14.089 seconds
Complete requests: 2000
Failed requests: 0
Total transferred: 218000 bytes
HTML transferred: 58000 bytes
Requests per second: 141.95 [#/sec] (mean)
Time per request: 35.223 [ms] (mean)
Time per request: 7.045 [ms] (mean, across all concurrent requests)
Transfer rate: 15.11 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 10 35 14.6 38 83
Waiting: 10 35 14.6 38 83
Total: 10 35 14.6 39 83
我们用ab测试5并发总共2000个/show_date请求,可以看到 平均每个请求花费35毫秒。下一节我们将采用线程池技术来继续改进我们的执行效率。
从零开始一个http服务器(六)-多路复用和压力测试的更多相关文章
- 从零开始一个http服务器(五)-模拟cgi
从零开始一个http服务器-模拟cgi(五) 代码地址 : https://github.com/flamedancer/cserver git checkout step5 运行: make cle ...
- 从零开始一个http服务器(三)-返回response 构造
从零开始一个http服务器(三) 代码地址 : https://github.com/flamedancer/cserver git checkout step3 运行: gcc request.h ...
- 从零开始一个http服务器(二)-请求request解析
从零开始一个http服务器 (二) 代码地址 : https://github.com/flamedancer/cserver git checkout step2 解析http request 观察 ...
- 从零开始一个http服务器(一)-开始
从零开始一个http服务器 (一) 代码地址 : https://github.com/flamedancer/cserver git checkout step1 一个简单的socket serve ...
- 从零开始一个http服务器(四)-动态返回
从零开始一个http服务器(四) 代码地址 : https://github.com/flamedancer/cserver git checkout step4 运行: make clean &am ...
- Pylot网站Web服务器性能和负载压力测试-适用Windows可绘制图表
为了能够准确地评估网站服务器对网络流量的承受能力,我们一般会采取模拟网站用户访问,通过不断地增加并发数,延长访问时长,从而最终得出网站Web服务器的性能和负载能力.当然也可以通过Web压力测试,来完善 ...
- 一个基于.NET平台的自动化/压力测试系统设计简述
AutoTest系统设计概述 AutoTest是一个基于.NET平台实现的自动化/压力测试的系统,可独立运行于windows平台下,支持分布式部署,不需要其他配置或编译器的支持.(本质是一个基于协议的 ...
- 九款Web服务器性能压力测试工具
一.http_load 程序非常小,解压后也不到100Khttp_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会 ...
- Web服务器压力测试一例
近期部门新上线一个服务,我们使用ab和locust分别测试 目前项目属于demo阶段,对访问量的支持不要求太高,我们暂且设定在500请求,20并发 工具介绍 ab ab全称为:Apache HTTP ...
随机推荐
- 设计能长按并有动画效果且能触发事件的高级view
设计能长按并有动画效果且能触发事件的高级view 效果图: 源码: LongTapAnimationView.h 与 LongTapAnimationView.m // // LongTapAnima ...
- 移动App中常见的Web漏洞
智能手机的存在让网民的生活从PC端开始往移动端转向,现在网民的日常生活需求基本上一部手机就能解决.外卖,办公,社交,银行转账等等都能通过移动端App实现.那么随之也带来了很多信息安全问题,大量的用户信 ...
- Entity Framework 指定架构无效 错误:1052
IIS发布网站:如果不发布放到IIS没有问题,发布后IIS部署 打开网站却提示指定架构无效 1052 找到很多解决的问题 1添加wenconfig 2.更改entity名的 其实我认为最简单的就是先找 ...
- Java的日期时间
Date类 Date d = new Date() 使用SimpleDateFormat格式化日期. SimpleDateFormat允许用户自定义日期时间格式来运行. package cuiyuee ...
- Cinder组件解析
1 Cinder架构图 Cinder是在虚拟机和具体存储设备之间引入了一层“逻辑存储卷”的抽象,Cinder本身并不是一种存储技术,只是提供一个中间的抽象层,Cinder通过调用不同存储后端类型的驱 ...
- Hive安装报错
安装好hive后在bin路径下输入hive报错: [ERROR] Terminal initialization failed; falling back to unsupported 原因是hado ...
- python文件读写模式 --- r,w,a,r+,w+,a+,rb,wb
要了解文件读写模式,需要了解几种模式的区别,以及对应指针 r : 读取文件,若文件不存在则会报错 w: 写入文件,若文件不存在则会先创建再写入,会覆盖原文件 a : 写入文件,若文件不存在则会先创建再 ...
- 程序人生:02我来告诉你,一个草根程序员如何进入BAT
本文摘自左潇龙博客,原文出处:http://www.cnblogs.com/zuoxiaolong/p/life54.html 引言 首先声明,不要再问LZ谁是林萧,林萧就是某著名程序员小说的主角名字 ...
- 随手练——HDU Safe Or Unsafe (小根堆解决哈夫曼问题)
HDU 2527 :http://acm.hdu.edu.cn/showproblem.php?pid=2527 哈夫曼树,学完就忘得差不多了,题目的意思都没看懂,有时间复习下,看了别人的才知道是怎么 ...
- JavaScript脚本的执行原理?
JavaScript是一种动态.弱类型.基于原型的语言,通过浏览器可以直接执行. 当浏览器遇到\<script>标记的时候,浏览器会执行之间的JavaScript代码.嵌入的js代码是顺序 ...