分享方式:


使用資源記錄來監視 SignalR 服務

本文說明如何使用 Azure 監視器功能來分析和疑難排解 Azure SignalR 所產生的資源記錄監視資料。

每個 Azure SignalR Service 的 Azure 入口網站中的 [概觀] 頁面包含資源使用量的簡短檢視,例如並行連線和訊息計數。 這項實用資訊只是入口網站中提供的少量監視資料。 其中有些資料會自動進行收集,並可在您建立資源時立即進行分析。

在完成一些設定後,您可以啟用其他類型的資料收集。 本文會逐步解說如何使用 Azure 監視器工具來設定記錄資料收集及分析換疑難排解此資料。

必要條件

若要啟用資源記錄,您必須設定儲存記錄資料的位置,例如 Azure 儲存體或 Log Analytics。

  • Azure 儲存體會保留用於原則稽核、靜態分析或備份的資源記錄。
  • Log Analytics 是彈性的記錄搜尋和分析工具,可讓您分析 Azure 資源所產生的原始記錄。

啟用資源記錄

Azure SignalR Service 支援連線記錄、傳訊記錄和 HTTP 要求記錄。 如需這些記錄類型的更多詳細資料,請參閱資源記錄類別。 記錄會儲存在 [診斷記錄] 窗格中所設定的儲存體帳戶。 如需儲存體格式和欄位的更多詳細資料,請參閱資料儲存體

建立診斷設定

資源記錄預設為停用。 若要使用診斷設定來啟用資源記錄,請參閱在 Azure 監視器中建立診斷設定

查詢資源記錄

若要查詢資源記錄,請遵循下列步驟操作:

  1. 在目標 Log Analytics 中,選取 [記錄]

    Log Analytics 功能表項目

  2. 輸入 SignalRServiceDiagnosticLogs 並選取時間範圍。 如需進階查詢,請參閱開始使用 Azure 監視器中的 Log Analytics

    Log Analytics 中的查詢記錄

若要使用 Azure SignalR Service 的範例查詢,請遵循下列步驟:

  1. 在目標 Log Analytics 中,選取 [記錄]

  2. 選取 [查詢] 索引標籤以開啟查詢總管。

  3. 選取 [資源類型] 以將資源類型的範例查詢分組。

  4. 選取 [執行] 以執行指令碼。

    Log Analytics 中的範例查詢

如需 Azure SignalR Service 的範例查詢,請參閱 SignalRServiceDiagnosticLogs 資料表的查詢

注意

儲存體目的地的查詢欄位名稱與 Log Analytics 的欄位名稱略有不同。 如需儲存體與 Log Analytics 資料表之間欄位名稱對應的詳細資料,請參閱資源記錄資料表對應

使用資源記錄進行疑難排解

若要針對 Azure SignalR Service 進行疑難排解,您可以啟用伺服器端/用戶端記錄來擷取失敗。 當 Azure SignalR Service 公開資源記錄時,您可以利用資源記錄來針對服務的記錄進行疑難排解。

當您遇到連線意外成長或中斷時,您可以利用連線記錄進行疑難排解。 一般問題通常涉及非預期的連線數量變更、連線達到連線限制,以及授權失敗。 下列各節說明如何進行疑難排解。

未預期的連線中斷

如果您遇到意外的連線中斷,請先啟用服務、伺服器和用戶端中的記錄。

如果中斷連線,則資源記錄會記錄此中斷連線事件,您將會在 operationName 中看到 ConnectionAbortedConnectionEnded

ConnectionAbortedConnectionEnded 之間的差異在於,ConnectionEnded 是用戶端或伺服器端所觸發的預期中斷連線。 ConnectionAborted 通常是非預期的連線中斷事件,會在 message 中提供中止原因。

下表列出中止原因。

原因 描述
連線計數達到限制 連線計數達到您目前價格區間的限制。 請考慮調整服務單位規模
應用程式伺服器已關閉連線 應用程式伺服器會觸發中止。 可將其視為預期中的中止
連線 Ping 逾時 通常是因為網路問題所造成。 請考慮檢查應用程式伺服器與網際網路的可用性
服務重新載入,嘗試重新連線 Azure SignalR Service 重新載入。 Azure SignalR 支援自動重新連線,您可以等待重新連線,或手動重新連線至 Azure SignalR Service
內部伺服器暫時性錯誤 Azure SignalR Service 中發生暫時性錯誤,應該會自動復原
伺服器連線已中斷 伺服器連線中斷時發生未知的錯誤,請考慮先使用服務/伺服器/用戶端記錄進行自我疑難排解。 嘗試排除基本問題 (例如網路問題、應用程式伺服器端問題等等)。 如果問題未解決,請與我們連絡,以取得進一步協助。 如需詳細資訊,請參閱取得協助一節。

未預期的連線成長

若要針對非預期的連線成長進行疑難排解,您需要做的第一件事是將額外的連線篩選掉。 您可以將唯一測試使用者識別碼新增至測試用戶端連線。 檢查資源記錄。 如果您看到多個用戶端連線具有相同的測試使用者識別碼或 IP,則用戶端可能會建立較預期更多的連線。 檢查您的用戶端。

授權失敗

如果您收到 401 未經授權傳回用戶端要求,請檢查您的資源記錄。 如果您遇到 Failed to validate audience. Expected Audiences: <valid audience>. Actual Audiences: <actual audience>,表示您存取權杖中的所有對象都無效。 請嘗試使用記錄中建議的有效對象。

節流

如果您發現無法建立 Azure SignalR Service 的 SignalR 用戶端連線,請檢查您的資源記錄。 如果您在資源記錄中遇到 Connection count reaches limit,則會建立太多 SignalR Service 的連線,如此會達到連線計數限制。 請考慮相應增加您的 SignalR Service。 如果您在資源記錄中遇到 Message count reaches limit,這表示您使用的是免費層,且您耗盡訊息的配額。 如果您想要傳送更多訊息,請考慮將 SignalR Service 變更為標準層。 如需詳細資訊,請參閱 Azure SignalR Service 定價

遇到訊息相關問題時,您可以利用傳訊記錄進行疑難排解。 首先,在服務、伺服器記錄和用戶端中啟用資源記錄

注意

如需 ASP.NET Core,請參閱這裡,以啟用在伺服器和用戶端中進行記錄。

如需 ASP.NET,請參閱這裡,以啟用在伺服器和用戶端中進行記錄。

如果您不考慮潛在的效能效果,且沒有用戶端對伺服器方向訊息,請檢查 Log Source Settings/Types 中的 Messaging,以啟用全部收集記錄收集行為。 如需關於此行為的詳細資訊,請參閱全部收集

否則,取消核取Messaging 以啟用 部分收集記錄收集行為。 此行為需要在用戶端和伺服器中的設定才能加以啟用。 如需詳細資訊,請參閱部分收集

訊息遺失

如果您遇到訊息遺失問題,則重點就是找出遺失訊息的位置。 基本上,使用 SignalR 服務時,您有三個元件:SignalR 服務、伺服器和用戶端。 伺服器和用戶端都會連線到 SignalR 服務,但在交涉完成後,不會直接互相連線。 因此,您需要考慮訊息的兩個方向,而針對每個方向,您必須考慮兩個路徑:

  • 透過 SignalR 服務從用戶端到伺服器
    • 路徑 1:用戶端到 SignalR 服務
    • 路徑 2:SignalR 服務到伺服器
  • 透過 SignalR 服務從伺服器到用戶端
    • 路徑 3:伺服器到 SignalR 服務
    • 路徑 4:SignalR 服務到用戶端

訊息路徑

針對全部收集收集行為:

Azure SignalR Service 只會透過 SignalR 服務以從伺服器到用戶端的方向追蹤訊息。 追蹤識別碼會在伺服器中產生。 訊息會將追蹤識別碼帶到 SignalR 服務。

注意

如果您想要追蹤訊息並從應用程式伺服器中樞外部傳送訊息,您必須啟用全部收集收集行為,以收集非源自診斷用戶端訊息的訊息記錄。 診斷用戶端適用於全部收集部分收集的收集行為,但收集記錄的優先順序較高。 如需詳細資訊,請參閱診斷用戶端一節

藉由檢查登入伺服器和服務端,您可以輕鬆地找出訊息是否是從伺服器傳送、抵達 SignalR 服務,以及從 SignalR 服務離開。 基本上,您可以根據訊息追蹤識別碼檢查已接收已傳送的訊息是否相符,藉此判斷訊息遺失問題是否位於伺服器或以這個方向位於 SignalR 服務中。 如需詳細資訊,請參閱以下詳細資料

針對部分收集收集行為:

將用戶端標示為診斷用戶端之後,Azure SignalR Service 會雙向追蹤訊息。

您可以檢查登入伺服器和服務端,輕鬆地找出訊息是否成功傳遞伺服器或 SignalR 服務。 基本上,您可以根據訊息追蹤識別碼檢查已接收已傳送的訊息是否相符,藉此判斷訊息遺失問題是否位於伺服器或位於 SignalR 服務中。 如需詳細資訊,請參閱下列詳細資料。

訊息流程的詳細資料

針對 [透過 SignalR 服務從用戶端到伺服器] 的方向,SignalR 服務只會考慮源自診斷用戶端的叫用,也就是在診斷用戶端中直接產生的訊息,或是因間接叫用診斷用戶端而產生的服務訊息。

