Chuyện khá hy hữu là đứa em mình sang công ty mới, đang làm outsourcing cho một tập đoàn xây dựng lớn thì thấy một bản kiến trúc hệ thống... trông quen quá. Hóa ra đó chính là bản thiết kế mình vẽ cho một dự án BĐS từ những năm 2020-2021 (thời COVID).
Nhìn lại "đứa con" cũ, mình lại nhớ về một bài học lớn: Đừng bao giờ tin vào "Viên đạn bạc" (Silver Bullet).
1. Khi Functional Requirements (FRs) là một "màu hồng"
Hồi đó, khách hàng muốn dùng Odoo để làm hệ thống Service Desk/Request cho hơn 10.000 nhân sự. Yêu cầu nghe qua rất mượt:
• Tạo ticket dịch vụ giữa các phòng ban.
• Chat nội bộ, chat nhóm.
• Video call, họp trực tuyến.
• Đánh giá nhân sự, quản lý doanh nghiệp...
Odoo demo thì cực ngon, tính năng gì cũng có sẵn (All-in-one). Sếp mình "chốt" deal cũng rất nhanh. Nhưng khi mình bắt tay vào điều tra kỹ hơn về kỹ thuật, bài toán mới thực sự bắt đầu.
2. Cú tát từ Non-functional Requirements (NFRs)
Khi hỏi đến con số: "Bao nhiêu người dùng đồng thời (CCU)?", câu trả lời là 1.000 CCU (trên tổng 10k nhân sự).
Nếu ai từng triển khai Odoo sẽ biết, với 1.000 CCU mà chạy Monolithic Odoo thuần túy thì:
• Chi phí vận hành (OpsEx) cực cao: Yêu cầu cấu hình server rất khủng để gánh lượng Worker lớn.
• Khó mở rộng: Odoo mạnh về Vertical Scaling (tăng cấu hình máy chủ), nhưng rất khó để Horizontal Scaling (mở rộng hàng ngang) hiệu quả cho các tính năng realtime.
3. Giải pháp: "Rã xác" Monolithic để cứu hệ thống
Để hệ thống thực sự "sống" được, mình buộc phải tước bỏ những thứ có sẵn của Odoo và thay bằng các mảnh ghép chuyên biệt bên ngoài:
• Trải nghiệm người dùng: Viết lại toàn bộ Front-end bằng ReactJS (SPA) để tránh việc reload trang liên tục của Odoo, giúp giao diện mượt mà hơn.
• Chatting: Thay vì dùng chat mặc định của Odoo (hồi đó vẫn dùng Long-polling, rất tốn resource), mình đưa Rocket.Chat (Meteor.js) vào. Vừa hỗ trợ WebSocket, vừa giảm tải bottle-neck cho server Odoo.
• Video Conference: Tích hợp Jitsi Meet chạy trên nền WebRTC để xử lý luồng video call 1-1 và họp nhóm, hoàn toàn tách biệt khỏi Odoo.
• Database: Phải tối ưu rất kỹ vì Odoo "ngốn" RAM và kết nối vào Postgres rất bạo.
4. Bài học rút ra
Sai lầm lớn nhất của nhiều bên là chỉ nhìn thấy Framework A, Framework B có đầy đủ tính năng mà chủ quan đánh cược toàn bộ vào nó.
Lời khuyên của mình: Mọi người đừng chỉ quan tâm đến tính năng (Functional Requirements). Hãy đào sâu vào Non-functional Requirements:
• Hệ thống có chịu tải được không (Scalability)?
• Có dễ dàng bảo trì không (Maintainability)?
• Có khả năng triển khai độc lập không (Independently Deployable)?
Không có Framework nào là vạn năng. Muốn hệ thống chạy "ngon" ở quy mô lớn, đôi khi chúng ta phải chấp nhận đập bỏ cái "có sẵn" để xây dựng một kiến trúc bền vững hơn.
#SolutionArchitect #HungNguyenVN #OdooMonolithic #OdooDecompose
Đừng để "Tính năng" đánh lừa: Bài học về Non-functional Requirements từ một dự án Odoo cũ