Производительность SignalR

Патрик Флетчер

Предупреждение

Эта документация не для последней версии SignalR. Взгляните на ASP.NET Core SignalR.

В этом разделе описывается проектирование, измерение и повышение производительности в приложении SignalR.

Версии программного обеспечения, используемые в этом разделе

Предыдущие версии этого раздела

Сведения о более ранних версиях SignalR см. в разделе Старые версии SignalR.

Вопросы и комментарии

Оставьте отзыв о том, как вам понравилось это руководство и что мы могли бы улучшить в комментариях в нижней части страницы. Если у вас есть вопросы, которые не связаны напрямую с руководством, вы можете опубликовать их на форуме ASP.NET SignalR или StackOverflow.com.

Недавнюю презентацию о производительности и масштабировании SignalR см. в статье Масштабирование интернета в режиме реального времени с помощью ASP.NET SignalR.

Этот раздел состоит из следующих подразделов.

Рекомендации по проектированию

В этом разделе описываются шаблоны, которые можно реализовать во время разработки приложения SignalR, чтобы гарантировать, что производительность не будет препятствовать созданию ненужного сетевого трафика.

Частота сообщений регулирования

Даже в приложении, которое отправляет сообщения с высокой частотой (например, в игровом приложении в реальном времени), большинству приложений не нужно отправлять более нескольких сообщений в секунду. Чтобы уменьшить объем трафика, генерируемого каждым клиентом, можно реализовать цикл сообщений, который помещает в очередь и отправляет сообщения не чаще, чем фиксированная частота (т. е. до определенного количества сообщений будет отправляться каждую секунду при наличии сообщений в этот интервал времени). Пример приложения, которое регулирует сообщения с определенной скоростью (как от клиента, так и от сервера), см. в разделе Высокочастотный режим реального времени с SignalR.

Уменьшение размера сообщения

Вы можете уменьшить размер сообщения SignalR, уменьшив размер сериализованных объектов. Если в коде сервера вы отправляете объект, содержащий свойства, которые не нужно передавать, запретите сериализацию этих свойств с помощью атрибута JsonIgnore . Имена свойств также хранятся в сообщении; имена свойств можно сократить с помощью атрибута JsonProperty . В следующем примере кода показано, как исключить свойство из отправки клиенту и как сократить имена свойств:

Код сервера .NET, демонстрирующий атрибут JsonIgnore для исключения данных из отправки клиенту, и атрибут 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 сообщений на каждый концентратор для каждого подключения. Если используются большие сообщения, это может привести к проблемам с памятью, которые можно устранить, уменьшив это значение. Этот параметр можно задать в обработчике Application_Start событий в приложении ASP.NET или в Configuration методе класса запуска OWIN в локальном приложении. В следующем примере показано, как уменьшить это значение, чтобы уменьшить объем памяти приложения, чтобы уменьшить объем используемой памяти сервера:

    Код сервера .NET в Файле Startup.cs для уменьшения размера буфера сообщений по умолчанию

    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, включают следующие:

  • Максимальное количество одновременных запросов на ЦП. Увеличение этого параметра может устранить узкие места производительности. Чтобы увеличить этот параметр, добавьте в файл следующий параметр конфигурации 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 Обозреватель и Chrome см. в статье Транспорты и резервные варианты.

Использование счетчиков производительности SignalR

В этом разделе описывается, как включить и использовать счетчики производительности SignalR, которые находятся в пакете Microsoft.AspNet.SignalR.Utils .

Установка signalr.exe

Счетчики производительности можно добавить на сервер с помощью служебной программы SignalR.exe. Чтобы установить эту служебную программу, выполните следующие действия.

  1. В Visual Studio выберите Инструменты> Диспетчер >пакетов NuGetУправление пакетами NuGet для решения.

  2. Найдите signalr.utils и выберите Установить.

    Снимок экрана: выбранный пункт Microsoft A P NET Signal R Utilities.

  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-запроса или ответа.

  • Ошибки: все итого
  • Ошибки: все/с
  • Ошибки: всего разрешения концентратора
  • Ошибки: разрешение концентратора/с
  • Ошибки: всего вызовов концентратора
  • Ошибки: вызов концентратора/с
  • Ошибки: общий объем транспорта
  • Ошибки: транспорт/с

Метрики масштабирования

Следующие метрики измеряют трафик и ошибки, созданные поставщиком масштабирования. 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 с помощью Служебная шина Azure.

Использование других счетчиков производительности

Следующие счетчики производительности также могут быть полезны для мониторинга производительности приложения.

Память

  • .NET CLR Memory\# во всех кучах (для w3wp)

ASP.NET

  • ASP.NET\Requests Current
  • ASP.NET\Queued
  • ASP.NET\Отклонено

ЦП

  • Сведения о процессоре\Время процессора

TCP/IP

  • TCPv6 и установленные подключения
  • TCPv4/Установленные подключения

Веб-служба

  • Веб-служба\Текущие подключения
  • Веб-служба\Максимальное количество подключений

Работа с потоками

  • .NET CLR Locks And Threads\# текущих логических потоков
  • .NET CLR Locks And Threads\# текущих физических потоков

Другие ресурсы

Дополнительные сведения о мониторинге и настройке производительности ASP.NET см. в следующих разделах: