Mở đầu
- Nhớ năm trước tham gia sự kiện của CLB thấy anh em dùng google biểu mẫu để tạo form đăng ký và google sheet để checkin. Quy trình thì đến quầy rồi đọc tên và 1 bạn ở quầy sẽ hỗ trợ checkin. Do làm như thế khá là thủ công và nhiều người cùng sửa 1 sheet nên việc sai sót là không thể tránh khỏi.
- Vừa muốn cho anh em "nhàn" hơn và thời gian checkin nhanh nhất có thể => Ý tưởng checkin bằng QRCode loé lên trong đầu.
Thiết kế hệ thống
Do là hệ thống chỉ có chức năng checkin và thống kê cơ bản nên nghiệp vụ cũng khá đơn giản.
- FE viết bằng VueJS.
- Nodejs là service chính, chịu trách nhiệm thao tác với database và giao tiếp với service python phục vụ checkin bằng khuôn mặt.
- Database ở đây mình sử dụng PostgreSQL. Với nghiệp vụ cũng như số lượng data ít thì database nào cũng đáp ứng được.
- Bộ đôi Prometheus được sử dụng để trích xuất các metrics từ các service, tài nguyên của VPS và Granfana để visualization thành các biểu đồ.
- Alertmanage chịu trách nhiệm bắn thông báo về Discord của team dev khi tài nguyên của VPS đang được sử dụng quá mức hoặc API của service nào đó đang gặp vấn đề.
Thiết kế cơ sở dữ liệu
Như đã nói ở đầu hệ thống nghiệp vụ chỉ là checkin nên database về cơ bản chỉ có 1 bảng là users
với vài trường thông tin cơ bản ví dụ như :
- Họ tên
- Số điện thoại
- Trạng thái checkin
- Quyền
- Mật khẩu (dành cho admin)
- v.v
Và 1 bảng jobs
để lưu lại trạng thái và mã lỗi của hàng chờ gửi mail (sau khi đăng ký xong, hệ thống sẽ gửi mail xác nhận kèm với QRCode đến người đăng ký).
Các bước xây dựng
Quy trình người dùng checkin bằng QR
- Đăng ký
- Đầu tiên người dùng sẽ điền thông tin cần thiết.
- BE nhận dữ liệu và ghi vào database đồng thời trả về dữ liệu cho FE.
- FE nhận dữ liệu từ BE và tạo mã QRCode.
- Người dùng tải mã QR về thiết bị.
- Checkin tại quầy
- Người dùng mang mã QRCode được cấp đến quầy checkin và đưa trước camera để nhận diện.
- FE đọc nội dung mã QRCode và request lên BE để checkin.
- Nếu thành công FE hiển thị thông báo và đồng thời danh sách người checkin (trang admin) được cập nhật theo thời gian thực.
Lưu dữ liệu gì vào QRCode ?
- Chắc chắn không được lưu dữ liệu cá nhân vào vì ai cũng có thể đọc nội dung.
- Không lưu các dữ liệu có thể được cập nhật như email, số điện thoại ...
- Vậy có lẽ lưu id là ok nhất. Nhưng nếu dùng id tăng tự động thì người tinh ý có thể biết tổng số người đã đăng ký thông qua id trong mã QR.
- Chốt vẫn lưu id vào QR nhưng dưới dạng UUID.
Tạo mã QRCode
- Việc tạo mã QR khá đơn giản, khá nhiều thư viện support và đủ đáp ứng nhu cầu. Ngoài ra có thể dùng các API các bên thứ 3 như google cũng ổn.
Đọc mã QRCode
- Search nhanh các thư viện QR Reader cho Vue thì có 1 - 2 thằng có thể sử dụng. Nhưng khi sử dụng thì khá hạn chế, có lúc phải clone lib về để fix bug, custom và build lại nhưng không được. Không như bên React lib khá ổn, nhưng chả nhẽ lại đập đi xây lại. Nên anh em phải khắc phục tạm thời.
- Sau khi đã đọc được nội dung của QR chính là id của người dùng thì request lên BE để checkin.
Gửi mail
- Việc gửi mail bằng gmail đôi khi có thể bị khóa do sếp google nghi ngờ spam, kháng không được thì bay màu cái mail.
- May mắn được một người anh tài trợ business email, không lo vấn đề ý nữa. Đúng là mọi việc đều có thể giải quyết bằng tiền 😂 .
- Nhưng bắt người dùng chờ mail gửi thành công thì không hay lắm, phải cho vào queue nó mới chuẩn sách giáo khoa. Search lẹ được 1 thằng
bull
của bên NodeJS, giờ muốn gửi mail cứ sút vào queue cho nó gửi email.
Monitor
- Trích xuất các tài nguyên của VPS thì mình sài
node exporter
, các service của hệ thống 100% chạy docker hết nên sài thêmcadvisor
để giám sát các container. Kết hợp với các thư viện client của NodeJS và Python thì cũng có hệ thống giám sát cơ bản. - Việc triển khai hệ thống monitor cũng khá đơn giản với sự giúp đỡ của docker. Chủ yếu mình cũng chỉ quan tâm đến các tài nguyên cơ bản của server như CPU, RAM, Disk. Và tần suất gọi, thời gian phản hồi, số lần gọi lỗi của các API để có biện pháp xử lý kịp thời.
Khác (bảo mật, spam, xử lý lỗi)
- Các container như database, redis,... không public port ra ngoài. Anh em deploy bằng docker compose rất hay để cái port vào tuy có cài password nhưng nó vẫn không hẳn là an toàn 😂. và các container nên chạy quyền non-root.
- Rate limit và để captcha với các api người dùng là cần thiết.
- Các password của các service nếu có đều dài 16 ký tự, có chữ thường, chữ hoa, số và ký tự đặc biệt.
- Chống các kiểu tấn công web thường gặp.
- Việc ghi log cũng rất quan trọng, đôi khi log không chỉ có thời gian, level, message lỗi mà cần cả vị trí lỗi, cả dữ liệu và một số meta nữa. Sau này server có lỗi hay hẹo điều tra cho dễ.
Kết luận
- Với sinh viên làm một project để áp dụng những cái đã học mà còn được ứng dụng vào thực tế khá là vui 😊.
- Đó là quá trình mình xây dựng một hệ thống nho nhỏ cho CLB. Nếu mọi người có góp ý hay thắc mắc thì comment xuống phía dưới cho mình biết nhé. 😘😘