tornado的同步框架與其他web框架相同都是處理先來的請求,如果先來的請求阻塞,那么后面的請求也會處理不了。一直處於等待過程中。但是請求一旦得到響應,那么:
- 請求發送過來后,將需要的本站資源直接返回給客戶端
- 請求發送過來后,本站沒有需要的資源,從其它站點獲取過來,再返回給客戶端
一、Tornado中的同步框架
1、本站資源直接返回
import tornado.web import time class LoginHandler(tornado.web.RequestHandler): def get(self): time.sleep(10) #第一個請求來后等10s,后面的請求無法處理,只有等這個請求結束后才能處理其他的請求 self.write('LoginHandler') def post(self): pass class IndexHandler(tornado.web.RequestHandler): def get(self): self.write('IndexHandler') def post(self): pass application=tornado.web.Application([ (r'/login/',LoginHandler), (r'/index/', IndexHandler), ],) if __name__ == '__main__': application.listen(8888) tornado.ioloop.IOLoop.instance().start()
可以看到因為回調函數中阻塞了10s,所以后面的請求必須等這個回調函數結束后才能處理后面的請求,在tornado中使用future對象進行異步處理。
2、從其它站點獲取資源再返回
import tornado.web import requests class LoginHandler(tornado.web.RequestHandler): def get(self): requests.get('http://www.baidu.com') #此時無法處理其它請求 self.write('LoginHandler') def post(self): pass class IndexHandler(tornado.web.RequestHandler): def get(self): self.write('IndexHandler') def post(self): pass application=tornado.web.Application([ (r'/login/',LoginHandler), (r'/index/', IndexHandler), ],) if __name__ == '__main__': application.listen(8888) tornado.ioloop.IOLoop.instance().start()
從其它站點獲取資源的過程也是阻塞的,服務端處理不了其它請求,必須等這個請求處理完畢才能處理其它請求。
二、Tornado中的異步框架
對於上面的兩種情況tornado也是有對策的,就是使用future對象,進行異步處理。
1、本站資源直接返回
import tornado.web from tornado import gen from tornado.concurrent import Future import time class LoginHandler(tornado.web.RequestHandler): @gen.coroutine def get(self): future=Future() tornado.ioloop.IOLoop.current().add_timeout(time.time()+10,self.done) #此處的10s延遲不會影響處理其它請求 yield future def done(self,*args,**kwargs): self.write('LoginHandler') self.finish() def post(self): pass class IndexHandler(tornado.web.RequestHandler): def get(self): self.write('IndexHandler') def post(self): pass application=tornado.web.Application([ (r'/login/',LoginHandler), (r'/index/', IndexHandler), ],) if __name__ == '__main__': application.listen(8888) tornado.ioloop.IOLoop.instance().start()
2、從其它站點獲取資源再返回
import tornado.web from tornado import gen from tornado import httpclient class LoginHandler(tornado.web.RequestHandler): @gen.coroutine def get(self): http=httpclient.AsyncHTTPClient() yield http.fetch('http://www.google.com',self.done) #訪問其它網址不能用requests,應該使用tornado內置的,其實質也是返回future對象 def done(self,*args,**kwargs): self.write('LoginHandler') self.finish() def post(self): pass class IndexHandler(tornado.web.RequestHandler): def get(self): self.write('IndexHandler') def post(self): pass application=tornado.web.Application([ (r'/login/',LoginHandler), (r'/index/', IndexHandler), ],) if __name__ == '__main__': application.listen(8888) tornado.ioloop.IOLoop.instance().start()
tornado解決異步請求就是利用future對象。future對象中設定默認參數result=None,如果在某一時刻future的result中被設定值了,那么它就會自動執行回調函數,實際上這種執行回調函數的功能就是所謂的異步,不需要服務器等待,自己自動執行完后會進行回調(注意這都是在一個線程中)。詳情參考:https://www.cnblogs.com/shenjianping/p/11622210.html