业务环境
- 业务背景
在做服务器并发测试的时候,使用了专门的代码进行代码测试,每次请求都会记录到mysql中;该测试同时也是为了学习mysql锁机制。 -
后台代码
Route::get('/update', function () { $result = \Illuminate\Support\Facades\DB::transaction(function () { \App\Models\LockRequestModel::insert(['mark' => time()]); \App\Models\LockUpdateModel::where('id', 1)->lockForUpdate()->get(); return \App\Models\LockUpdateModel::where('id', 1)->increment('times', 1); }); if ($result === 1) return 'ok'; });
- 代码说明
测试路由为/update
; 每次请求该路由都会像lock_requests
数据表中添加一条数据,记录当前真实请求;同时lock_updates
数据表中ID=1
的数据增加1
; - 测试条件
所有测试前,数据库的初始值为0
;lock_requests
表中的所有数据会被清空;lock_updates
表中ID=1
数据的times
属性,会被设置为0
测试工具
测试过程中使用了 webbench 和 Apcahe AB
出现的问题
测试工具返回结果的请求数量与服务器记录不一致。webbench
测试返回结果中的 Requests
与数据库的实际访问量相差甚远;Apache AB
的测试结果在并发量过大之后无效 ; AB
请求中是否有 缓存
? 如何解决出现的该问题?
具体示例
- webbench
# 第一次测试
$ webbench -c 200 -t 30 http://mysql.dev/update
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://mysql.dev/update
200 clients, running 30 sec.
Speed=32538 pages/min, 197558 bytes/sec.
Requests: 16269 susceed, 0 failed
## 此时数据库新增数据 488 条, times 数据记录也为 488, 与返回 Requests
数量不一致
# 第二次测试
$ webbench -c 100 -t 10 http://mysql.dev/update
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://mysql.dev/update
100 clients, running 10 sec.
Speed=1848 pages/min, 35425 bytes/sec.
Requests: 308 susceed, 0 failed.
## 此时数据库新增数据 408 条, times 数据记录同为 408, 比返回 Requests 数据量高
- Apach AB
# 第一次测试
$ ab -n1000 -c200 http://mysql.dev/update
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking mysql.dev (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: nginx/1.12.1
Server Hostname: mysql.dev
Server Port: 80
Document Path: /update
Document Length: 193 bytes
Concurrency Level: 200
Time taken for tests: 3.201 seconds
Complete requests: 1000
Failed requests: 964
(Connect: 0, Receive: 0, Length: 964, Exceptions: 0)
Non-2xx responses: 869
Total transferred: 447182 bytes
HTML transferred: 151319 bytes
Requests per second: 312.38 [#/sec] (mean)
Time per request: 640.247 [ms] (mean)
Time per request: 3.201 [ms] (mean, across all concurrent requests)
Transfer rate: 136.42 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 1.7 1 7
Processing: 0 223 641.6 5 3193
Waiting: 0 223 641.7 5 3193
Total: 0 225 642.5 6 3196
Percentage of the requests served within a certain time (ms)
50% 6
66% 10
75% 15
80% 23
90% 814
95% 2063
98% 2737
99% 2978
100% 3196 (longest request)
## 此时数据库数据量为 131
# 第二次测试
$ ab -n500 -c100 http://mysql.dev/update
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking mysql.dev (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests
Server Software: nginx/1.12.1
Server Hostname: mysql.dev
Server Port: 80
Document Path: /update
Document Length: 2 bytes
Concurrency Level: 100
Time taken for tests: 11.466 seconds
Complete requests: 500
Failed requests: 0
Total transferred: 575158 bytes
HTML transferred: 1000 bytes
Requests per second: 43.61 [#/sec] (mean)
Time per request: 2293.297 [ms] (mean)
Time per request: 22.933 [ms] (mean, across all concurrent requests)
Transfer rate: 48.98 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.9 0 4
Processing: 71 2073 542.7 2287 2428
Waiting: 71 2073 542.7 2287 2428
Total: 74 2074 542.0 2287 2428
WARNING: The median and mean for the initial connection time are not within a normal deviation
These results are probably not that reliable.
Percentage of the requests served within a certain time (ms)
50% 2287
66% 2306
75% 2315
80% 2321
90% 2341
95% 2354
98% 2372
99% 2391
100% 2428 (longest request)
## 此时数据库结果与请求结果一致。
# 第三次测试
$ ab -n1500 -c150 http://mysql.dev/update
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking mysql.dev (be patient)
Completed 150 requests
Completed 300 requests
Completed 450 requests
Completed 600 requests
Completed 750 requests
Completed 900 requests
Completed 1050 requests
Completed 1200 requests
Completed 1350 requests
Completed 1500 requests
Finished 1500 requests
Server Software: nginx/1.12.1
Server Hostname: mysql.dev
Server Port: 80
Document Path: /update
Document Length: 173 bytes
Concurrency Level: 150
Time taken for tests: 3.221 seconds
Complete requests: 1500
Failed requests: 131
(Connect: 0, Receive: 0, Length: 131, Exceptions: 0)
Non-2xx responses: 1369
Total transferred: 616044 bytes
HTML transferred: 237099 bytes
Requests per second: 465.71 [#/sec] (mean)
Time per request: 322.092 [ms] (mean)
Time per request: 2.147 [ms] (mean, across all concurrent requests)
Transfer rate: 186.78 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.0 0 5
Processing: 0 151 550.2 1 3214
Waiting: 0 151 550.2 1 3214
Total: 0 152 551.0 1 3217
Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 2
90% 11
95% 1523
98% 2575
99% 2929
100% 3217 (longest request)
## 数据库数据量为 131