Workers與背景任務 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
內容目錄
A. 簡介
雖然通道層主要是為了在不同的 ASGI 應用實例之間進行通信設計的,但它們也可以用於將工作卸載到一組聆聽固定通道名稱的工作伺服器上,作為一個簡單的、非常低延遲的任務隊列。
Channels 的Worker/背景任務系統簡單且非常快速,這是因為它缺少了一些可能對你有用的功能,例如重試機制或返回值。我們建議將其用於不需要完成保證的工作(最多一次傳遞)。而對於需要更多保證的工作,則考慮使用一個單獨的專用任務隊列。這個功能不適用於內存中的通道層。
設定背景任務分為兩個部分 – 發送事件,以及設置消費者以接收和處理事件。
B. 發送事件
要發送事件,只需將其發送到一個固定的通道名稱。例如,假設我們想要一個預先快取縮略圖的背景處理程序:
# Inside a consumer
self.channel_layer.send(
"thumbnails-generate", # channel name
{
"type": "thumbnails.gen",
"id": 123456789,
},
)
請注意,您發送的事件必須包含一個 `type` 鍵,即使在通道上僅發送一種類型的訊息,因為這將轉變為消費者必須處理的事件。此外,請記住,如果您是在同步環境中發送事件,則必須使用 `asgiref.sync.async_to_sync
` 包裝器,就如同在Channel Layers中指定的那樣。
C. 接收事件與編寫Consumer
Channels 會將傳入的工作者任務作為事件呈現給你,這些事件位於一個具有 `channel` 類型的範疇(scope)中,並且具有與通道名稱匹配的通道鍵。建議使用 `ProtocolTypeRouter` 和 `ChannelNameRouter`(參見Router部分以獲取更多信息)來安排你的消費者:
application = ProtocolTypeRouter({
...
"channel": ChannelNameRouter({
"thumbnails-generate": consumers.GenerateConsumer.as_asgi(),
}),
})
當你發送事件時,你需要自行指定各個事件的類型值,所以需要決定你的命名並撰寫相應的消費者。舉個例子,以下是一個基礎的消費者,它預期處理類型為 thumbnails.gen 的事件,event接收事件資訊:
class GenerateConsumer(SyncConsumer):
def thumbnails_gen(self, event):
print(f"thumbnails generate for ", event['id'])
一旦你連接了消費者,你只需要運行一個處理它們的過程。由於這裡不涉及任何連接,因此無需使用協議伺服器,Channels 提供了 `runworker` 命令來達成這個目的。
先在在 INSTALLED_APPS
中加入channels
,不然會出現 Unknown command: 'runworker'
的錯誤訊息,這個部分在官方文件並無提及,如果遇到可嘗試這個方法。
接著執行 runworker
指令:
python manage.py runworker thumbnails-generate
請注意,`runworker
` 只會監聽您在命令列中傳遞給它的頻道。如果您未包含任何頻道,或忘記執行工作者,您的事件將無法被接收和處理。
D. Django Channels 的 Worker 與 Celery 的選擇時機
當在 Django 專案中,需要處理背景任務或非同步操作時,選擇合適的工具是至關重要的。Django Channels 和 Celery 是兩種常用的解決方案,但它們的應用場合有所不同,因此了解它們各自的優勢和使用場景可以幫助開發者做出最佳選擇。
1. Channels 的 Worker
Django Channels 提供了一種對 Django 應用進行非同步處理的方式,它是基於事件驅動的架構,主要針對 WebSocket 以及長連接等場景。Channels 的 Workers 可用來處理異步請求,管理多用戶連結,或處理需要即時響應的任務。
1-1. 適用場合
- 即時通訊:如聊天應用,即時遊戲,或即時通知。
- WebSocket 連接:任何需要長時間保持連接的應用。
- 需要即時響應的應用:如追蹤用戶活動或更新即時數據。
1-2. 優勢
- 與 Django 緊密集成,對於需要處理 WebSocket 的應用特別有用。
- 簡化了需要即時性和持久連接特性的應用開發。
2. Celery
Celery 是一個專注於分發和處理任務的背景作業系統,特別適合需要處理大量計算密集型任務或需要排程(如定時運行)的應用場景。Celery 對任務的排程和重試機制非常成熟,適合用於需要可靠執行的長任務。
2-1. 適用場合
- 計算密集型工作:例如生成報表,圖片處理,或數據分析。
- 定時任務:如夜間批量作業,或定時的數據同步。
- 大規模的後台數據處理:如電子郵件發送,或背景數據庫更新。
2-2. 優勢
- 支持多種資料庫後端(如 RabbitMQ, Redis)作為隊列管理。
- 健全的重試機制和狀態跟踪功能。
3. 選擇建議
如果應用需要:
- 即時、雙向通信或處理 WebSocket 相關的任務,建議選擇 Django Channels。
- 長時間運行的、批量或計算密集型任務,建議選擇 Celery。
最終,根據專案的需求,可能還會考慮將這兩者結合使用。比如,使用 Channels 處理即時通信,同時讓 Celery 處理需要的長時間或定時的背景任務。這樣可以最大化利用每個工具的優勢,滿足各類型任務的性能需求。
E. 總結
在現代的 Django 專案中,異步處理和背景任務是越來越重要的需求,這使得選擇合適的工具來滿足不同的應用場景變得至關重要。透過 Django Channels 和 Celery,開發者擁有了處理即時性和排程任務的靈活選擇。
Django Channels 提供了一種處理非同步通信和長連接協議的方式,特別適合需要實時響應的應用程序,例如即時通訊、WebSocket 連接和多用戶互動的應用。Channels 簡便的 Worker 系統雖然缺乏一些高級功能(如重試機制),但它的低延遲特性使其成為即時應用的理想選擇。
另一方面,Celery 是一個專注於可靠任務調度和執行的背景作業系統,非常適合大規模的計算密集型任務或需要排程的操作。它強大的重試機制和支持多種資料庫後端(如 RabbitMQ、Redis),使其成為負責任和持久性後台任務的首選。
總結而言,若專案需要即時的雙向通信或與 WebSocket 相關的功能,Django Channels 是最佳選擇;而對於長時間運行的批量處理或計算密集型任務,Celery 則提供了更為專業的支持。根據具體需求,開發者還可以考慮將兩者結合使用,以充分利用每個工具的優勢來實現卓越的性能和效率。
F. 系列文章
-
簡介 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
Django Channels 是擴展 Django 的一個框架,它增加了非同步支持和長連接協議支持,包括 WebSockets 和 MQTT,適合需要持久連接的應用場景。相對於WSGI,ASGI 支… [閱讀全文]
-
實時更新的多人聊天室 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
文章介紹了如何使用 Django Channels 在 Django 架構中建立即時更新的多人聊天室。文章首先講解了安裝 Channels 這個套件的基本步驟,包括 Django 專案初始化、安裝相關… [閱讀全文]
-
Consumers深入說明 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
文章中根據官方文件對Consumer的說明,簡單的翻譯成了繁體中文,同時也增加了些許補充。文章探討了 Django Channels 中 Consumers 的使用,強調其在支持異步通信和長連接協議上… [閱讀全文]
-
資料庫存取 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
ASGI_THREADS, AsyncConsumer, close_old_connections, database_sync_to_async, django channels, Django ORM, SyncConsumer在 Django Channels 中,當處理資料庫存取時,需要區分同步和異步操作。同步消費者不需要額外處理,但異步消費者需使用 `database_sync_to_async` 或異步模型方法來安全… [閱讀全文]
-
Routing – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
Django Channels 提供了處理異步通信和長連接的能力,通過使用 ASGI 路由器來靈活地管理連接。核心元件包括 `ProtocolTypeRouter`,用於協議類型分派,如 HTTP 和… [閱讀全文]
-
Channel Layers – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
async_to_sync, channel, channel layer, channel layer specification, django channels, group, redis channel layer本文探討了 Django Channels 的通道層(Channel Layers),其允許應用實例之間進行非同步通信,適合用於分散式實時應用。通道層透過 `CHANNEL_LAYERS` 配置,支持… [閱讀全文]
-
Sessions、身份驗證、安全性 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
authentication, channels-auth-token-middlewares, csrf, django channels, security, SessionMiddlewareStack, sessionsDjango Channels 支援異步通訊,並在會話、身份驗證和安全性上提供解決方案。它使用 SessionMiddlewareStack 來簡化會話管理,並透過 AuthMiddleware 支援… [閱讀全文]
-
Workers與背景任務 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
Django Channels 和 Celery 是兩種用於處理背景任務和非同步操作的工具,各有其特定優勢。Django Channels 適用於即時通訊、WebSocket 連接和需要即時響應的應用… [閱讀全文]
-
部署 – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
部署 Django Channels(ASGI)應用程式類似於 WSGI,主要需要載入至伺服器如 Daphne,並可以設定通道層,通常會使用 Redis 伺服器。應用程式運行在協議伺服器中,兼容 HT… [閱讀全文]
-
ASGI – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統
ASGI(非同步伺服器網關介面)是一個規範,用於解綁Django Channels應用程式與特定伺服器,提供撰寫應用程式和中介軟體的共同方式。它採用一個異步可調用函數,包括範圍(Scope)字典、接收… [閱讀全文]