Rage.rb — Khi Ruby Học Cách Không Chờ Đợi
Vấn đề muôn thuở của Rails dưới tải cao Bạn có một Rails API. Mọi thứ chạy tốt ở môi trường dev, production cũng ổn ở lượng traffic vừa phải. Rồi một ngày đẹp trời, traffic tăng đột biến — và bạn b...

Source: DEV Community
Vấn đề muôn thuở của Rails dưới tải cao Bạn có một Rails API. Mọi thứ chạy tốt ở môi trường dev, production cũng ổn ở lượng traffic vừa phải. Rồi một ngày đẹp trời, traffic tăng đột biến — và bạn bắt đầu thấy: Response time leo thang Memory usage phình to Sidekiq queue tắc nghẽn Infra team hỏi "có cần thêm worker không?" Vấn đề không phải ở code logic. Vấn đề nằm sâu hơn — ở cách Rails xử lý concurrency. Rails xử lý concurrency như thế nào? Rails với Puma dùng mô hình multi-threaded. Mỗi HTTP request được xử lý bởi một thread riêng. Request 1 ──→ Thread 1: [connect DB] [======chờ 50ms======] [process] [respond] Request 2 ──→ Thread 2: [connect DB] [======chờ 50ms======] [process] [respond] Request 3 ──→ Thread 3: [connect DB] [======chờ 50ms======] [process] [respond] ... Request N ──→ Thread N: phải chờ thread trống Trong 50ms chờ database, thread đó không làm gì cả — nó block hoàn toàn. Đây gọi là blocking I/O. Giải pháp của Puma: tăng số thread. Nhưng mỗi thread tốn 1–8MB RAM và OS