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进行访问,得到结果如图所示
使用siege工具测试并发能力,运行命令
siege -t 1 -c 200 127.0.0.1:8000\static\1.png
表示1分钟内同时存在200个并发请求访问该服务器的图片资源。
以下第一张图是异步服务器版本的测试结果,第二张图是同步服务器版本的测试结果。异步服务器各方面性能上小优于同步版本,这可能是由于读取图片这个操作阻塞时间不是很长,导致效果不明显。
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函数中,异步请求需要指定回调函数。
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