🎯 Bối cảnh dự án
Đây là dự án của học phần Đồ Án Cơ Sở học kỳ 1 năm 2024. Giảng viên đặt yêu cầu: Xây dựng một hệ thống có tính năng real-time và phải xử lý được vấn đề race condition.
Bài toán cụ thể: Khi 100 người cùng lúc chọn 1 ghế trong rạp chiếu phim, làm sao đảm bảo chỉ 1 người book thành công?
🏗️ Kiến trúc hệ thống
Tech Stack
- Backend: Node.js + Express.js
- Real-time: Socket.io (WebSocket)
- Database: PostgreSQL
- Cache & Locking: Redis
- Frontend: React.js + Context API
Sơ đồ luồng xử lý
Client chọn ghế ↓ Socket.io emit 'select-seat' ↓ Server check Redis lock ↓ Nếu lock thành công → Update PostgreSQL → Broadcast Nếu lock thất bại → Return error
⚙️ Giải pháp kỹ thuật
1. Redis Distributed Lock
// Acquire lock với expire time 30s
const lockKey = `seat:${movieId}:${seatId}`;
const acquired = await redis.set(
lockKey,
userId,
'EX', 30, // Auto expire sau 30s
'NX' // Chỉ set nếu key chưa tồn tại
);
if (!acquired) {
throw new Error('Ghế đã được chọn');
}
2. WebSocket Broadcasting
io.to(`room-${movieId}`).emit('seat:updated', {
seatId,
status: 'locked',
userId,
timestamp: Date.now()
});
📊 Kết quả testing
Load Test với Artillery
- Test case: 100 users cùng lúc chọn 1 ghế
- Kết quả: Chỉ 1 request thành công, 99 requests nhận error
- Response time: 150-200ms
- Zero double booking: ✅
Test thực tế
- Mời 10 bạn cùng lớp test đồng thời
- Kết quả: Hệ thống hoạt động ổn định
- Feedback: UI real-time mượt mà
💡 Những gì đã học được
1. Technical Knowledge
- Hiểu sâu về WebSocket và cách nó khác HTTP
- Học cách implement distributed lock pattern
- Thực hành database transaction và row-level locking
2. Debugging Skills
- Bug 1: Redis lock không release khi server crash
- Fix: Dùng EXPIRE để auto-release
- Bug 2: WebSocket disconnect/reconnect liên tục
- Fix: Implement heartbeat mechanism
🏆 Kết quả đạt được
- Điểm đồ án: 9.0/10
🎓 Reflection
Dự án này giúp tôi hiểu rằng:
- Distributed systems không đơn giản như tưởng
- Testing với race condition cần cẩn thận và có methodology
- Real-world problems thường phức tạp hơn lý thuyết rất nhiều
