搜尋
首頁後端開發Python教學tornado非同步請求非阻塞

前言

也許有同學很迷惑:tornado不是標榜異步非阻塞解決10K問題的嘛?但是我卻發現不是torando不好,而是你用錯了.比如最近發現一個事情:某網站打開頁面很慢,伺服器cpu/內存都正常.網絡狀態也良好. 後來發現,打開頁面會有很多請求後端數據庫的訪問,有一個mongodb的數據庫業務api的rest服務.但是它的tornado卻用錯了,一步步的來研究問題:


說明

以下的例子都有2個url,一個是耗時的請求,一個是可以或者說需要立刻返回的請求,我想就算一個對技術不熟,從道理上來說的用戶, 他希望的是他訪問的請求不會影響也不會被其他人的請求影響


#!/bin/env python

import tornado.http

import

import tornado.httpopin

import

import tornado.options

import tornado.web

import tornado.httpclient

import time

from tornado.options import defined given port", type=int)

class SleepHandler(tornado.web.RequestHandler):

    def get(self):

   ")

class JustNowHandler(tornado.web.RequestHandler):

    def get(self):

        self.write("i hope just now see you__ 🠎 ornado.options. parse_command_line()

    app = tornado.web.Application(handlers=[

            (r"/sleep", SleepHandler), (r"/justnow", J TPServer(app )

    http_server.listen(options.port)

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

假如你使用頁面請求或使用哪個工具先訪問http://localhost /sleep,再訪問http://localhost:8000/justnow.你會發現本來可以立刻返回的/jsutnow的請求會一直阻塞到/sleep請求完才返回.

這是為啥?為啥我的請求被/sleep請求阻塞了?如果平時我們的web請求足夠快我們可能不會意識到這個問題,但是事實上經常會有一些耗時的進程,意味著應用程式被有效的鎖定直至處理結束.


這是時候你有沒有想起@tornado.web.asynchronous這個裝飾器?但是使用這個裝飾器有個前提就是你要耗時的執行需要執行異步,比如上面的time.sleep,你只是加裝飾器是沒有作用的,而且需要注意的是Tornado默認在函數處理返回時關閉客戶端的連接,但是當你使用@tornado.web.asynchonous裝飾器時,Tornado永遠不會自己關閉連接,需要顯式的self.finish()關閉


我們大部分的函數都是阻塞的,例如上面的time.sleep其實tornado有個非同步的實作:


#!/bin/env python

import tornado.httpserver

import tornado.iolooppopornp.

import tornado.gen

import tornado.httpclient

import tornado.concurrent

import tornado.ioloop

default=8000, help="run on the given port", type=int)

class SleepHandler(tornado.web.RequestHandler):

    @tornado.web.asynchronous

    @tornado.web.asynchronous

   

        yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 5)

  sel    web .RequestHandler):

    def get(self):

        self.write("i hope just now see you")

if __name__ option;

    app = tornado.web.Application(handlers=[

            (r"/sleep", SleepHandler), (r"/justnow", JustNowHandler)])

    http_server = tornado.httpserver.HTTPServer(app)

    http_server.listen( options.port)

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

這裡有個新的tornado.gen.coroutine裝飾器, coroutine是3.0之後新增的裝飾器.以前的辦法是用回調,還是看我這個例子:

class SleepHandler(tornado.web.RequestHandler):

    @tornado.web.asynchronous

    @tornado.web.asynchronous

. .instance(). add_timeout(time.time() + 5, callback=self.on_response)

    def on_response(self):

        self.write("when i sleep 5s")

        self.finish()

使用了callback, 但是新的裝飾器讓我們通過yield實現同樣的效果:你在打開/sleep之後再點擊/justnow, justnow的請求都是立刻返回不受影響.但是用了asynchronous的裝飾器你的耗時的函數也需要執行非同步


剛才說的都是沒有意義的例子,下面寫個有點用的:讀取mongodb資料庫數據,然後再前端按行write出來


#! /bin/env python

import tornado.httpserver

import tornado.ioloop

import tornado.options

import tornado。 rent

import tornado.ioloop

import time

# 一個mongodb出品的支援異步的資料庫的python驅動

import motor

from tornado.options import define, optorsdefine

from tornado.options defimport run on the given port", type=int)

# db其實就是test資料庫的遊標

db = motor.MotorClient().open_sync().test

class SleepHandler(BaseHandler): .asynchronous

    @tornado.gen.coroutine

    def get(self):

        # 這一行執行還是阻塞需要時間的,我的

        # 這一行執行還是阻塞需要時間的,我的

        # ) 。 _object( )

            self.write('

%s

' % message['a']))

     

    def _on_response(self, message, error):

        if error:

            raise tornado.web.HTTPError(500, error)

𠟎  for i in message:

                self.write('

%s

' % i['a'])

        else:

  •             self.write('')

        sel

        def get(self):

            self.write("i hope just now see you ")

    if __name__ == "__main__":

        tornado.options.parse_command_line()

        app = tornado.web.Application(handlers=[Han (r"/真主這個耗時的東西不能異步的丟給某工具去執行而不阻塞我的請求呢?好吧,我也想到了:celery,正好github有這個東西:tornado-celery

    執行下面的程序首先你要安裝rabbitmq和celery:

  • #!/bin/env python

    import tornado.httpserver

    import tornado.ioloop

    import tornado.options

    import tornado.web

    import tornado.gen

    import tornado.httpclient

    import tcelery, tasks

    import time

    from tornado.options import define, options

    int)

    tcelery.setup_nonblocking_producer()

    class SleepHandler(tornado.web.RequestHandler):

        @tornado.web.asynch :

            # tornado. gen.Task的參數是:要執行的函數, 參數

            yield tornado.gen.Task(tasks.sleep.apply_async, args=[5])

    selfin    self .finish()


    class JustNowHandler(tornado.web.RequestHandler):

        def get(self):

           ==

        tornado.options.parse_command_line()

        app = tornado.web.Application(handlers=[

             http_server = tornado. httpserver.HTTPServer(app)

        http_server.listen(options.port)

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

    time

    task是celery的任務定義的文件,包含我們說的time函數

    import time

    from celery import Celery

    celery = Celery("tasks", broker="amqp://guest:guest@localhost:5672")

    celery.conf.CELERY_RESULT_BACKEND = "amqp"

    @celery.task

    def sleep(seconds):

    time.sleep(float(seconds))

    return seconds

    if __name__ == "__main__":

    celery.start()

    Then start the celelry worker (otherwise, how will your task be executed? It is definitely needed A consumer takes it away):


    celery -A tasks worker --loglevel=info

    But the problem here may also be serious: our asynchronous non-blocking depends on celery, or the length of this queue, if the task If there are many, then you need to wait, which is very inefficient. Is there a way to change my synchronous blocking function to asynchronous (or be understood and recognized by tornado's decorator)?


    #!/bin/env python

    import tornado.httpserver

    import tornado.ioloop

    import tornado.options

    import tornado.web

    import tornado.httpclient

    import tornado.gen

    from tornado.concurrent import run_on_executor

    # This concurrency library In python3, you need to install sudo pip install futures

    from concurrent.futures import ThreadPoolExecutor

    import time

    from tornado.options import define, options

    define("port", default=8000, help="run on the given port", type=int)

    class SleepHandler(tornado.web.RequestHandler):

    executor = ThreadPoolExecutor(2)

      #executor is a local variable not global

    @tornado.web.asynchronous

    @tornado.gen.coroutine

    def get(self):

    # If the asynchronous execution you perform will return a value and continue to be called, you can do this (just for demonstration), otherwise just yield directly

    res = yield self.sleep() I Self.write ("WHEN I SLEEP % S" % Res)

    Self.finish () @Run_ON_EXECUTOR

    DEF SLEEP (SELF):

    Time.sleep (5) Return 5

    Class JustNowHandler(tornado.web.RequestHandler):

    def get(self):

    self.write("i hope just now see you")

    if __name__ == "__main__":

    tornado.options.parse_command_line( )

    app = tornado.web.Application(handlers=[

    (r"/sleep", SleepHandler), (r"/justnow", JustNowHandler)])

    http_server = tornado.httpserver.HTTPServer(app)

    http_server.listen(options.port)

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

  • 陳述
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    Python的科學計算中如何使用陣列?Python的科學計算中如何使用陣列?Apr 25, 2025 am 12:28 AM

    Arraysinpython,尤其是Vianumpy,ArecrucialInsCientificComputingfortheireftheireffertheireffertheirefferthe.1)Heasuedfornumerericalicerationalation,dataAnalysis和Machinelearning.2)Numpy'Simpy'Simpy'simplementIncressionSressirestrionsfasteroperoperoperationspasterationspasterationspasterationspasterationspasterationsthanpythonlists.3)inthanypythonlists.3)andAreseNableAblequick

    您如何處理同一系統上的不同Python版本?您如何處理同一系統上的不同Python版本?Apr 25, 2025 am 12:24 AM

    你可以通過使用pyenv、venv和Anaconda來管理不同的Python版本。 1)使用pyenv管理多個Python版本:安裝pyenv,設置全局和本地版本。 2)使用venv創建虛擬環境以隔離項目依賴。 3)使用Anaconda管理數據科學項目中的Python版本。 4)保留系統Python用於系統級任務。通過這些工具和策略,你可以有效地管理不同版本的Python,確保項目順利運行。

    與標準Python陣列相比,使用Numpy數組的一些優點是什麼?與標準Python陣列相比,使用Numpy數組的一些優點是什麼?Apr 25, 2025 am 12:21 AM

    numpyarrayshaveseveraladagesoverandastardandpythonarrays:1)基於基於duetoc的iMplation,2)2)他們的aremoremoremorymorymoremorymoremorymoremorymoremoremory,尤其是WithlargedAtasets和3)效率化,效率化,矢量化函數函數函數函數構成和穩定性構成和穩定性的操作,製造

    陣列的同質性質如何影響性能?陣列的同質性質如何影響性能?Apr 25, 2025 am 12:13 AM

    數組的同質性對性能的影響是雙重的:1)同質性允許編譯器優化內存訪問,提高性能;2)但限制了類型多樣性,可能導致效率低下。總之,選擇合適的數據結構至關重要。

    編寫可執行python腳本的最佳實踐是什麼?編寫可執行python腳本的最佳實踐是什麼?Apr 25, 2025 am 12:11 AM

    到CraftCraftExecutablePythcripts,lollow TheSebestPractices:1)Addashebangline(#!/usr/usr/bin/envpython3)tomakethescriptexecutable.2)setpermissionswithchmodwithchmod xyour_script.3)

    Numpy數組與使用數組模塊創建的數組有何不同?Numpy數組與使用數組模塊創建的數組有何不同?Apr 24, 2025 pm 03:53 PM

    numpyArraysareAreBetterFornumericalialoperations andmulti-demensionaldata,而learthearrayModuleSutableforbasic,內存效率段

    Numpy數組的使用與使用Python中的數組模塊陣列相比如何?Numpy數組的使用與使用Python中的數組模塊陣列相比如何?Apr 24, 2025 pm 03:49 PM

    numpyArraySareAreBetterForHeAvyNumericalComputing,而lelethearRayModulesiutable-usemoblemory-connerage-inderabledsswithSimpleDatateTypes.1)NumpyArsofferVerverVerverVerverVersAtility andPerformanceForlargedForlargedAtatasetSetsAtsAndAtasEndCompleXoper.2)

    CTYPES模塊與Python中的數組有何關係?CTYPES模塊與Python中的數組有何關係?Apr 24, 2025 pm 03:45 PM

    ctypesallowscreatingingangandmanipulatingc-stylarraysinpython.1)usectypestoInterfacewithClibrariesForperfermance.2)createc-stylec-stylec-stylarraysfornumericalcomputations.3)passarraystocfunctions foreforfunctionsforeffortions.however.however,However,HoweverofiousofmemoryManageManiverage,Pressiveo,Pressivero

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱工具

    SecLists

    SecLists

    SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    將Eclipse與SAP NetWeaver應用伺服器整合。

    SublimeText3 Linux新版

    SublimeText3 Linux新版

    SublimeText3 Linux最新版

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)