目录

    1. 网站性能基础指标

    • 并发数: 服务器单位时间内处理的会话数量
    • 吞吐率: 服务器单位时间内处理的请求数
    • 响应时间: 用户从发出请求到接受完响应之间的总耗时,由网络传输耗时、服务处理耗时等多个部分组成
    • 平均响应时间: 所有请求响应时间的平均值

    2. 测试工具

    性能测试有两个层次,一个是单接口的压力测试,一个是生产环境模拟用户操作的压力测试。前者可以通过工具对 CGI 自动化压测,后者通常需要根据业务逻辑定制化测试。

    主要的免费压力测试工具有,apache ab、webench、wrk、Gatling、sniper、hey、Siege、http_load、vegeta、t50、GoReplay、tcpcopy、gryphon、locust.io、Jmeter。下面描述其中若干的用法。

    2.1 ab

    ab 全称为:apache bench

    命令格式: ab [options] [http://]hostname[:port]/path

    主要参数:

      -n,总共请求数
      -c ,并发数
    

    例如,以每秒 50 的并发,产生 1000 个请求。

    ab -c 50 -n 1000 http://127.0.0.1/
    

    2.2 http_load

    http_load 测试前需要将测试的 url 写入文件,把文件作为参数传递给 http_load。

    命令格式:http_load [-checksum] [-throttle] [-proxy host:port] [-verbose] [-timeout secs] [-sip sip_file] -parallel N | -rate N [-jitter] -fetches N | -seconds N url_file

    主要参数:

    -parallel ,并发数
    -fetches,总共请求数
    

    例如,以每秒 50 的并发,产生 1000 个请求。

    # http_load -parallel 50 -fetches 1000 url.txt
    

    2.3 webbench、siege

    webbench 不支持指定总访问数,支持并发数和测试时长,不直接支持 https 测试。

    命令格式:webbench [option]… URL

    主要参数:

    -c,并发数
    -t,测试持续时间
    

    例如,以每秒 50 的并发,持续测试 20 秒

    webbench -c 50 -t 20 http://127.0.0.1/
    

    siege 的参数和命令格式与 webbench 类似。

    siege -c 50 -t 20 http://127.0.0.1/
    

    2.4 wrk

    wrk 使用了一些操作系统特定的高性能 io 机制, 比如 select, epoll, kqueue 等,能用很少的线程压测出很大的并发量。

    命令格式:wrk

    主要参数:

    -c,跟服务器建立并保持的连接数量  
    -d,压测时间           
    -t,使用多少个线程进行压测                                                      
    -s,指定 Lua 脚本路径       
    -H,为每一个 HTTP 请求添加HTTP头      
    --latency,在压测结束后,打印延迟统计信息   
    --timeout,超时时间     
    

    例如,开启 10 个线程,每秒 100 的并发,持续 30秒进行压测。

    wrk -t10 -c100 -d30s http://127.0.0.1
    

    相比较于 其他工具 wrk 可以使用 lua 脚本来压测更加复杂的场景。比如,需要测试 POST 请求,只需要准备一个 lua 脚本。

    post.lua

    wrk.method = "POST"
    wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
    wrk.body = "key1=val1&key2=val2 "
    

    使用 -s 参数

    wrk -t10 -c100 -d30s  -s post.lua http://127.0.0.1
    

    3. 测试 Demo

    Django 应用的部署架构,采用一个 Nginx 容器作为反向代理,后台通过 uSWGI 转发请求给 Django,Django 访问 MySQL、Redis 等服务,沿原链路返回响应。

    硬件配置:笔记本intel i5-5300 2.3GHz,8GB 内存,SAMSUNG 固态硬盘

    软件配置: CentOS 7.2,Nginx 2 个 work,uWSGI 8 个 work,无 gevent。

    下面是一个简单的单次测试试验:

    无 DB 访问:

    wrk -t10 -c10000 -d10 'http://127.0.0.1'
    
    Running 10s test @ http://127.0.0.1
      10 threads and 10000 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency   176.93ms  334.40ms   1.99s    90.73%
        Req/Sec   322.89    162.38   840.00     67.78%
      18351 requests in 10.06s, 7.70MB read
      Socket errors: connect 8989, read 56, write 0, timeout 549
    Requests/sec:   1824.76
    Transfer/sec:    784.08KB
    

    有 DB 访问:

    wrk -t10 -c10000 -d10 'http://127.0.0.1/books_fbv/'
    
    Running 10s test @ http://127.0.0.1/books_fbv/
      10 threads and 10000 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency   393.67ms  274.98ms   1.99s    92.02%
        Req/Sec    69.44     70.51   360.00     82.23%
      3623 requests in 10.05s, 2.27MB read
      Socket errors: connect 8989, read 102, write 0, timeout 179
    Requests/sec:    360.40
    Transfer/sec:    231.58KB
    

    Nginx 转发静态文件:

    wrk -t10 -c10000 -d10 'http://127.0.0.1/static/index.html'
    
    Running 10s test @ http://127.0.0.1/static/index.html
      10 threads and 10000 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency    26.33ms   54.99ms   1.34s    99.19%
        Req/Sec     4.84k     3.39k   10.72k    50.58%
      371148 requests in 10.08s, 89.54MB read
      Socket errors: connect 8989, read 0, write 0, timeout 19
    Requests/sec:  36809.92
    Transfer/sec:      8.88MB
    

    Django 转发静态文件:

    wrk -t10 -c10000 -d10 'http://127.0.0.1/static/index.html'
    
    Running 10s test @ http://127.0.0.1/static/index.html
      10 threads and 10000 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency   268.50ms  282.75ms   1.99s    92.15%
        Req/Sec   120.43    107.12   414.00     53.24%
      6184 requests in 10.06s, 15.33MB read
      Socket errors: connect 8989, read 301, write 0, timeout 264
      Non-2xx or 3xx responses: 6184
    Requests/sec:    615.00
    Transfer/sec:      1.52MB
    

    4. 参考