从零开始一个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 ...
随机推荐
- SQL Server Mobile/Compact Edition 简单介绍
除了SQL Server Express,SQL Server还有个更轻量级的版本:SQL Server Compact Edition,容易让人想起Windows Compact Edition ( ...
- 打通版微社区(4):微信第三方服务部署——JSP的IIS部署
写在前面: 本机环境2008R2.tomcat8 网上搜了很多JSP的IIS部署,内容大部分是相近的,这些文章最早出现在2012的样子.大概的原理就是通过ISAPI方式对IIS进行扩展(这个扩展是to ...
- python传递参数给shell
#格式化字符 print "hello, %s" % ('mm') #传递参数 n="192.168.200.2" os.popen('ping %s -c 2 ...
- Python初学者第十三天 三级菜单程序小作业
13day 作业题目: 三级菜单 作业需求: 数据结构: menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村' ...
- 021.11 IO流 序列流
序列流:SequenceInputStream特点:流对象有序排列解决问题:将多个输入流合并成一个输入流,将多个源合并成一个源,对于多个源的操作会变简单. 构造函数参数就是输入流,一初始化就合并了多个 ...
- sychronized关键字(多线程)
sychronized关键字: 1. 作用:利用该关键字来创建内置锁,实现线程同步: 2. 分类:(1)sychronized同步方法:(2)sychronized同步代码块: 3. sychroni ...
- python strip()
函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除序列的字符 s.lstrip(rm) 删除s字符串中开头 ...
- Vue Spa切换页面时更改标题
在Vue组件化开发过程中,因为是单页面开发,但是有时候需要页面的title根据情况改变,于是上网查了一下,各种说法花(wo)里(kan)胡(bu)哨(dong), 于是想到一个黑科技 documet. ...
- Bootstrap--模仿官网写一个页面
本文参考Bootstrap官方文档写了简单页面来熟悉Bootstrap的栅格系统.常用CSS样.Javascript插件和部分组件. 以下html代码可以直接复制本地运行: BootstrapPage ...
- PAT——1063. 计算谱半径
在数学中,矩阵的“谱半径”是指其特征值的模集合的上确界.换言之,对于给定的n个复数空间的特征值{a1+b1i, ..., an+bni},它们的模为实部与虚部的平方和的开方,而“谱半径”就是最大模. ...