天天看點

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

      随着副業如火如荼的進行,給我們這些掙紮在底層的人們極大的改善了生活條件,感謝政府,感謝黨,開展副業的同時也不能忘記自己的老本行,利用抽會兒煙的時間,接着上篇來實作Sanic異步非阻塞并行請求。

      我們在Sanic架構中請求通路的時候發現是一些問題,意思就是當你發起第一個請求的時候,在請求中你加入了類似time.sleep(5)阻塞主線程的方法,你同時又去發起第二個請求,但第二個請求要等待第一個請求結束後也就是5秒後才執行,那萬一第一個請求執行的時間過長,那其它請求就在苦苦等待,這在正式的操作環境中是不允許的,那我們怎麼解決這個,接下來就是我們要實作的異步非阻塞請求,我們便于測試先建立一個名為test.py的測試檔案,看下正常的執行方法:

# coding:utf-8
import time
from sanic import Sanic
from sanic.response import text

# 初始化
app = Sanic(__name__)

async def task_sleep():
    while True:
        time.sleep(5)
        print("執行中……")

# 定義路由實作首頁顯示
@app.route("/")
async def index(request):
    await task_sleep()
    return text("你好,美女!")


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000, debug=True)
           

我們添加一個task_sleep的方法,方法中我們加入了延遲5秒,在首頁方法函數中引入,這裡要注意的是要引入異步函數,我們在前面要加個await,我們運作看看,打開浏覽器開發者工具:

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

大家可以看到,在這個請求中一直在等待當中,這顯然不是我們想要的,那我們根據官方的方法改動下:

# 定義路由實作首頁顯示
@app.route("/")
async def index(request):
    app.add_task(task_sleep())
    return text("你好,美女!")
           

add_task:官方的解釋是在循環開始後,安排任務稍後運作。你可以了解将task_sleep方法放到了背景執行,我們運作看看結果:

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

可以看到通過上面的修改就實作了請求的異步執行,那問題又來了,這樣看着貌似很完美,但我們發現如果同時執行2個請求,我們會發現,第二個請求一直在請求等待中,無法達到接口并行請求:

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

那這個問題怎麼處理呢,通過檢視一些資料和方法,可能水準有限,沒發現sanic本身有什麼方法能處理,其它的處理方式都是使用了asyncio庫,我們這樣修改下:

# coding:utf-8
import time,asyncio
from sanic import Sanic
from sanic.response import text

# 初始化
app = Sanic(__name__)

async def task_sleep():
    while True:
        await asyncio.sleep(5)
        print("執行中……")

# 定義路由實作首頁顯示
@app.route("/")
async def index(request):
    app.add_task(task_sleep())
    return text("你好,美女!")


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000, debug=True)
           

使用 await asyncio.sleep(5)來替代time.sleep(5),來,我們繼續測試看下:

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

控制台列印:

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

這樣我們就實作了異步非阻塞并行的請求,嗯感覺很完美,這裡你可能不會發現,但在實際的開發過程中,你會發現這裡是用asyncio.sleep(5)實作延遲來測試背景任務,那在實際開發中,比如說我們提取PDF有100多頁,這個執行的過程可能要花數分鐘的時間,我們在這個PDF處理的方法中并沒有加入sleep()延遲這類的方法,那我們怎樣讓這個方法在背景運作而且能實作并行的請求而不阻塞呢?

這裡會用到asyncio中的ensure_future方法,這裡我們就先提及一下這個問題,在後面的調用提取PDF的方法中我們會用到這個,這裡我發個對比圖看下大家就能明白:

未并行處理 并行處理
江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求
江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求
江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求
江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

從上面的運作結果看,第一個是等任務執行完成後才去執行加載圖檔請求的通路,第二個很明顯是并行請求接口,一邊擷取一邊加載圖檔。

好了,今天對Sanic異步非阻塞并行請求的實作方法就介紹到這裡,下一節來實作websocket服務的搭建。

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

開始要為晚上的地攤生意做準備了,歡迎廣大人民群衆提供一些喜歡的需求物品清單。

沒有做不到,隻有想不到。江湖不說再見,咱們下篇見!

江湖小白之進階篇 (三)實作Sanic異步非阻塞并行請求

關注公衆号,超越平凡才能成就自我