Uvicorn:輕量級ASGI服務器的持續監聽機制詳解
Uvicorn作為一款基于ASGI的輕量級Web服務器,其持續監聽http請求的能力是其核心功能。然而,與傳統的阻塞式服務器不同,Uvicorn的代碼中并沒有直接使用server.serve_forever()這樣的顯式循環調用。本文將深入探討Uvicorn是如何實現這一巧妙的持續監聽機制的。
Uvicorn啟動的關鍵代碼片段包含server = await loop.create_server(…)。 這行代碼并非直接創建了一個監聽循環,而是利用了python的asyncio庫提供的異步事件循環機制。loop.create_server函數異步地創建一個TCP服務器,并將其注冊到asyncio的事件循環中。
asyncio事件循環本身就是一個無限循環,持續監聽網絡事件,包括新的連接請求。當新的連接到達時,asyncio會自動調用create_server中指定的協議處理函數(在Uvicorn中,這是處理ASGI請求的函數)來處理該連接。 因此,Uvicorn并非通過顯式的serve_forever()來實現持續監聽,而是巧妙地利用了asyncio事件循環的機制。
需要注意的是,示例代碼中,如果沒有async with server:和await server.serve_forever(),asyncio.run(main())函數執行完畢后,asyncio事件循環會終止,導致服務器停止監聽。添加這兩行代碼實際上是手動控制asyncio事件循環的運行,這并非Uvicorn本身的運行機制,而是為了在特定場景下更精細地控制服務器生命周期。 Uvicorn本身充分利用asyncio的特性,將服務器監聽和請求處理集成到事件循環中,無需顯式調用serve_forever()即可實現持續監聽。loop = asyncio.get_running_loop()獲取了asyncio的當前運行事件循環,正是這個事件循環保證了Uvicorn的持續運行。