Tornado 异步服务器和异步客户端

1.Tornado 异步服务器实现

Tornado异步服务器主要通过协程实现,代码如下,整个服务器端接收到请求后,读取本地文件并返回给浏览器。RequestHandle的派生类方法get被tornado.web.gen.coroutine装饰器装饰。读取图片,这个IO操作会导致程序阻塞,因此使用yield暂停当前协程,在等待IO的过程中,IOLoop调度另外一个代码模块执行。

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import os
from tornado.concurrent import Future
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class cPic(tornado.web.RequestHandler):
    @tornado.web.gen.coroutine
    def get(self,filename):
        content=yield self.readImage(filename)
        if not content:
            self.write_error(404)
        else:
            self.set_header('Content-Type', 'image/png')
            self.write(content)


    def readImage(self,filename):
        picpath = os.path.join('./', 'static', filename)
        with open(picpath, 'rb') as f:
            content = f.read()
        future=Future()
        #Future封装了异步操作的结果
        #Future对象实际是coroutine函数装饰器和IOLoop的沟通使者,有着非常重要的作用。
        future.set_result(content)#发送一个信号,告诉IOLoop去调度暂停的协程继续执行。
        return future



if __name__=="__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"^/static/(.*)$",cPic )])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

相对应的同步服务器版本为

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import os
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class cPic(tornado.web.RequestHandler):

    def get(self,filename):
        picpath = os.path.join('./', 'static', filename)
        with open(picpath,'rb') as f:
            content=f.read()
        if not content:
            self.write_error(404)
        else:
            self.set_header('Content-Type', 'image/png')
            self.write(content)

if __name__=="__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"^/static/(.*)$",cPic )])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

在浏览器中输入127.0.0.1:8000\static\1.png进行访问,得到结果如图所示

Tornado 异步服务器和异步客户端_第1张图片

使用siege工具测试并发能力,运行命令

siege -t 1 -c 200 127.0.0.1:8000\static\1.png

表示1分钟内同时存在200个并发请求访问该服务器的图片资源。

以下第一张图是异步服务器版本的测试结果,第二张图是同步服务器版本的测试结果。异步服务器各方面性能上小优于同步版本,这可能是由于读取图片这个操作阻塞时间不是很长,导致效果不明显。

Tornado 异步服务器和异步客户端_第2张图片

Tornado 异步服务器和异步客户端_第3张图片

2.Tornado异步客户端

Tornado客户端请求主要涉及到HTTPClient、AsyncHTTPClient,HTTPRequest等模块。

同步客户端代码如下

from tornado.httpclient import HTTPClient,HTTPRequest

def getRequest(url):
    hc=HTTPClient()
    response=hc.fetch(url)
    return response.body

def postRequest(request):
    hc=HTTPClient()
    response=hc.fetch(request)
    return response.body
#print(getRequest('http://www.bjsxt.com'))
req=HTTPRequest(url='http://www.bjsxt.com',method='POST',headers={'User-Agent':'Mozilla/5.0 '
                                                                              '(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                                                                              '(KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'
                                                                 },body='uname=zhangsan')
print(postRequest(req))

异步客户端代码如下

from tornado.httpclient import AsyncHTTPClient

def loadpage(url):
    ahc=AsyncHTTPClient()
    ahc.fetch(url,callbac=callback)

def callback():
    print('callback')

两者主要区别在于模块不同以及fetch函数中,异步请求需要指定回调函数。 

3.参考

siege安装及操作

https://blog.csdn.net/qq_41493093/article/details/81774693

tornado协程

https://blog.csdn.net/wyx819/article/details/45420017

B站视频

https://www.bilibili.com/video/BV1kA41187TD?p=23

 

 

 

你可能感兴趣的:(Python,tornado)