Python web框架 Tornado異步非阻塞


Python web框架 Tornado異步非阻塞

 

異步非阻塞

阻塞式:(適用於所有框架,Django,Flask,Tornado,Bottle)
  一個請求到來未處理完成,后續一直等待
  解決方案:多線程,多進程

異步非阻塞(存在IO請求): Tornado(單進程+單線程)
  使用異步非阻塞,需要遵循Tornado框架內部規則,gen

  多個連接請求,連接給服務端,如果是有異步非阻塞的話,服務端會接收所有的請求交由后台處理,等待其他鏈接的同時,原先連接不斷開,直至返回后台處理完成的結果!
  外部請求,連接服務端 或在select中創建Future對象,然后服務端再把請求交給業務處理平台,此時select監聽的列表中又會生成一個socket對象,當業務平台對請求處理完成之后就會把信息返回到服務端的select監聽列表中,同時對這個Future對象賦值,用於標記服務端是否要給客戶端返回請求信息。

  執行流程,本質上都是返回一個future對象,如果對這個對象被set_result了就返回值,否則就是夯住,一直保持連接,不終止請求。

1、基本使用

裝飾器 + Future 從而實現Tornado的異步非阻塞

class AsyncHandler(tornado.web.RequestHandler):

  
     @gen .coroutine
     def  get( self ):
         future  =  Future()
         future.add_done_callback( self .doing)
         yield  future
         # 或
         # tornado.ioloop.IOLoop.current().add_future(future,self.doing)
         # yield future
  
     def  doing( self , * args,  * * kwargs):
         self .write( 'async' )
         self .finish()

  當發送GET請求時,由於方法被@gen.coroutine裝飾且yield 一個 Future對象,那么Tornado會等待,等待用戶向future對象中放置數據或者發送信號,如果獲取到數據或信號之后,就開始執行doing方法。

  異步非阻塞體現在當在Tornaod等待用戶向future對象中放置數據時,還可以處理其他請求。

  注意:在等待用戶向future對象中放置數據或信號時,此連接是不斷開的。

2、同步阻塞和異步非阻塞對比

     同步阻塞

     

class SyncHandler(tornado.web.RequestHandler):

    def get(self):
        self.doing()
        self.write('sync')

    def doing(self):
        time.sleep(10)

異步非阻塞
class AsyncHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        future = Future()
        tornado.ioloop.IOLoop.current().add_timeout(time.time() + 5, self.doing)
        yield future


    def doing(self, *args, **kwargs):
        self.write('async')
        self.finish()

3、httpclient類庫

  Tornado提供了httpclient類庫用於發送Http請求,其配合Tornado的異步非阻塞使用。

  import tornado.web

   from  tornado  import  gen
   from  tornado  import  httpclient
  
   # 方式一:
   class  AsyncHandler(tornado.web.RequestHandler):
     @gen .coroutine
     def  get( self * args,  * * kwargs):
         print ( '進入' )
         http  =  httpclient.AsyncHTTPClient()
         data  =  yield  http.fetch( "http://www.google.com" )
         print ( '完事' ,data)
         self .finish( '6666' )
  
   # 方式二:
   # class AsyncHandler(tornado.web.RequestHandler):
   #     @gen.coroutine
   #     def get(self):
   #         print('進入')
   #         http = httpclient.AsyncHTTPClient()
   #         yield http.fetch("http://www.google.com", self.done)
   #
   #     def done(self, response):
   #         print('完事')
   #         self.finish('666')
  
  
  
application  =  tornado.web.Application([
     (r "/async" , AsyncHandler),
])
  
if  __name__  = =  "__main__" :
     application.listen( 8888 )
     tornado.ioloop.IOLoop.instance().start()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM