一篇关于django,tornado性能测试的非专业性报告

Posted python自动化运维之美

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇关于django,tornado性能测试的非专业性报告相关的知识,希望对你有一定的参考价值。

上一篇里我们简单了说了一下 django、tornado最基础代码 性能方面的对比 不知道的同学可以点这个 一篇关于django,tornado性能测试的非专业性报告(一)
那么这一篇我们稍微深入一些。继续对比两者之间的性能。

第一篇的第二个测试,由于tornado的设计问题我们采用阻塞的编程方式来测试,导致那是一个无意义的对比。那么这篇的第一个测试就采用tornado异步处理的方式来进行吧

ps:由于django不存在阻塞非阻塞设计理念的问题 所以这里就不写django的代码及测试报告了。这里仅仅将第一篇中 “二、django、tornado最基本代码模拟访问数据库测试对比” 的tornado部分代码改造后重新测试。第一篇

tornado异步处理模拟访问数据库测试

容我再啰嗦一句,简单介绍一下这里的代码编写逻辑。我们是通过ping 一次百度来模拟打开网页时从数据库中读取信息的过程。采用tornado异步方式,这里的异步方式不是传统的celery方式,而是tornado协程(异步非阻塞式返回),如果这里不理解那么你只能看tornado的官方文档了。(ps:传统的celery是后台异步,直接不返回处理结果的,这里虽然是异步但是依然返回结果。)
 
   
   
 
  1. import textwrap

  2. import tornado.httpserver

  3. import tornado.ioloop

  4. import tornado.options

  5. import tornado.web

  6. import tornado.httpclient

  7. import tornado.gen

  8. import os

  9. import functools

  10. import tornado.concurrent

  11. from tornado.options import define, options

  12. import time

  13. from tornado import escape

  14. from tornado import gen

  15. define("port", default=8888, help="run on the given port", type=int)

  16. class AsyncHandler(tornado.web.RequestHandler):

  17.    @tornado.web.asynchronous

  18.    @tornado.gen.coroutine

  19.    def get(self, *args, **kwargs):

  20.        yield gen.sleep(1)

  21.        self.finish('hello')

  22. if __name__ == "__main__":

  23.    tornado.options.parse_command_line()

  24.    app = tornado.web.Application(

  25.        handlers=[

  26.            (r"/aaa", FutureHandler2),

  27.            (r"/bbb", AsyncHandler),

  28.        ],

  29.        # debug=True,

  30.    )

  31.    http_server = tornado.httpserver.HTTPServer(app)

  32.    http_server.listen(options.port)

  33.    tornado.ioloop.IOLoop.instance().start()

 
   
   
 
  1. [root@centos1 ~]# ab -n 1000 -c 1000 http://localhost:8888/bbb

  2. This is ApacheBench, Version 2.3 <$Revision: 655654 $>

  3. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

  4. Licensed to The Apache Software Foundation, http://www.apache.org/

  5. Benchmarking localhost (be patient)

  6. Completed 100 requests

  7. Completed 200 requests

  8. Completed 300 requests

  9. Completed 400 requests

  10. Completed 500 requests

  11. Completed 600 requests

  12. Completed 700 requests

  13. Completed 800 requests

  14. Completed 900 requests

  15. Completed 1000 requests

  16. Finished 1000 requests

  17. Server Software:        TornadoServer/4.5.2

  18. Server Hostname:        localhost

  19. Server Port:            8888

  20. Document Path:          /bbb

  21. Document Length:        5 bytes

  22. Concurrency Level:      1000

  23. Time taken for tests:   4.872 seconds

  24. Complete requests:      1000

  25. Failed requests:        0

  26. Write errors:           0

  27. Total transferred:      199000 bytes

  28. html transferred:       5000 bytes

  29. Requests per second:    205.26 [#/sec] (mean) ##看这里!!

  30. Time per request:       4871.895 [ms] (mean)

  31. Time per request:       4.872 [ms] (mean, across all concurrent requests)

  32. Transfer rate:          39.89 [Kbytes/sec] received

  33. Connection Times (ms)

  34.              min  mean[+/-sd] median   max

  35. Connect:        0  450 492.7     35    1003

  36. Processing:  1005 1466 511.4   1276    2842

  37. Waiting:     1002 1466 511.4   1275    2842

  38. Total:       1040 1916 873.0   1486    3843

  39. Percentage of the requests served within a certain time (ms)

  40.  50%   1486

  41.  66%   2136

  42.  75%   2537

  43.  80%   2713

  44.  90%   3495

  45.  95%   3789

  46.  98%   3826

  47.  99%   3835

  48. 100%   3843 (longest request)

可以看到这种情况下,吞吐率为205.26 [#/sec]
!!!这里解释一下,由于tornado 在执行os.system的时候不能进行异步操作,google和查看官方文档后得证 os操作属于block形式 无法进行异步操作,故上述代码改成了sleep 1秒的形式来模拟访问数据库。
关于tornado的异步用法有好多种,这里就演示这一种。有兴趣的同学可以自行学习。

结果,当tornado采用异步方式进行代码构建时,性能确实远远超过django。虽然我们这个测试不够严谨(理论上django是不建议直接运行来承担访问的)。

半路杀出的go

当博主我正沉浸在编写此篇博文和测试的热潮中时,一位好友突然杀出,让我将同样的功能用go语言编写测试一下性能。为了友谊 ,我决定满足他这要求。(此段纯属娱乐)
 
   
   
 
  1. //代码贴上,这里只是简单实现了一个web服务,功能也仅仅是返回helloword而已。

  2. package main

  3. import (

  4.    "fmt"

  5.    "log"

  6.    "net/http"

  7. )

  8. func sayHello(response http.ResponseWriter, request *http.Request) {

  9.    fmt.Println("Hello World!")

  10. }

  11. func main() {

  12.    http.HandleFunc("/hello", sayHello)  

  13.    er := http.ListenAndServe(":8888", nil)  

  14.    if er != nil {

  15.        log.Fatal("ListenAndServe: ", er)

  16.    }

  17.    }

 
   
   
 
  1. #将代码编译一下

  2. go bulid hello.go

  3. #运行./hello

  4. [root@centos1 ~]# ab -n 1000 -c 1000 http://localhost:8090/hello/

  5. This is ApacheBench, Version 2.3 <$Revision: 655654 $>

  6. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

  7. Licensed to The Apache Software Foundation, http://www.apache.org/

  8. Benchmarking localhost (be patient)

  9. Completed 100 requests

  10. Completed 200 requests

  11. Completed 300 requests

  12. Completed 400 requests

  13. Completed 500 requests

  14. Completed 600 requests

  15. Completed 700 requests

  16. Completed 800 requests

  17. Completed 900 requests

  18. Completed 1000 requests

  19. Finished 1000 requests

  20. Server Software:        

  21. Server Hostname:        localhost

  22. Server Port:            8090

  23. Document Path:          /hello/

  24. Document Length:        39 bytes

  25. Concurrency Level:      1000

  26. Time taken for tests:   0.340 seconds

  27. Complete requests:      1000

  28. Failed requests:        0

  29. Write errors:           0

  30. Total transferred:      197028 bytes

  31. HTML transferred:       49257 bytes

  32. Requests per second:    2943.64 [#/sec] (mean) ##看这里!!

  33. Time per request:       339.715 [ms] (mean)

  34. Time per request:       0.340 [ms] (mean, across all concurrent requests)

  35. Transfer rate:          566.39 [Kbytes/sec] received

  36. Connection Times (ms)

  37.              min  mean[+/-sd] median   max

  38. Connect:        0   75  21.1     69     113

  39. Processing:    45  129  48.7    132     184

  40. Waiting:        0   90  48.7    120     146

  41. Total:        113  204  30.1    215     253

  42. Percentage of the requests served within a certain time (ms)

  43.  50%    215

  44.  66%    227

  45.  75%    230

  46.  80%    233

  47.  90%    237

  48.  95%    241

  49.  98%    245

  50.  99%    248

  51. 100%    253 (longest request)

好吧如此炸裂的性能!
限于篇幅的原因,本次性能测试基本是接近尾声了。虽然测试的过程不够严谨,但是我们也能简单的看出。tornado的异步处理能力,性能确实优于直接运行的django。注意这个前提是django直接运行。那么如果采用Gunicorn+django的方式呢。我们以后再战!


以上是关于一篇关于django,tornado性能测试的非专业性报告的主要内容,如果未能解决你的问题,请参考以下文章

Tornado x MVC

Django/Flask/Tornado三大web框架性能分析

python tornado异步性能测试

关于性能测试并发的设置,看这一篇就够了

使用Tornado作为Django App的服务器

tornado 入门篇