- Loại bỏ RabbitMQ và thay bằng hàng đợi dùng SQL trên PostgresDB
- Việc thay thế chỉ mất khoảng nửa ngày, và mã nguồn giảm 580 dòng
- Quan trọng hơn nhiều là độ ổn định và khả năng phục hồi (resiliency) đã được cải thiện đáng kể
- Đây không phải là câu chuyện về vấn đề của các hệ thống hàng đợi như RabbitMQ, mà đơn giản là một phần của nỗ lực giữ mọi thứ tối giản
- Prequel, đơn vị viết bài này, là sản phẩm giúp các công ty B2B SaaS đồng bộ với cơ sở dữ liệu của khách hàng thông qua các pipeline dữ liệu quy mô lớn
- Họ đã xây dựng bằng RabbitMQ + AQMP + Helm + wrapper GoLang, và đã chạy tốt trong một thời gian, nhưng rồi bắt đầu xuất hiện vấn đề
- Việc chuyển thông điệp bị chậm quá lâu khiến thông điệp bị hủy
- Khi consumer prefetch thông điệp, tình huống xảy ra là nó giữ sẵn thông điệp tiếp theo cho đến khi hoàn tất thông điệp hiện tại
- Nếu đặt prefetch về 0 thì nó lại trở thành vô hạn, nên không thể vô hiệu hóa prefetch
- Vấn đề này phát sinh vì các tác vụ nhận và xử lý thông điệp thường là tác vụ dài hạn (truyền dữ liệu)
- Họ đã hiểu chính xác chuyện gì đang xảy ra, nhưng không có cách sửa ngay lập tức. Vì sự cố xảy ra với khách hàng production nên không thể chờ đợi
- Vì vậy họ chuyển sang cách đọc và ghi bằng một bảng đơn giản trong Postgres
- Dùng row-level lock cho đọc/ghi để đảm bảo chỉ một consumer có thể đọc công việc
- Đơn giản đến khó tin nhưng đang hoạt động hoàn hảo
- Một lợi thế nữa là trạng thái của ứng dụng không còn bị chia tách giữa RabbitMQ và Postgres mà được hợp nhất vào một nơi
6 bình luận
Tôi cũng đã tự triển khai queue trực tiếp bằng
row level locktrong MySQL và nó đã vận hành ổn định trong sản phẩm suốt nhiều năm.Điều tôi muốn đơn giản là cung cấp chức năng tương tự queue cho nhiều worker, đồng thời có thể lưu luôn payload kèm các trạng thái như chờ/đang xử lý/thất bại (nếu hoàn tất thì xóa) ngay trong queue.
Nhìn vào việc trong bài họ chuyển từ RabbitMQ sang DB trong thời gian ngắn, có lẽ là vì họ thực sự không cần đến tính đa dụng, các tính năng phong phú hay khả năng cấu hình đa dạng của một dịch vụ queue chuyên biệt riêng.
Có vẻ vấn đề phát sinh do bị lệch nhịp giữa việc gửi ACK thủ công và transaction của DB,
điều thú vị là họ giải quyết chuyện này không phải bằng kỹ thuật xử lý mà bằng cách gỡ bỏ RabbitMQ.
Chắc RabbitMQ cũng không có tội gì...
https://news.ycombinator.com/item?id=35526846
Có khá nhiều ý kiến trong phần bình luận.
Cũng có thứ như thế này hoạt động theo cách tương tự: https://github.com/pjongy/jasyncq
Có vẻ như có khả năng bị
selectđồng thời; tôi tò mò không biết họ đã giải quyết việc đó như thế nào.Có vẻ như ở đây ghi là khóa cấp hàng.