1. 准备:AB命令 httpd-tool HTTP压测工具
$ sudo apt-get install apache2-utils
使用命令快捷安装 apache ab压测工具
用法:ab [options] [http[s]://]hostname[:port]/path
选项是:
-n requests 要执行的请求数
-c concurrency 一次发出的多个请求数
-t timelimit 秒到最大值。花费在基准测试上
这意味着 -n 50000
-s timeout 秒到最大值。等待每个响应
默认为 30 秒
-b windowssize TCP 发送/接收缓冲区的大小,以字节为单位
-B address 建立传出连接时要绑定的地址
-p postfile 包含要 POST 的数据的文件。还记得设置 -T
-u putfile 包含要 PUT 的数据的文件。还记得设置 -T
-T content-type 用于 POST/PUT 数据的内容类型标头,例如。
'应用程序/x-www-form-urlencoded'
默认为“文本/纯文本”
-v verbosity 要打印多少故障排除信息
-w 在 HTML 表格中打印结果
-i 使用 HEAD 而不是 GET
-x attributes 字符串作为表属性插入
-y 属性 字符串作为 tr 属性插入
-z attributes 字符串作为 td 或 th 属性插入
-C 属性 添加cookie,例如。 '阿帕奇 = 1234'。 (可重复)
-H 属性添加任意标题行,例如。 '接受编码:gzip'
在所有正常标题行之后插入。 (可重复)
-A 属性 添加Basic WWW Authentication,属性
是冒号分隔的用户名和密码。
-P attribute 添加Basic Proxy Authentication,属性
是冒号分隔的用户名和密码。
-X proxy:port 要使用的代理服务器和端口号
-V 打印版本号并退出
-k 使用 HTTP KeepAlive 功能
-d 不显示服务表的百分位数。
-S 不显示置信度估计器和警告。
-q 处理超过 150 个请求时不显示进度
-l 接受可变文档长度(用于动态页面)
-g 文件名 将收集的数据输出到 gnuplot 格式文件。
-e 文件名 输出带有百分比的 CSV 文件
-r 不要在套接字接收错误时退出。
-m method 方法名称
-h 显示使用信息(此消息)
-I 禁用 TLS 服务器名称指示 (SNI) 扩展
-Z ciphersuite 指定 SSL/TLS 密码套件(参见 openssl ciphers)
-f 协议 指定 SSL/TLS 协议
(SSL2、TLS1、TLS1.1、TLS1.2 或全部)
-E certfile 指定可选的客户端证书链和私钥
* 压测重点关注的几个概念:
吞吐量(RPS Request per second):
对服务器并发处理能力的量化指标。 计算公式: 总请求数 / 总测试时间
并发数
用户请求平均等待时长
服务器请求平均等待时长
计算公式:总测试时间 / 总请求数,是RPS的倒数
static kit_server::Logger::ptr g_logger = KIT_LOG_ROOT(); static kit_server::Logger::ptr g_logger2 = KIT_LOG_NAME(“system”);
void run() {
kit_server::Address::ptr addr = kit_server::Address::LookUpAnyIPAddress("0.0.0.0:8888");
if(!addr)
{
KIT_LOG_ERROR(g_logger) << "get addr error";
return;
}
kit_server::http::HttpServer::ptr server(new kit_server::http::HttpServer);
while(!server->bind(addr))
{
sleep(1);
}
server->start();
}
int main(int argc, char argv[]) { g_logger2->setLevel(kit_server::LogLevel::Level::INFO); /起初为单线程处理*/ kit_server::IOManager iom(“http_server”, 1); iom.schedule(&run);
return 0;
} ```
1.1 单线程测试
$ ab -n 1000000 -c 200 "[http://192.168.77.136:8888/kit"](http://192.168.77.136:8888/kit")
请求总数=100万,并发数量=200 短连接
1.1.1 测试结果
- 总测试时间: 约45 s
- 总传输量:26,300万字节
- HTML总传输量:14,800万字节
- RPS: 22,223.39 请求数/sec (平均)
- 用户平均等待时长: 9 ms
- 服务器平均等待时长:0.045 ms
1.1.2 资源使用情况:
1.2 两个线程测试
$ ab -n 1000000 -c 200 "[http://192.168.77.136:8888/kit"](http://192.168.77.136:8888/kit")
请求总数=100万,并发数量=200 短连接
BUG:程序发生断言
现象:单线程测试正常,而多线程发生错误,说明协程调度的模块有点问题。重点关注一下Scheduler::run()
这个函数里面调度的一些情况。
通过断言打印的函数调用栈信息:断言发生在HOOK模块的do_io()::addEvent()
函数中。也就说此时负责执行accept()
的协程处于挂起HOLD状态。这很奇怪,HOLD状态的协程怎么会被调度?
修正:将YieldToHold()
中对协程状态的修改注释掉就正常了
原因:笨办法试出来的,由于是一个HOLD状态的协程被调度了,就去检查所有调度前可能修改状态的地方,最后控制变量发现的这个地方………具体什么原因造成的不清楚。
找到问题:协程重入状态冲突。本质上是因为协程切入/切出之间的操作并非原子性的。
如何解决问题?
1.2.1 测试结果
- 总测试时间: 约45 s
- 总传输量:26,300万字节
- HTML总传输量:14,800万字节
- RPS: 22,032.43 请求数/sec (平均)
- 用户平均等待时长: 9.078 ms
- 服务器平均等待时长:0.045 ms
1.2.2 资源使用情况
1.3 5个线程测试
$ ab -n 1000000 -c 200 "[http://192.168.77.136:8888/kit"](http://192.168.77.136:8888/kit")
请求总数=100万,并发数量=200 短连接
1.3.1 测试结果
- 总测试时间: 约45 s
- 总传输量:26,300万字节
- HTML总传输量:14,800万字节
- RPS: 22,008.10 请求数/sec (平均)
- 用户平均等待时长: 9.088 ms
- 服务器平均等待时长:0.045 ms
1.3.2 资源使用情况
2. 准备:认识nginx
ubuntu20.04环境$ sudo apt-get install nginx
即可便捷安装
概念:nginx是高性能HTTP和反向代理Web服务器。处理高并发的能力十分强大。
- nginx的配置:
/etc/nginx/nginx.conf
- https://blog.csdn.net/tjcyjd/article/details/50695922
2.1 以nginx的压测作为对照
- nginx单线程、短连接压测:
$ ab -n 1000000 -c 200 "http://192.168.77.136:80/kit"
- 自己服务器框架单线程、短连接压测:
$ ab -n 1000000 -c 200 "http://192.168.77.136:8888/kit"
- nginx单线程、长连接压测:
$ ab -n 1000000 -c 200 -k "http://192.168.77.136:80/kit"
- 自己服务器框架单线程、长连接压测:
$ ab -n 1000000 -c 200 -k "http://192.168.77.136:8888/kit"