SignalR 效能
作者: Patrick Fletcher
警告
本檔不適用於最新版的 SignalR。 請查看ASP.NET Core SignalR。
本主題描述如何在 SignalR 應用程式中設計、測量及改善效能。
本主題中使用的軟體版本
- Visual Studio 2013
- .NET 4.5
- SignalR 第 2 版
本主題的舊版
如需舊版 SignalR 的相關資訊,請參閱 SignalR 舊版。
問題和批註
請留下您喜歡本教學課程的意見反應,以及我們可以在頁面底部的批註中改善的內容。 如果您有與教學課程不直接相關的問題,您可以將問題張貼到 ASP.NET SignalR 論壇 或 StackOverflow.com。
如需 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 應用程式的事件處理常式中,或在自我裝載應用程式中 OWIN 啟動類別的 方法中
Configuration
設定Application_Start
此設定。 下列範例示範如何減少此值,以減少應用程式的記憶體使用量,以減少所使用的伺服器記憶體數量:Startup.cs 中的 .NET 伺服器程式碼,用於減少預設訊息緩衝區大小
public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here GlobalHost.Configuration.DefaultMessageBufferSize = 500; app.MapSignalR(); } }
IIS 組態設定
每個應用程式的並行要求數目上限:增加並行 IIS 要求的數目將會增加可用於處理要求的伺服器資源。 預設值為 5000;若要增加此設定,請在提升許可權的命令提示字元中執行下列命令:
cd %windir%\System32\inetsrv\ appcmd.exe set config /section:system.webserver/serverRuntime /appConcurrentRequestLimit:10000
ApplicationPool QueueLength:這是應用程式集區Http.sys佇列的要求數目上限。 當佇列已滿時,新的要求會收到 503「服務無法使用」回應。 預設值為 1000。
縮短裝載應用程式之應用程式集區中背景工作進程的佇列長度將會節省記憶體資源。 如需詳細資訊,請參閱 管理、微調和設定應用程式集區。
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 的公用程式,將效能計數器新增至伺服器。 若要安裝此公用程式,請遵循下列步驟:
在 Visual Studio 中,選取 [工具>][NuGet 套件管理員>管理方案的 NuGet 套件]
搜尋 signalr.utils,然後選取 [安裝]。
接受授權合約以安裝套件。
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 效能計數器
公用程式套件會安裝下列效能計數器。 「Total」 計數器會測量自上次應用程式集區或伺服器重新開機後的事件數目。
連接計量
下列計量會測量發生的連線存留期事件。 如需詳細資訊,請參閱 瞭解及處理連線存留期事件。
- 連線
- 連線已重新連線
- 連線中斷連線
- 連線目前
訊息計量
下列計量會測量 SignalR 所產生的訊息流量。
- 已接收的連線訊息總計
- 已傳送的連線訊息總計
- 已接收的連線訊息/秒
- 已傳送的連線訊息/秒
訊息匯流排計量
下列計量會測量透過內部 SignalR 訊息匯流排的流量,也就是所有傳入和傳出 SignalR 訊息的佇列。 訊息會在傳送或廣播時 發佈 。 此內容中的 訂閱者 是訊息匯流排上的訂閱;這應該等於用戶端數目加上伺服器本身。 配置的背景工作角色是將資料傳送至作用中連線的元件;忙碌工作者是主動傳送訊息的工作者。
- 已收到訊息匯流排訊息總計
- 接收的訊息匯流排訊息/秒
- 已發行的訊息匯流排訊息總計
- 訊息匯流排訊息已發佈/秒
- 訊息匯流排訂閱者目前
- 訊息匯流排訂閱者總計
- 訊息匯流排訂閱者/秒
- 消息匯流排配置的背景工作角色
- 訊息匯流排忙碌工作者
- 訊息匯流排主題目前
錯誤計量
下列計量會測量 SignalR 訊息流量所產生的錯誤。 無法解決中樞或中樞方法時發生中樞解決錯誤。 叫用中樞方法時,中樞調用錯誤是擲回的例外狀況。 傳輸 錯誤是在 HTTP 要求或回應期間擲回的連接錯誤。
- 錯誤:全部總計
- 錯誤:全部/秒
- 錯誤:中樞解決總計
- 錯誤:中樞解決/秒
- 錯誤:中樞調用總計
- 錯誤:中樞調用/秒
- 錯誤:傳輸總計
- 錯誤:Transport/Sec
向外延展計量
下列計量會測量向外延展提供者所產生的流量和錯誤。 此內容中的Stream是向外延展提供者所使用的縮放單位;如果使用SQL Server,則為數據表、使用服務匯流排時為主題,如果使用 Redis 則為訂用帳戶。 每個資料流程可確保已排序的讀取和寫入作業;單一資料流程是潛在的規模瓶頸,因此可以增加資料流程數目來協助降低該瓶頸。 如果使用多個資料流程,SignalR 會自動將 (分區) 訊息分散到這些資料流程,以確保從任何指定連線傳送的訊息會依序傳送。
MaxQueueLength設定可控制 SignalR 所維護的向外延展傳送佇列長度。 將它設定為大於 0 的值,會將所有訊息放在傳送佇列中,一次傳送一個訊息到設定的傳訊後板。 如果佇列的大小超過設定的長度,後續傳送的呼叫將會立即失敗,並顯示 InvalidOperationException, 直到佇列中的訊息數目再次小於設定為止。 預設會停用佇列,因為實作的幕後程式通常會有自己的佇列或流程式控制制。 在SQL Server的情況下,連線共用實際上會限制任何一次傳送的數目。
根據預設,只有一個資料流程用於 SQL Server 和 Redis,五個數據流用於服務匯流排,並停用佇列,但這些設定可以透過SQL Server和服務匯流排上的組態來變更:
.NET 伺服器程式碼,用於設定資料表計數和SQL Server背板的佇列長度
var connectionString = "(your connection string)";
var config = new SqlScaleoutConfiguration(connectionString) {
TableCount = 3,
MaxQueueLength = 50 };
GlobalHost.DependencyResolver.UseSqlServer(config);
.NET 伺服器程式碼,用於設定服務匯流排背板的主題計數和佇列長度
string connectionString = "(your connection string)";
var config = new ServiceBusScaleoutConfiguration(connectionString, "YourAppName") {
TopicCount = 3,
MaxQueueLength = 50 };
GlobalHost.DependencyResolver.UseServiceBus(config);
緩衝資料流程是已進入錯誤狀態的資料流程;當資料流程處於錯誤狀態時,所有傳送到備份板的訊息都會立即失敗,直到資料流程不再發生錯誤為止。 傳送佇列長度是已張貼但尚未傳送的訊息數目。
- 已接收向外延展訊息匯流排訊息/秒
- 向外延展資料流程總計
- 向外延展資料流程已開啟
- 向外延展資料流程緩衝
- 相應放大錯誤總計
- 相應放大錯誤/秒
- 向外延展傳送佇列長度
如需這些計數器所測量內容的詳細資訊,請參閱SignalR Scaleout with Azure 服務匯流排。
使用其他效能計數器
下列效能計數器在監視應用程式的效能時也很有用。
記憶體
- w3wp) 的所有堆積 (.NET CLR Memory\# 位元組
ASP.NET
- ASP.NET\Requests Current
- ASP.NET\Queued
- ASP.NET\Rejected
CPU
- 處理器資訊\處理器時間
TCP/IP
- TCPv6/Connections 已建立
- TCPv4/Connections 已建立
Web 服務
- Web 服務\目前的連線
- Web 服務\連線上限
執行緒
- 目前邏輯執行緒的 .NET CLR 鎖定和執行緒\#
- 目前實體執行緒的 .NET CLR 鎖定和執行緒\#
其他資源
如需 ASP.NET 效能監視和微調的詳細資訊,請參閱下列主題: