Azure 的 ASP.NET SignalR

Dino Wang (王育民) /hexdigits.com

在 One ASP.NET 的架構方塊圖中,微軟將 WebAPI 和 SignalR 歸類到 Services 類型與 MVC、Web Forms 同列為一級公民,未來的 ASP.NET vNext 儘管還在早期階段,由釋出的架構圖中可以發現原來就非常相似的 MVC 與 WebAPI 統一合併到 MVC 的大框架中了,而 SignalR 在未來依然在 Services 扮演著重要的角色。

SignalR 是一個集成了多種 HTTP 通訊方式並且優先使用 HTML5 Web Sockets 作為即時通訊管道的技術,在過往文章中常提及[1],而其設計架構相當清晰易懂,在 ASP.NET 中作為提供即時訊息通訊服務層的重要地位由此可見。

另一個方面來看,在微軟 "Cloud First, Mobile First" 的策略中,位於要角的 Microsoft Azure 以不停演化的完整架構以及多年累積的用戶實證,在在說明了 Microsoft Azure 是成為雲端開發人員的重要入口,其相關開發技術已經進入到 ASP.NET 開發者技能清單中一哥的位置,筆者在TechDays Taiwan 2014後,很榮幸受邀為本期MSDN 電子報客座編輯,來為大家介紹在 Microsoft Azure 上開發 SignalR 應用程式是多麼的方便以及合作無間。

環境

開發 SignalR 應用程式前,應該認識 SignalR 技術對執行環境有一些基本要求,執行現行的SignalR 2.0 需要有 .NET Framework 4.5,伺服器端需要 Windows Server 2008 R2 以上的作業系統以及 IIS7,若要使用 Web Sockets 來使 SignalR 技術得到最好的發揮,則應該執行於 Windows Server 2012 和 IIS 8 (開發環境需要 Windows 8 和 IIS 8 Express),因為 IIS 8 以上才可選裝 Web Sockets 擴充元件。所幸應用程式若最終將部署至Microsoft Azure 雲端環境,您可以不必大費周章地準備以上環境,具備大致的認識即可,

在 Microsoft Azure 中 ASP.NET 網站應用程式的三個主要部署方式為 Websites、Cloud Service、Virtual Machine。一般網站應用程式可選擇 Websites,若需要對執行環境進行客製化則可選擇Cloud Service,或者選擇 Virtual Machine部署一個完全自己掌握的執行環境。

使用以上的 Websites、Cloud Service 時,Azure 對於管理工作上的要求都是非常輕盈的,您可以藉著 Management Portal 完成相關設定。

Websites 網站

目前 Azure 上有新舊兩個 Portal,由於沒有明確的定名,以下統一就直接以舊 Portal、新Portal 稱呼。

舊Portal 的設定方式

進入到您的 Websites 管理頁面,如圖切換到 [設定] 頁面,尋找 [WEB 通訊端] 項目,將其設定為 [開啟] ,然後按下下方的 [儲存] 按鈕即可,這個動作可以在短短十幾秒內完成,相當的簡單。

NOTE: 筆者經常被詢問找不到 Websites 上開啟 Web Socket 功能的界面,主要都是因為中文譯名的關係,如果您切換到英文界面,相信也會跟筆者一樣頓時豁然開朗。

新Portal的設定方式

請先點擊左側 Charm bar 上的 [BROWSE],在選單中點選 [Websites] 選項打開 Websites 管理清單,選擇您的 Websites 應用程式後會出現一個新的控制面板,捲動到最下方可以發現 [Site
settings] 動態磚,點擊 [Site settings] 動態磚,在新開啟的 Site settings 面板中尋找 WEB SOCKETS 選項,並且將之開啟,最後切記按下位於面板上方的 [Save] 按鈕。

NOTE: 由於新版 Portal 還不具備中文界面,暫時沒有 WEB 通訊端/WEB SOCKETS 的譯文識別問題。

Cloud Service 雲端服務

Cloud Service 預設在所有 instance 中自動地啟用 Web Sockets 項目,所以您可以直接部署使用 SignalR 技術的網站應用程式,不需要進行設定就可得到最好的連線效能。

Virtual Machine 虛擬機器

在虛擬機中開啟 Web Sockets 的設定方式與一般 Windows 2008/2012 Server 的上管理設定方式相同,本篇就不再贅述。

連線管理

在 SignalR 中有一項十分重要的能力,即為「自動化的連線管理」,自動化的連線管理是在執行期間當用戶端意外離線時,SignalR Client Library 會在固定時間內自動地嘗試重新建立連線以恢復與 Server 的對話狀態,這個特性在現在的環境下顯得十分重要,以下就舉兩個十分容易理解的場景:

移動連線

行動載具的網路連線狀態向來若桌面環境不穩定,可能隨時因為收訊位置或是連線載具變得稠密(像是捷運上)而發生時間不一的斷線情況,自動化的連線管理能夠在這樣的場景下得到不錯的使用體驗。

更新部署

另外一方面來看,造成斷線的情況也不一定只有用戶端會發生,當應用程式重啟或者伺服器端處於軟體更新、停機維運狀態,也會造成斷線,後者更有可能產生長時間的網站離線狀態。

所幸 Microsoft Azure 以 Production/Staging 的環境切換來避免伺服器端軟體更新可能造成的網站長時間停止服務。

這項設計讓維運人員在部署階段對 Staging 環境作業,確保測試一切正常後,再執行 VIP SWAP 動作將 Production/Staging 環境進行對調以得到最短的維護離線狀態,也就是在 IP 位置不改變的情況下更換了伺服器來提供服務,不知道您意識到了嗎?SignalR Client Library 在這樣的情況下會經歷斷線重連的階段而且依舊執行得非常良好,保持與「當下」的 Production 環境連線狀態喔。

不過值得注意的是雖然 SignalR Client Library自動地處理了斷線重連,但由於 Web Role instance 實體已經被完全置換,在架構上如果沒有相對應的設計(儲存體外移),可能會造成原來運作中SignalR 部分訊息的漏失,在下一段將說明 SignalR 中的 Backplane 機制來避免這種情況下訊息可能漏失的情況。

SignalR Backplane

Backplane 是 SignalR 基於 publish/subscribe (以下簡稱 pub/sub) pattern 設計下的系統延展架構,Backplane 將「訊息」自「instance 內部」移出到「外部儲存體」中,讓狀態不再侷限於 instance 個體上,以提供 SignalR Server scaleout 的能力,達到支援 Web Farm 架構。

上圖以分解動作說明了SignalR 是如何的運用 Backplane 架構實作 pub/sub pattern。首先由接受到訊息請求的SignalR Server 將訊息儲存到 Backplane 上?,再由多部 SignalR Server 處理訊息的接收與發送‚,最後送抵 SignalR Client 端ƒ。

由於Backplane 架構的第一項特徵便是將儲存體外移(動作?),對於 Web Farm架構是必須有的作為,然而在單一 Azure instance 時也能從其中得到好處,可以不必擔心應用程式部署 VIP SWAP 時可能發生的訊息漏失問題,對於處理訊息敏感的應用程式來說,這點來說相當地重要。

在 Azure 有多種支持 Backplane 訊息向外儲存的方式,包含了 SQL Server、Service Bus 以及 Redis Cache,以下針對這三種擴充方式進一步的說明。

SQL Server

透過簡單的設定,開發人員所熟知的 SQL Database (或 SQL Server) 就能夠用來儲存 SignalR 訊息到表格中,接著由 Service Broker 來有效的轉送訊息到系統中所有的 SignalR Server 處理(註:Server Broker 是為了增加效率,沒有 Service Broker 也能夠正常運作)。

 

開發人員獲得以 SQL Server 延展 SignalR 服務的方式是透過 nuget 在專案中取得 Microsoft.AspNet.SignalR.SqlServer 套件,給予可提供儲存資料的 SQL Database 儲存個體的連線字串即可,SQL Database 執行個體上不需預先建立表格,所需要的 table schema 會由 SQL Server 套件自動建立完成。

詳細的實作資訊,可由 ASP.NET 官網所提供的 SignalR Scaleout with SQL Server 文章中獲得。值得注意的是當使用 SQL Server 作為訊息儲存體,目前在訊息轉送的效率上較其他方案低上一些。

Service Bus

service Bus 是一項在 Azure 中重要的基礎結構,提供了 Queue、Topic、Relay 以及 Notification Hub 等功能。其中 Topics 正是一個與 SignalR Backplane pub/sub pattern相同設計的典型服務。

 

詳細的實作資訊,可由 ASP.NET 官網所提供的 SignalR Scaleout with Azure Service Bus 文章中獲得。 

Redis Cache 

Redis 是在記憶體內以鍵值 (key-value) 對方式儲存的資料的服務,Redis 也支援 pub/sub pattern 來提供訊息服務。詳細的實作資訊,可由 ASP.NET 官網所提供的 SignalR Scaleout with Redis 文章中獲得。

Redis 利用記憶體的運作方式使得它是一個低延遲、高傳輸量的 Backplane 架構,另外 Azure 所提供的 Redis Cache 服務也已在 2014/10 正式 GA (General Availability) 了,標準等級的 Redis Cache 具有兩個節點可用度達到 99.9% SLA。

結語

ASP.NET SignalR 實在是個設計的非常漂亮的軟體架構,與本文中介紹的 Azure 諸項特點更是結合的恰到好處,無論是 WebApp、Mobile App甚或是 Desktop App,凡於訊息處理的即時性與可用性十分重視的應用程式,都可以運用 SignalR + Azure 架構出可用性非常高的即時互動體驗。