0Pricing
C# Academy · Урок

Масштабирование с помощью Redis Backplane

Масштабируйте SignalR на несколько серверов с помощью Redis Backplane, синхронизируя сообщения между экземплярами.

«Масштабирование с помощью Redis Backplane» — бесплатный урок C# Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.

Проблема нескольких серверов

Когда SignalR работает на одном сервере, клиенты и сервер используют общую память для подключений и групп. При переходе на два или более серверов каждый сервер знает только о своих подключениях — сообщение, отправленное на сервере A, никогда не достигает клиентов, подключённых к серверу B.

Что такое шина сообщений?

Шина сообщений — это общая шина обмена сообщениями между экземплярами серверов SignalR. Когда один сервер хочет отправить сообщение, он публикует его в шине сообщений; все серверы получают его и пересылают своим локальным подключениям.

Добавление шины сообщений Redis

Установите пакет Microsoft.AspNetCore.SignalR.StackExchangeRedis и вызовите AddStackExchangeRedis() после AddSignalR().

// dotnet add package Microsoft.AspNetCore.SignalR.StackExchangeRedis

builder.Services.AddSignalR()
    .AddStackExchangeRedis("localhost:6379", options =>
    {
        options.Configuration.ChannelPrefix =
            RedisChannel.Literal("myapp"); // namespace your channels
    });

// Or from config:
// .AddStackExchangeRedis(builder.Configuration.GetConnectionString("Redis")!);

Как работает публикация и подписка Redis в SignalR

Каждый сервер SignalR подписывается на каналы Redis. Когда сервер A публикует сообщение для группы или пользователя, Redis доставляет его всем подписчикам (серверам B, C…), которые затем пересылают его своим локальным подключениям.

// Server A: client sends message
// Hub on Server A calls:
await Clients.Group("room-42").ReceiveMessage(user, msg);

// Internally SignalR publishes to Redis:
// PUBLISH signalr/myapp/group/room-42 <serialized message>

// Redis delivers to Server B and C
// Both servers find connections in "room-42" and push to them

Параметры конфигурации

Точно настройте подключение к Redis для рабочей среды: TLS, пароль, устойчивость соединения и префикс каналов публикации и подписки.

builder.Services.AddSignalR()
    .AddStackExchangeRedis(opts =>
    {
        opts.Configuration = ConfigurationOptions.Parse(
            builder.Configuration["Redis:ConnectionString"]!);
        opts.Configuration.Password      = builder.Configuration["Redis:Password"];
        opts.Configuration.Ssl           = true;
        opts.Configuration.AbortOnConnectFail = false;
        opts.Configuration.ConnectRetry  = 3;
    });

Служба Azure SignalR

Для полностью управляемого масштабирования используйте Службу Azure SignalR. Она выполняет роль шины сообщений и менеджера подключений — серверы приложения не хранят состояние и сами не поддерживают подключения WebSocket.

// dotnet add package Microsoft.Azure.SignalR

builder.Services.AddSignalR()
    .AddAzureSignalR(builder.Configuration["Azure:SignalR:ConnectionString"]!);

// That's it — Azure manages all connections and backplane
// Your server scales to zero when not needed

Липкие сеансы (резервный вариант для транспорта без WebSockets)

При использовании событий, отправляемых сервером, или длительного опроса (не WebSockets) тот же клиент должен всегда обращаться к одному и тому же серверу — это называется липкими сеансами. Настройте их в балансировщике нагрузки или обратном прокси-сервере.

# Nginx: sticky session config (IP hash)
upstream signalr_servers {
    ip_hash; # ensures same client hits same server
    server server1:5000;
    server server2:5000;
    server server3:5000;
}

# Or use cookie-based sticky sessions:
# sticky cookie srv_id expires=1h;

# WebSockets don't need sticky sessions —
# the connection is long-lived on one server

Группы на нескольких серверах

Членство в группах поддерживается шиной сообщений. Добавление подключения в группу на сервере A означает, что сервер B узнает об этом через Redis — для кода приложения это происходит прозрачно.

// This works correctly across servers:
public async Task JoinRoom(string room)
{
    // Adds to Redis-backed group
    await Groups.AddToGroupAsync(Context.ConnectionId, room);

    // Clients.Group sends via Redis to all servers
    await Clients.Group(room).UserJoined(Context.User!.Identity!.Name!);
}
// No code changes needed — the Redis backplane handles distribution

Мониторинг публикации и подписки Redis

Следите за каналами Redis, чтобы проверять трафик SignalR и диагностировать проблемы. Используйте redis-cli SUBSCRIBE или Redis Insights, чтобы наблюдать за потоком сообщений.

# redis-cli: monitor all SignalR channels
redis-cli PSUBSCRIBE "myapp*"

# Check active channel subscribers
redis-cli PUBSUB CHANNELS "myapp*"

# Check number of subscribers per channel
redis-cli PUBSUB NUMSUB "myapp/all"

Обработка сбоев Redis

Если Redis становится недоступен, SignalR переходит в режим только локальной доставки — сообщения не пересекают границы серверов. Настройте политики повторных попыток и оповещения о доступности Redis.

builder.Services.AddSignalR()
    .AddStackExchangeRedis(opts =>
    {
        opts.Configuration = ConfigurationOptions.Parse(redisConn);
        opts.Configuration.AbortOnConnectFail = false; // don't crash app
        opts.Configuration.ConnectRetry       = 5;
        opts.Configuration.ReconnectRetryPolicy =
            new ExponentialRetry(5000, maxDeltaBackoffMilliseconds: 60000);
    });

Практический пример: масштабируемая архитектура чата

В рабочей среде запустите как минимум 3 экземпляра серверов SignalR за балансировщиком нагрузки, используя Redis или Службу Azure SignalR в качестве шины сообщений. Всё состояние хранится в Redis; серверы не хранят состояние и могут быть заменены в любой момент.

// Architecture:
// [Browser] -> [Load Balancer (any server, WebSocket)] ->
//   [SignalR Server 1] -+
//   [SignalR Server 2] -+-> [Redis Pub/Sub] -> all servers
//   [SignalR Server 3] -+

// Server code is identical on all instances:
builder.Services.AddSignalR().AddStackExchangeRedis(redisConn);
app.MapHub<ChatHub>("/hubs/chat");
// Scale replicas: kubectl scale deployment chat --replicas=3

Быстрая проверка

Какую проблему решает шина сообщений SignalR?

Итоги: масштабирование с помощью шины сообщений Redis

Главные выводы:

  • Без шины сообщений сообщения с одного сервера не достигают клиентов на других серверах
  • AddStackExchangeRedis() прозрачно добавляет шину публикации и подписки Redis
  • Служба Azure SignalR предоставляет полностью управляемую бессерверную альтернативу шине сообщений
  • Липкие сеансы необходимы для транспортов без WebSocket (SSE, длительный опрос)
  • Членство в группах синхронизируется между серверами через шину сообщений
  • Настройте AbortOnConnectFail=false и политики повторных попыток для повышения устойчивости Redis

Часто задаваемые вопросы

Урок «Масштабирование с помощью Redis Backplane» бесплатный?

Да — полный текст урока «Масштабирование с помощью Redis Backplane» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.

Чему я научусь в уроке «Масштабирование с помощью Redis Backplane»?

Масштабируйте SignalR на несколько серверов с помощью Redis Backplane, синхронизируя сообщения между экземплярами. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Масштабирование с помощью Redis Backplane»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Центры и подключения SignalR
  2. Группы, пользователи и управление подключениями
  3. Строго типизированные центры
  4. Масштабирование с помощью Redis Backplane
← Назад к C# Academy