一旦訊息抵達 [路徑 1] 中的 SignalR 服務後,就會在 SignalR 服務中產生追蹤識別碼。 SignalR 服務會針對診斷用戶端中的每個訊息來產生記錄 Received a message <MessageTracingId> from client connection <ConnectionId>.。 一旦訊息從 SignalR 離開並到達伺服器後,SignalR 服務就會產生記錄訊息 Sent a message <MessageTracingId> to server connection <ConnectionId> successfully.。 如果您看到這兩個記錄,就可以確定訊息已成功通過 SignalR 服務。

注意

由於 ASP.NET Core SignalR 的限制,來自用戶端的訊息不包含任何訊息層級識別碼,但 ASP.NET SignalR 會為每個訊息產生叫用識別碼。 您可以使用它來對應追蹤識別碼。

然後訊息會傳遞路徑 2 中的追蹤識別碼伺服器。 伺服器會在訊息抵達時產生記錄 Received message <messagetracingId> from client connection <connectionId>

一旦訊息在伺服器中叫用中樞方法後,新的服務訊息就會產生新的追蹤識別碼。 產生服務訊息之後,伺服器會產生登入範本 Start to broadcast/send message <MessageTracingId> ...。 實際的記錄是以您的案例為基礎。 然後訊息會傳遞至路徑 3 中的 SignalR 服務。 一旦服務訊息離開伺服器,就會產生名為 Succeeded to send message <MessageTracingId> 的記錄。

注意

來自用戶端訊息的追蹤識別碼無法對應至要傳送至 SignalR 服務的服務訊息追蹤識別碼。

服務訊息抵達 SignalR 服務之後,將會產生名為 Received a <MessageType> message <MessageTracingId> from server connection <ConnectionId>. 的記錄。 然後,SignalR 服務會處理服務訊息,並傳遞至目標用戶端。 一旦訊息傳送至路徑 4 中的用戶端後,就會產生 Sent a message <MessageTracingId> to client connection <ConnectionId> successfully. 記錄。

總而言之,當訊息進出 SignalR 服務和伺服器時,將會產生訊息記錄。 您可以使用這些記錄來驗證這些元件中是否遺失訊息。

下列範例是典型的訊息遺失問題。

用戶端無法接收群組中的訊息

此問題中的一般內容是用戶端會在傳送群組訊息之後加入群組。

Class Chat : Hub
{
    public void JoinAndSendGroup(string name, string groupName)
    {
        Groups.AddToGroupAsync(Context.ConnectionId, groupName); // join group
        Clients.Group(groupName).SendAsync("ReveiceGroupMessage", name, "I'm in group"); // send group message
    }
}

例如,可能有人會在相同的中樞方法中叫用聯結群組以及傳送群組訊息。 此處的問題是 AddToGroupAsyncasync 方法。 因為沒有 AddToGroupAsyncawait 來等候其完成,所以群組訊息會在 AddToGroupAsync 完成之前傳送。 由於網路延遲,以及將用戶端加入某些群組的程序延遲,聯結群組動作可能會在群組訊息傳遞之後才完成。 若是如此,則第一個群組訊息沒有任何用戶端作為接收器,因為沒有任何用戶端已加入群組,因此會變成訊息遺失問題。

如果沒有資源記錄,您就無法得知用戶端何時加入群組,以及何時傳送群組訊息。 啟用傳訊記錄之後,您就可以比較訊息在 SignalR 服務中的抵達時間。 請執行下列步驟以進行疑難排解:

  1. 在伺服器中尋找訊息記錄,以尋找用戶端加入群組的時間以及傳送群組訊息的時間。
  2. 取得加入群組的訊息追蹤識別碼 A,以及訊息記錄中群組訊息的訊息追蹤識別碼 B。
  3. 在記錄封存目標中的訊息記錄中篩選這些訊息追蹤識別碼,然後比較其抵達時間戳記。 您發現哪些訊息會先抵達 SignalR 服務。
  4. 如果訊息追蹤識別碼 A 的抵達時間晚於 B 的抵達時間,您必須在加入群組的用戶端之前傳送群組訊息。 您必須先確定用戶端位於群組中,再傳送群組訊息。

如果 SignalR 或伺服器中的訊息遺失,請嘗試根據訊息追蹤識別碼取得警告記錄,以了解原因。 如果您需要進一步的說明,請參閱取得說明一節

收集行為的資源記錄

有兩個使用資源記錄的典型案例,特別是傳訊記錄。

可能有人會關心每個訊息的品質。 例如,這些人會區分訊息是否成功傳送/接收,或是想要記錄每個透過 SignalR 服務傳遞的訊息。

同時,其他人可能會關心效能。 這些人會注意訊息的延遲,有時會基於某些原因而需要追蹤幾個連線中的訊息,而不是所有的連線。

因此,SignalR 服務會提供兩種收集行為

  • 全部收集:收集所有連線中的記錄
  • 部分收集:收集某些特定連線中的記錄

注意

為了區分這些收集記錄與未收集記錄的連線,SignalR 服務會根據伺服器和用戶端的診斷用戶端設定,將某些用戶端視為診斷用戶端,其中一律會收集資源記錄,而其他用戶端則不會收集。 如需詳細資訊,請參閱部分收集一節

全部收集

所有連線都會收集資源記錄。 以傳訊記錄為例。 啟用此行為時,SignalR 服務會將通知傳送給伺服器,以開始產生每個訊息的追蹤識別碼。 追蹤識別碼會在訊息中帶往服務。 服務也會記錄具有追蹤識別碼的訊息。

注意

請注意,為了確保 SignalR 服務的效能,SignalR 服務不會等候並剖析從用戶端傳送的整個訊息。 因此,用戶端訊息不會記錄。 如果用戶端標示為診斷用戶端,則用戶端訊息會記錄在 SignalR 服務中。

設定指南

若要啟用此行為,請核取 [記錄來源設定] 中 [類型] 區段的核取方塊。

此行為不需要您更新伺服器端組態。 此組態變更一律會自動傳送到伺服器。

部分收集

資源記錄診斷用戶端收集。 會記錄所有訊息,包括診斷用戶端中的用戶端訊息和連線事件。

注意

診斷用戶端數目的限制為 100。 如果診斷用戶端數目超過 100,則 SignalR 服務會節流 Outnumbered 診斷用戶端。 新的但數量超過的用戶端無法連線到 SignalR 服務,且會擲回 System.Net.Http.HttpRequestException,其具有訊息 Response status code does not indicate success: 429 (Too Many Requests)。 已連線的用戶端會在不受節流原則影響的情況下運作。

診斷用戶端

診斷用戶端是邏輯概念。 任何用戶端都可以是診斷用戶端。 伺服器會控制可成為診斷用戶端的用戶端。 一旦用戶端標示為診斷用戶端之後,則會在此用戶端中啟用所有資源記錄。 若要將用戶端設定為診斷用戶端,請參閱設定指南

設定指南

若要啟用此行為,您必須設定服務、伺服器和用戶端。

服務端

若要啟用此行為,請在 [記錄來源設定] 的 [類型] 區段中取消核取特定記錄類型的核取方塊。

伺服器端

此外,也將 ServiceOptions.DiagnosticClientFilter 設定為根據來自用戶端的 HTTP 內容定義診斷用戶端的篩選。 例如,使用中樞 URL <HUB_URL>?diag=yes 建立用戶端,然後設定 ServiceOptions.DiagnosticClientFilter,以篩選診斷用戶端。 如果傳回 true,則用戶端會標示為診斷用戶端。 否則,用戶端會維持為一般用戶端。 可在您的啟動類別中將 ServiceOptions.DiagnosticClientFilter 設定如下:

// sample: mark a client as diagnostic client when it has query string "?diag=yes" in hub URL
public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services
        .AddSignalR()
        .AddAzureSignalR(o =>
        {
            o.ConnectionString = "<YOUR_ASRS_CONNECTION_STRING>";
            o.DiagnosticClientFilter = context => context.Request.Query["diag"] == "yes";
        });

    return services.BuildServiceProvider();
}
用戶端

設定 HTTP 內容,將用戶端標示為診斷用戶端。 例如,新增查詢字串 diag=yes,藉此將用戶端標示為診斷用戶端。

var connection = new HubConnectionBuilder()
    .WithUrl("<HUB_URL>?diag=yes")
    .Build();

取得協助

建議您先自行進行疑難排解。 大部分的問題都是由應用程式伺服器或網路問題所造成。 請遵循包含資源記錄的疑難排解指南基本疑難排解指南,以找出根本原因。 如果仍無法解決問題,請考慮在 GitHub 中開啟問題,或在 Azure 入口網站中建立票證。 提供:

  1. 問題發生的時間範圍大約 30 分鐘
  2. Azure SignalR Service 的資源識別碼
  3. 問題詳細資料,盡可能明確:例如,apperver 不會傳送訊息、用戶端連線中斷等等
  4. 從伺服器/用戶端所收集的記錄,以及其他可能有用的資料
  5. [選擇性] 重現程式碼

注意

如果您在 GitHub 中開啟問題,請將敏感性資訊 (例如資源識別碼、伺服器/用戶端記錄) 保密。 僅私下傳送給 Microsoft 組織中的成員。