00 Project Overview
เป้าหมายคือออกแบบระบบที่ Client หลายตัวติดตามและเปลี่ยนแปลง State ร่วมกันได้ โดยให้เซิร์ฟเวอร์เป็นผู้ตัดสินสถานะสุดท้าย เหมาะกับ Dashboard, ระบบจำลอง และเครื่องมือจัดการงานร่วมกัน
01 The Challenge & Constraints
การ Polling เป็นระยะอาจสร้าง Request แม้ไม่มีข้อมูลเปลี่ยนแปลง และทำให้ Client ต้องรอรอบถัดไปก่อนเห็นสถานะใหม่ อย่างไรก็ตาม Polling ยังเหมาะกับระบบที่อัปเดตไม่บ่อยและต้องการความเรียบง่าย
โจทย์หลักที่ต้องแก้
- Update delay: ลดช่วงเวลาระหว่างการเปลี่ยน State และการแสดงผล
- Concurrent actions: จัดลำดับคำสั่งที่แก้ไข Entity เดียวกัน
- Reconnect: กู้สถานะเมื่อ Client หลุดการเชื่อมต่อ
- Limited resources: จำกัด Queue, Payload และจำนวน Connection ตามทรัพยากร
ขอบเขตของแบบออกแบบเริ่มต้น
เริ่มจาก Application Instance เดียว ใช้ Queue ต่อ Entity และฐานข้อมูลแบบ Transaction เมื่อขยายหลาย Instance ต้องมีการกำหนดเจ้าของ State หรือเพิ่มกลไกประสานงานร่วมกัน Queue ในหน่วยความจำของแต่ละ Process เพียงอย่างเดียวไม่เพียงพอ
02 Architecture Topology
แยก Gateway, Validation, State Resolution และ Persistence เพื่อให้ทดสอบแต่ละส่วนได้โดยไม่ผูกกับ UI และลดความซับซ้อนในตัวจัดการ WebSocket
+-------------+ +---------------------+
| Client UI | <---> | WebSocket Gateway |
+-------------+ WSS +----------+----------+
|
+-----------v------------+
| Auth / Origin / Schema |
| Limits / Authorization |
+-----------+------------+
|
+-----------v------------+
| Bounded Per-Entity Queue|
+-----------+------------+
|
+-----------v------------+
| State Resolver |
| Version / Idempotency |
+-----------+------------+
|
+-----------v------------+
| Transaction / Database |
+-----------+------------+
|
+-----------v------------+
| Commit → ACK / Publish |
+-----------+------------+
|
Authorized Clients
Reconnect → Last Seen Version → Delta or Snapshot
ทุก Command ต้องผ่านการตรวจสอบสิทธิ์ และเผยแพร่ State หลังยืนยันการบันทึกสำเร็จ เส้นทาง Reconnect ใช้ Version เพื่อตรวจข้อมูลที่ขาดหาย
เส้นทางการทำงานของหนึ่ง Action
- Client ส่ง Command พร้อม
requestIdและexpectedVersion - Gateway ตรวจ Session, Origin, ขนาด Payload และ Schema
- ตรวจสิทธิ์ต่อ Entity และส่งเข้า Queue ที่มีขนาดจำกัด
- Resolver ตรวจ Version และกฎของระบบภายในขอบเขต Transaction
- บันทึก State พร้อมข้อมูลป้องกันการประมวลผล Command ซ้ำ
- หลัง Commit จึงตอบ ACK และส่ง Event ให้ผู้รับที่มีสิทธิ์
เมื่อการเชื่อมต่อขาดหาย
Client ส่ง Version ล่าสุดที่ได้รับเพื่อขอ Delta หากประวัติไม่เพียงพอให้ส่ง Snapshot ใหม่ และต้องรองรับ Event ซ้ำหรือขาดช่วง ไม่ถือว่า WebSocket ทำให้การส่งข้อมูลเป็น Exactly-once โดยอัตโนมัติ
03 Security & Reliability Decisions
ไม่เชื่อถือข้อมูลจาก Client และไม่ถือว่าการเชื่อมต่อสำเร็จ หมายถึงมีสิทธิ์เรียกทุก Action แยกการยืนยันตัวตน การตรวจสิทธิ์ และการตรวจความถูกต้องของ State ออกจากกัน
| ความเสี่ยง | แนวทางออกแบบ | ข้อจำกัด / สิ่งที่ต้องทดสอบ |
|---|---|---|
| Race condition | Queue ต่อ Entity ร่วมกับ Transaction และ Version Check | Memory Queue ไม่ประสานหลาย Instance ต้องมีกลไกเพิ่มเติม |
| Malformed message | จำกัด Payload และตรวจ Schema ก่อนเข้า Business Logic | ปฏิเสธข้อความผิดรูปแบบ ปิด Connection เมื่อผิดร้ายแรงหรือซ้ำตามนโยบาย |
| Unauthorized action | ตรวจสิทธิ์ทุก Action และทุก Subscription | ทดสอบ Session หมดอายุ การเพิกถอนสิทธิ์ และการเข้าถึงข้ามผู้ใช้ |
| Duplicate command | ใช้ Request ID ที่ผูกผู้ใช้และตรวจซ้ำแบบ Atomic | กำหนดช่วงเก็บ ID และให้การบันทึกผลอยู่ใน Transaction เดียวกัน |
| Resource exhaustion | จำกัด Message Rate, Connection, Queue และ Outbound Buffer | กำหนด Backpressure และตรวจพฤติกรรม Client ที่รับข้อมูลช้า |
| Sensitive data exposure | ใช้ WSS กรองข้อมูลก่อน Broadcast และไม่บันทึก Token ใน Log | ตรวจ Log จริง รวมถึง Error และเครื่องมือ Monitoring |
ทำไมไม่ตัดการเชื่อมต่อทุกครั้งที่ข้อมูลผิด?
Validation Error ที่เกิดจากการใช้งานปกติสามารถตอบกลับแบบมีโครงสร้างได้ ส่วนข้อความที่เกินขนาด ละเมิด Protocol หรือทำผิดซ้ำ จึงใช้แนวทางปิด Connection ตามนโยบาย เพื่อรักษาสมดุลระหว่างความปลอดภัยและการใช้งาน
04 Benchmark & Measurement Plan
ส่วนนี้แสดงรูปแบบการรายงานผล ก่อนใช้เป็นผลงานจริงต้องแทนค่าด้วยผลทดสอบที่ทำซ้ำได้ พร้อมระบุเครื่องทดสอบ เวอร์ชันระบบ และลักษณะโหลด
ตัวอย่างการเปรียบเทียบ Mean Update Latency
ตัวเลขสมมติ 100 → 60 ms เท่ากับลดลง 40% เป็นตัวอย่างการคำนวณ ไม่ใช่ผล Benchmark ของโปรเจกต์ และไม่ได้หมายความว่า WebSocket จะเร็วขึ้น 40% ในทุกระบบ
| ตัวชี้วัด | สิ่งที่ต้องบันทึก | สถานะ |
|---|---|---|
| Mean / p50 / p95 / p99 Latency | เวลาตั้งแต่ส่ง Action จนได้รับ State ยืนยันกลับ | ยังไม่มีผลวัดจริง |
| Concurrent Connections | แผนทดสอบ 50 / 100 / 250 / 500 Connections | เป้าหมายทดสอบ ไม่ใช่ความสามารถที่ยืนยันแล้ว |
| Event Throughput | Events ต่อวินาที รวม Fan-out และ Payload Size | ยังไม่กำหนด Workload จริง |
| CPU / Memory / Queue Depth | ค่าเฉลี่ย จุดสูงสุด และพฤติกรรมเมื่อโหลดเกิน | รอทดสอบ |
| Error / Recovery | Error Rate, Reconnect Time และ State Consistency | รอทดสอบ |
เงื่อนไขสำหรับการเปรียบเทียบที่น่าเชื่อถือ
- ใช้ Hardware, Dataset และ Network Conditions เดียวกัน
- ระบุ Polling Interval, Payload Size และ Event Rate
- แยก Idle Connections ออกจาก Connections ที่ส่งข้อมูลจริง
- มีช่วง Warm-up และรันทดสอบซ้ำหลายรอบ
- รายงาน Tail Latency และ Error Rate ไม่ใช้ค่าเฉลี่ยเพียงอย่างเดียว
05 Design Lessons & Next Steps
1. Transport ไม่ได้แก้ปัญหา Consistency ให้ทั้งหมด
เปลี่ยนจาก Polling เป็น WebSocket ช่วยเปลี่ยนวิธีส่งข้อมูล แต่การจัดลำดับคำสั่ง การตรวจ Version และการกู้สถานะยังต้องออกแบบแยกต่างหาก
2. Memory Queue เป็นจุดเริ่มต้น ไม่ใช่ระบบจัดคิวถาวร
Queue ในหน่วยความจำช่วยจัดลำดับภายใน Process แต่ข้อมูลอาจหายเมื่อ Process หยุด งานที่ต้องรับประกันการรับคำสั่งต้องมี Durable Storage และนิยามให้ชัดว่า ACK หมายถึงรับไว้หรือบันทึกสำเร็จแล้ว
3. เริ่มจากขอบเขตเล็ก แล้วเพิ่มความซับซ้อนจากหลักฐาน
ออกแบบ Single Instance ให้ตรวจสอบได้ก่อน เมื่อผลวัดชี้ว่าถึงข้อจำกัด จึงพิจารณา Shared Broker, Durable Queue, Transactional Outbox หรือการแบ่งเจ้าของ State
Next iteration
- สร้าง Prototype ตามเส้นทาง Command และ State ที่ระบุ
- เพิ่ม Integration Tests สำหรับคำสั่งซ้ำและ Version Conflict
- ทดสอบการตัด Connection และการกู้ Snapshot
- แทนข้อมูลตัวอย่างด้วยผล Benchmark ที่ทำซ้ำได้
// Apply this approach to your project
มีระบบที่ต้องอัปเดตข้อมูลร่วมกัน?
เล่า Workflow จำนวนผู้ใช้งาน และข้อจำกัดของระบบ เพื่อประเมินว่าควรใช้ Polling, WebSocket หรือแนวทางที่เรียบง่ายกว่าให้เหมาะกับโจทย์
Inquire for Similar Architecture ↗