0Pricing
C# Academy · บทเรียน

การปรับขนาดด้วย Redis Backplane

ปรับขนาด SignalR ข้ามเซิร์ฟเวอร์หลายเครื่องด้วย Redis backplane เพื่อซิงโครไนซ์ข้อความระหว่างอินสแตนซ์

การปรับขนาดด้วย Redis Backplane เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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 Service

หากต้องการการขยายระบบที่มีการจัดการอย่างสมบูรณ์ ให้ใช้ Azure SignalR Service ซึ่งทำหน้าที่เป็นทั้งแบ็กเพลนและตัวจัดการการเชื่อมต่อ — เซิร์ฟเวอร์แอปพลิเคชันของคุณจะไม่เก็บสถานะ และไม่ต้องเก็บการเชื่อมต่อ 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

เซสชันแบบยึดติด (ทางเลือกสำรองสำหรับการขนส่งที่ไม่ใช่ WebSocket)

เมื่อใช้เหตุการณ์ที่ส่งจากเซิร์ฟเวอร์หรือการสำรวจแบบยาว (ไม่ใช่ 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);
    });

การใช้งานจริง: สถาปัตยกรรมแชตแบบขยายระบบ

ในระบบจริง ให้เรียกใช้อินสแตนซ์เซิร์ฟเวอร์ SignalR อย่างน้อย 3 เครื่องอยู่หลังตัวกระจายโหลด โดยมี Redis (หรือ Azure SignalR Service) เป็นแบ็กเพลน สถานะทั้งหมดอยู่ใน 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 Service เป็นทางเลือกแบ็กเพลนที่มีการจัดการอย่างสมบูรณ์และไม่ต้องจัดการเซิร์ฟเวอร์เอง
  • การขนส่งที่ไม่ใช่ WebSocket (SSE, การสำรวจแบบยาว) จำเป็นต้องใช้เซสชันแบบยึดติด
  • การเป็นสมาชิกกลุ่มจะซิงโครไนซ์ระหว่างเซิร์ฟเวอร์ผ่านแบ็กเพลน
  • กำหนดค่า AbortOnConnectFail=false และนโยบายการลองใหม่เพื่อให้ Redis ทนทานต่อความขัดข้อง

คำถามที่พบบ่อย

บทเรียน “การปรับขนาดด้วย Redis Backplane” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การปรับขนาดด้วย Redis Backplane” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การปรับขนาดด้วย Redis Backplane”

ปรับขนาด SignalR ข้ามเซิร์ฟเวอร์หลายเครื่องด้วย Redis backplane เพื่อซิงโครไนซ์ข้อความระหว่างอินสแตนซ์ คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 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