SignalR 效能 (SignalR 1.x)

作者 :Patrick Fletcher

警告

本檔不適用於最新版的 SignalR。 看看ASP.NET Core SignalR

本主題描述如何在 SignalR 應用程式中設計、測量及改善效能。

如需 SignalR 效能和調整的最新簡報,請參閱 使用 ASP.NET SignalR 調整即時 Web

本主題包含下列幾節:

設計考量

本節描述可在 SignalR 應用程式設計期間實作的模式,以確保產生不必要的網路流量不會阻礙效能。

節流訊息頻率

即使在以高頻率傳送訊息的應用程式中, (例如即時遊戲應用程式) ,大部分的應用程式不需要每秒傳送多個訊息。 若要減少每個用戶端產生的流量,可以實作訊息迴圈,讓佇列和傳送訊息的頻率不超過固定速率 (,也就是說,如果該時間間隔中有訊息要傳送) ,則最多會每秒傳送一些訊息。 如需從用戶端和伺服器) 將訊息節流至特定速率 (的範例應用程式,請參閱 使用 SignalR 的高頻率即時

減少訊息大小

您可以藉由減少序列化物件的大小來減少 SignalR 訊息的大小。 在伺服器程式碼中,如果您要傳送包含不需要傳輸之屬性的物件,請使用 屬性防止這些屬性序列化 JsonIgnore 。 屬性的名稱也會儲存在訊息中;您可以使用 屬性來縮短 JsonProperty 屬性的名稱。 下列程式碼範例示範如何排除要傳送至用戶端的屬性,以及如何縮短屬性名稱:

示範 JsonIgnore 屬性的 .NET 伺服器程式碼,以排除要傳送至用戶端的資料,以及用來減少訊息大小的 JsonProperty 屬性

using Newtonsoft.Json; 
using System; 
public class ShapeModel
{
[JsonProperty("l")]
    public double Left { get; set; }
[JsonProperty("t")]
    public double Top { get; set; }
    // We don't want the client to get the "LastUpdatedBy" property
[JsonIgnore]
    public string LastUpdatedBy { get; set; }
}

為了在用戶端程式代碼中保留可讀性/可維護性,在收到訊息之後,縮寫的屬性名稱可以重新對應至人類易記的名稱。 下列程式碼範例示範將縮短的名稱重新對應到較長名稱的其中一種可能方式,方法是定義訊息合約 (對應) ,並使用 函 reMap 式將合約套用至優化的訊息類別:

將縮短的屬性名稱重新對應至人類可讀取名稱的用戶端 JavaScript 程式碼

function reMap(smallObject, contract) {
    var largeObject = {};
    for (var smallProperty in contract) {
        largeObject[contract[smallProperty]] = smallObject[smallProperty];
    }
    return largeObject;
}
var shapeModelContract = {
    l: "left",
    t: "top"
};
myHub.client.setShape = function (shapeModelSmall) {
    var shapeModel = reMap(shapeModelSmall, shapeModelContract);
    // shapeModelSmall has "l" and "t" properties  but after remapping
    // shapeModel now has "left" and "top" properties
};

您也可以使用相同的方法,在從用戶端到伺服器的訊息中縮短名稱。

減少記憶體使用量 (亦即,用於訊息物件之訊息) 的記憶體數量也可以改善效能。 例如,如果不需要 的完整 int 範圍, short 則可以改用 或 byte

由於訊息會儲存在伺服器記憶體中的訊息匯流排中,因此減少訊息的大小也可以解決伺服器記憶體問題。

調整 SignalR 伺服器以達到效能

下列組態設定可用來微調您的伺服器,以取得 SignalR 應用程式中更好的效能。 如需如何改善 ASP.NET 應用程式中效能的一般資訊,請參閱 改善 ASP.NET 效能

SignalR 組態設定

  • DefaultMessageBufferSize:根據預設,SignalR 會在每個連線的每個中樞記憶體中保留 1000 個訊息。 如果使用大型訊息,這可能會建立可藉由減少此值來減輕的記憶體問題。 您可以在 ASP.NET 應用程式的事件處理常式中,或在 Configuration 自我裝載應用程式中 OWIN 啟動類別的 方法中設定 Application_Start 此設定。 下列範例示範如何減少此值,以減少應用程式的記憶體使用量,以減少所使用的伺服器記憶體數量:

    Global.asax 中的 .NET 伺服器程式碼,用於減少預設訊息緩衝區大小

    protected void Application_Start(object sender, EventArgs e)
    {
        GlobalHost.Configuration.DefaultMessageBufferSize = 500;
    }
    

IIS 組態設定

  • 每個應用程式的並行要求數目上限:增加並行 IIS 要求的數目會增加服務要求可用的伺服器資源。 預設值為 5000;若要增加此設定,請在提升許可權的命令提示字元中執行下列命令:

    cd %windir%\System32\inetsrv\
    appcmd.exe set config /section:system.webserver/serverRuntime 
            /appConcurrentRequestLimit:10000
    

ASP.NET 組態設定

本節包含可在檔案中設定的 aspnet.config 組態設定。 根據平臺,此檔案位於兩個位置的其中一個:

  • %windir%\Microsoft.NET\Framework\v4.0.30319\aspnet.config
  • %windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet.config

ASP.NET 可改善 SignalR 效能的設定包括:

  • 每個 CPU 的並行要求上限:增加此設定可能會降低效能瓶頸。 若要增加此設定,請將下列組態設定新增至 aspnet.config 檔案:

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <system.web>
            <applicationPool maxConcurrentRequestsPerCPU="20000" />
        </system.web>
    </configuration>
    
  • 要求佇列限制:當連線總數超過 maxConcurrentRequestsPerCPU 設定時,ASP.NET 將會使用佇列啟動節流要求。 若要增加佇列的大小,您可以增加 requestQueueLimit 設定。 若要這樣做,請將下列組態設定新增至 processModel (中的 config/machine.config 節點,而不是 aspnet.config) :

    <processModel autoConfig="false" requestQueueLimit="250000" />
    

針對效能問題進行疑難排解

本節說明在應用程式中尋找效能瓶頸的方式。

確認正在使用 WebSocket

雖然 SignalR 可以使用各種傳輸進行用戶端與伺服器之間的通訊,但 WebSocket 提供顯著的效能優勢,而且如果用戶端和伺服器支援它,則應該使用。 若要判斷您的用戶端和伺服器是否符合 WebSocket 的需求,請參閱 傳輸和後援。 若要判斷應用程式中所使用的傳輸,您可以使用瀏覽器開發人員工具,並檢查記錄來查看連線所使用的傳輸。 如需在 Internet Explorer 和 Chrome 中使用瀏覽器開發工具的詳細資訊,請參閱 傳輸和後援

使用 SignalR 效能計數器

本節說明如何啟用和使用套件中找到的 Microsoft.AspNet.SignalR.Utils SignalR 效能計數器。

安裝signalr.exe

效能計數器可以使用名為 SignalR.exe 的公用程式新增至伺服器。 若要安裝此公用程式,請遵循下列步驟:

  1. 在 Visual Studio 中,選取[工具>][NuGet 套件管理員>] [管理方案的 NuGet 套件]

  2. 搜尋 signalr.utils,然後選取 [安裝]。

    此螢幕擷取畫面顯示已醒目提示 S P 點 NET Signal R 的 Microsoft A P 點 NET Signal R 公用程式命令列公用程式。

  3. 接受授權合約以安裝套件。

  4. SignalR.exe將會安裝至 <project folder>/packages/Microsoft.AspNet.SignalR.Utils.<version>/tools

使用 SignalR.exe 安裝效能計數器

若要安裝 SignalR 效能計數器,請使用下列參數在提升許可權的命令提示字元中執行SignalR.exe:

SignalR.exe ipc

若要移除 SignalR 效能計數器,請使用下列參數在提升許可權的命令提示字元中執行SignalR.exe:

SignalR.exe upc

SignalR 效能計數器

公用程式套件會安裝下列效能計數器。 「總計」計數器會測量自上次應用程式集區或伺服器重新開機後的事件數目。

連接計量

下列計量會測量發生的連線存留期事件。 如需詳細資訊,請參閱 瞭解及處理連線存留期事件

  • 連線
  • 已重新連線
  • 連線中斷連線
  • 連線目前

訊息計量

下列計量會測量 SignalR 所產生的訊息流量。

  • 已收到連線訊息總計
  • 已傳送連線訊息總計
  • 已接收的連接訊息/秒
  • 已傳送的連線訊息/秒

訊息匯流排計量

下列計量會透過內部 SignalR 訊息匯流排來測量流量,這是放置所有傳入和傳出 SignalR 訊息的佇列。 訊息會在傳送或廣播時 發佈 。 此內容中的 訂閱者 是訊息匯流排上的訂用帳戶;這應該等於用戶端數目加上伺服器本身。 已配置的背景工作角色是將資料傳送至作用中連線的元件;忙碌背景工作角色是主動傳送訊息的背景工作角色。

  • 已收到訊息匯流排訊息總計
  • 接收的訊息匯流排訊息/秒
  • 訊息匯流排訊息已發佈總計
  • 訊息匯流排訊息已發佈/秒
  • 訊息匯流排訂閱者目前
  • 訊息匯流排訂閱者總計
  • 訊息匯流排訂閱者/秒
  • 訊息匯流排配置的背景工作
  • 訊息匯流排忙碌工作者
  • 訊息匯流排主題目前

錯誤計量

下列計量會測量 SignalR 訊息流量所產生的錯誤。 無法解決中樞或中樞方法時發生中樞解決錯誤。 中樞調用 錯誤是在叫用中樞方法時擲回的例外狀況。 傳輸 錯誤是在 HTTP 要求或回應期間擲回的連接錯誤。

  • 錯誤:所有總計
  • 錯誤:全部/秒
  • 錯誤:中樞解決總計
  • 錯誤:中樞解析/秒
  • 錯誤:中樞調用總計
  • 錯誤:中樞調用/秒
  • 錯誤:傳輸總計
  • 錯誤:Transport/Sec

向外延展計量

下列計量會測量向外延展提供者所產生的流量和錯誤。 此內容中的Stream是向外延展提供者所使用的縮放單位;如果使用 SQL Server,這是資料表、使用服務匯流排時的主題,以及使用 Redis 的訂用帳戶。 根據預設,只會使用一個資料流程,但是這可以透過SQL Server和服務匯流排上的組態來增加。 緩衝資料流程是已進入錯誤狀態的資料流程;當資料流程處於錯誤狀態時,傳送至幕後程式的所有訊息都會立即失敗,直到資料流程不再發生錯誤為止。 傳送佇列長度是已張貼但尚未傳送的訊息數目。

  • 接收的相應放大訊息匯流排訊息/秒
  • 相應放大串流總計
  • 向外延展資料流程開啟
  • 向外延展資料流程緩衝
  • 相應放大錯誤總計
  • 相應放大錯誤/秒
  • 相應放大傳送佇列長度

如需這些計數器測量內容的詳細資訊,請參閱具有Azure 服務匯流排的 SignalR Scaleout

使用其他效能計數器

下列效能計數器在監視應用程式的效能時可能也很有用。

記憶體

  • w3wp) 的所有堆積 (.NET CLR 記憶體# 位元組

ASP.NET

  • ASP.NET\Requests Current
  • ASP.NET\Queued
  • ASP.NET\拒絕

CPU

  • 處理器資訊\處理器時間

TCP/IP

  • TCPv6/Connections 已建立
  • TCPv4/已建立連線

Web 服務

  • Web 服務\目前的連線
  • Web 服務\連線上限

執行緒

  • 目前邏輯執行緒的 .NET CLR LocksAndThreads#
  • 目前實體執行緒的 .NET CLR LocksAnd Threads#

其他資源

如需有關 ASP.NET 效能監視和微調的詳細資訊,請參閱下列主題: