1. Worker và Thread trong Rails là gì?
Worker
Worker trong Rails là một tiến trình (process) hoạt động ngoài chu kỳ yêu cầu (request cycle) của ứng dụng Rails. Mỗi worker sẽ là một tiến trình riêng biệt, mỗi tiến trình chạy một instance riêng của ứng dụng Rails.
Thread
Mỗi worker có thể chạy nhiều thread, cho phép xử lý nhiều yêu cầu đồng thời trong cùng một tiến trình.
2. Cách cấu hình worker và thread trong Puma
Thông thường, sau khi khởi tạo một dự án Rails, bạn sẽ thấy nội dung trong tệp puma.rb
như sau:
threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
threads threads_count, threads_count
# Chỉ định cổng (port) mà Puma sẽ lắng nghe để nhận yêu cầu, mặc định là 3000.
port ENV.fetch("PORT", 3000)
# Cho phép Puma được khởi động lại bằng lệnh `bin/rails restart`.
plugin :tmp_restart
# Xác định tệp PID. Mặc định là tmp/pids/server.pid trong môi trường phát triển.
# Trong các môi trường khác, chỉ đặt tệp PID nếu được yêu cầu.
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
Điều này có nghĩa là:
- Worker: Không được chỉ định trong tệp Puma, vì vậy mặc định chỉ có 1 tiến trình.
- Thread: Có
RAILS_MAX_THREADS
số lượng threads nếu bạn chỉ định trong tệp.env
, nếu không thì mặc định là 3.
Để điều chỉnh số lượng worker, chúng ta cần thay đổi tệp Puma như sau:
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
threads threads_count, threads_count
# Chỉ định cổng (port) mà Puma sẽ lắng nghe để nhận yêu cầu, mặc định là 3000.
port ENV.fetch("PORT", 3000)
# Cho phép Puma được khởi động lại bằng lệnh `bin/rails restart`.
plugin :tmp_restart
# Xác định tệp PID. Mặc định là tmp/pids/server.pid trong môi trường phát triển.
# Trong các môi trường khác, chỉ đặt tệp PID nếu được yêu cầu.
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
3. Cách xác định số lượng worker và thread phù hợp
Cách số lượng worker/thread ảnh hưởng đến hiệu suất của server
Ví dụ 1: với WEB_CONCURRENCY = 1
và RAILS_MAX_THREADS = 5
, ta có 1 tiến trình với 5 thread, nghĩa là ứng dụng có thể xử lý tối đa 1 x 5 = 5 yêu cầu đồng thời
. Nếu mỗi yêu cầu mất 100ms, số lượng yêu cầu mỗi giây (RPS) sẽ là:
Ví dụ 2: với WEB_CONCURRENCY = 2
và RAILS_MAX_THREADS = 5
, ứng dụng có thể xử lý 100 RPS.
Tăng số lượng worker/thread có làm tăng RPS không?
Câu trả lời là: KHÔNG. Tại sao? Bởi vì CPU và bộ nhớ (Memory) của server là có giới hạn. Các tiến trình tiêu tốn CPU và bộ nhớ của server. Nếu có nhiều tiến trình và thread hơn, chúng sẽ tiêu tốn nguồn lực CPU và bộ nhớ nhiều hơn.
Cách xác định và chọn số lượng worker/thread tối ưu
Bạn cần dành một chút thời gian để thực hiện kiểm tra tốc độ và đo đạc CPU cũng như bộ nhớ của server. Một trong những công cụ để thực hiện kiểm tra tốc độ là Artillery.
=> Dựa trên tài nguyên của server (CPU & Memory), bạn có thể xác định số lượng worker/thread tương ứng. Một cách khác để tăng RPS là tối ưu hóa logic ứng dụng của bạn (tất nhiên).
Lời Kết
Hy vọng tôi đã giúp bạn tự tin hơn trong việc cấu hình máy chủ một cách hợp lý. Bạn nghĩ gì về cách tiếp cận này? Hãy chia sẻ ý kiến của bạn trong phần bình luận!
Cảm ơn bạn đã đọc!
source: viblo