sieuthicode.com

Thông báo

16

Ưu Đãi Khi Mua Hosting

Mã giảm giá 10% : HOSTING1205
1 năm trước

THÔNG BÁO API

API MBBANK ĐÃ UPDATE VẪN SỬ DỤNG BÌNH THƯỜNG NHÉ
2 năm trước

Thông Báo Khẩn

Chúng tôi đã mã hóa mật khẩu và dữ liệu API. Vui lòng xóa và thêm lại tài khoản của bạn.
2 năm trước

NHẬN FIX TẤT CẢ API

NHẬN FIX TẤT CẢ API TỪ 100K ĐÊN 300K MỌI API
2 năm trước

THÔNG BÁO MỚI

MÃ GIẢM 50% KHI MUA CODE : SINAMI23H
2 năm trước

THÔNG BÁO API

HẠ GIÁ THUÊ API XUỐNG 25K/ THÁNG VÀ HỖ TRỢ ĐẤU APP FREE
3 năm trước

THỐNG BÁO HÓT

FREE HOST USA1 ĐẾN 30/3/2024
3 năm trước

THÔNG BÁO GIẢM GIÁ

GIẢM GIÁ THUÊ CRONS 1S SERVER US VÀ VN XUỐNG 6K
3 năm trước

THÔNG BÁO

Lsgd mbbank sử dụng bth rồi
3 năm trước

Thông báo hot

Ra mắt thêm api seabank
3 năm trước

THÔNG BÁO KHẨN

NÂNG GIÁ THUÊ API LÊN 30K/ THÁNG VÀ HỖ TRỢ ĐẤU WEB APP FREE
3 năm trước

THÔNG BÁO HOT

TẠNG HOSTING FREE 1 NĂM CODE : FREEHOSSTING
3 năm trước

KHUYỄN MÃI

FREE CRONS SEVER 4 (VN) 1S
3 năm trước

THÔNG BÁO KHẨN

GIẢM GIÁ CRONS 1S CHỈ CÒN 5K
3 năm trước

KHUYỄN MÃI NẠP

NẠP TRÊN 100K NHẬN THÊM 10% TRONG HÔM NAY
3 năm trước
SIÊU THỊ CODE / KIẾN THỨC & CÔNG NGHỆ

Cách giới hạn thời gian chạy và tài nguyên cho cron Node.js

Để cron Node.js không chạy quá lâu hoặc chiếm hết tài nguyên máy chủ, bạn cần kiểm soát riêng thời gian chạy, số phiên chạy đồng thời và mức sử dụng RAM, CPU. Trên Linux, có thể dùng timeout và flock để xử lý hai việc đầu; nếu cần giới hạn tài nguyên cho cả tiến trình và các tiến trình con, nên dùng systemd hoặc cơ chế quản lý tương đương.

Hướng dẫn dưới đây dành cho người vận hành website và lập trình viên chạy tác vụ đồng bộ, gửi thông báo hoặc xử lý hàng đợi bằng Node.js. Các lệnh là ví dụ minh họa trên Linux dùng GNU coreutils và systemd; hãy thay đường dẫn, tên người dùng và thông số theo môi trường thực tế.

Chọn giới hạn theo công việc cần hoàn thành

Không nên đặt timeout chỉ dựa trên chu kỳ cron. Một job chạy mỗi năm phút vẫn có thể được phép chạy lâu hơn nếu hệ thống chủ động bỏ qua lượt kế tiếp. Ngược lại, tác vụ cập nhật dữ liệu gần thời gian thực thường cần chia nhỏ để hoàn thành trước lượt tiếp theo.

Chọn giới hạn theo công việc cần hoàn thành
  • Thời gian: đo thời lượng ở dữ liệu bình thường và lúc tồn đọng, sau đó đặt ngưỡng có khoảng dự phòng.
  • RAM: theo dõi bộ nhớ của toàn tiến trình, không chỉ JavaScript heap.
  • CPU: xác định job chủ yếu chờ mạng hay thực hiện tính toán trước khi đặt hạn mức.
  • Đồng thời: quyết định bỏ qua, xếp hàng hay cho phép chạy song song khi lượt cũ chưa xong.

Ví dụ giả định: job nhập dữ liệu thường mất 40 giây nhưng khi tồn đọng có thể mất hai phút. Có thể thử ngưỡng ba phút, kiểm tra trên môi trường thử nghiệm rồi điều chỉnh. Đây không phải cấu hình mặc định phù hợp cho mọi website.

Đặt timeout và khóa chống chạy chồng bằng cron

Tạo lệnh chạy có thời hạn

Ví dụ sau cho job tối đa ba phút. Khi hết hạn, GNU timeout gửi SIGTERM; nếu tiến trình chưa thoát sau 15 giây nữa, nó gửi SIGKILL:

/usr/bin/timeout --signal=TERM --kill-after=15s 3m /usr/bin/node /srv/myapp/jobs/sync.js

Hãy kiểm tra vị trí thực tế của các chương trình trên máy. Cron có môi trường tối giản, nên Node.js cài qua trình quản lý phiên bản có thể không nằm trong PATH của cron. Đồng thời, cần đặt đúng thư mục làm việc nếu ứng dụng đọc tệp bằng đường dẫn tương đối.

Không để lượt mới khởi chạy khi lượt cũ còn hoạt động

Trên cùng một máy, flock có thể giữ khóa trong suốt thời gian lệnh chạy. Ví dụ crontab dưới đây chạy mỗi năm phút và bỏ qua lượt mới nếu khóa đang được giữ:

*/5 * * * * cd /srv/myapp && /usr/bin/flock -n /srv/myapp/run/sync.lock /usr/bin/timeout --signal=TERM --kill-after=15s 3m /usr/bin/node /srv/myapp/jobs/sync.js >> /srv/myapp/logs/sync.log 2>&1

Tạo trước thư mục run, logs và cấp quyền cho tài khoản chạy cron. Tệp khóa còn tồn tại không đồng nghĩa khóa vẫn bị giữ; không cần xóa tệp sau mỗi lượt. Ví dụ này không tự ghi lý do bỏ qua vào log, nên hãy bổ sung script bao ngoài nếu cần thống kê lượt bị bỏ.

Khóa cục bộ không giải quyết đồng thời giữa nhiều máy. Nếu nhiều VPS cùng chạy một lịch, cần cơ chế điều phối dùng chung, chẳng hạn hàng đợi hoặc khóa cơ sở dữ liệu có thiết kế xử lý hết hạn phù hợp.

Giới hạn RAM và CPU bằng systemd

Tham số --max-old-space-size chỉ giới hạn vùng old space của V8, không phải toàn bộ RAM của Node.js. Buffer, bộ nhớ native và các phần khác vẫn có thể làm tổng bộ nhớ vượt con số này. Muốn giới hạn nhóm tiến trình, có thể tạo service systemd.

Giới hạn RAM và CPU bằng systemd

Ví dụ tệp /etc/systemd/system/node-sync.service:

[Unit]
Description=Node.js scheduled sync

[Service]
Type=exec
User=appjob
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/node --max-old-space-size=256 /srv/myapp/jobs/sync.js
RuntimeMaxSec=180s
TimeoutStopSec=15s
KillMode=control-group
MemoryHigh=384M
MemoryMax=512M
CPUQuota=50%

Cấu hình giả định này cần được đối chiếu với phiên bản systemd và khả năng kiểm soát tài nguyên của máy:

  • RuntimeMaxSec giới hạn thời gian service hoạt động; không áp dụng theo cách này cho service Type=oneshot.
  • TimeoutStopSec giới hạn thời gian chờ dừng trước khi systemd buộc kết thúc theo cấu hình kill.
  • MemoryHigh tạo áp lực thu hồi bộ nhớ; MemoryMax là giới hạn cứng và có thể dẫn đến OOM kill.
  • CPUQuota=50% giới hạn thời gian CPU tương đương khoảng nửa một lõi, không phải nửa tổng CPU của mọi máy.

Giới hạn CPU thấp có thể khiến job chạm timeout dù dữ liệu không tăng. Vì vậy cần kiểm thử RAM, CPU và thời gian cùng nhau.

Dùng timer để tránh hai lịch độc lập

Tạo tệp /etc/systemd/system/node-sync.timer:

[Unit]
Description=Schedule Node.js sync

[Timer]
Unit=node-sync.service

[Install]
WantedBy=timers.target

Sau đó nạp cấu hình và bật timer:

sudo systemctl daemon-reload
sudo systemctl enable --now node-sync.timer

Timer không khởi tạo thêm một phiên của cùng service khi service đó vẫn đang hoạt động. Hãy gỡ lịch cron cũ nếu chuyển sang timer để tránh có hai cơ chế cùng chạy script.

Cho Node.js dừng có kiểm soát khi nhận SIGTERM

Giới hạn ở hệ điều hành chỉ ngăn job tiếp tục chiếm tài nguyên; nó không bảo đảm dữ liệu đang xử lý được hoàn tất. Trong ứng dụng, khi nhận SIGTERM, hãy ngừng nhận phần việc mới, hủy yêu cầu mạng nếu thư viện hỗ trợ, hoàn tất hoặc rollback giao dịch rồi đóng kết nối.

Đặt timeout riêng cho từng thao tác mạng hoặc truy vấn theo khả năng của thư viện. Promise.race chỉ giúp ngừng chờ kết quả, không tự hủy tác vụ bên dưới. Với tác vụ tính toán đồng bộ chặn event loop, trình xử lý tín hiệu JavaScript cũng có thể không chạy kịp; giới hạn bên ngoài vẫn cần thiết.

Ví dụ, job giả định nhập từng trang dữ liệu nên lưu checkpoint sau khi ghi trang thành công. Lượt sau tiếp tục từ checkpoint và dùng khóa duy nhất hoặc upsert để tránh tạo bản ghi trùng. Không đánh dấu một trang đã hoàn tất trước khi dữ liệu được ghi thành công.

Kiểm tra giới hạn và tìm nguyên nhân job bị dừng

Thực hiện thử nghiệm trên dữ liệu giả hoặc môi trường staging trước khi áp dụng cho tác vụ thật:

Kiểm tra giới hạn và tìm nguyên nhân job bị dừng
  1. Thử quá thời gian: tạo job chờ lâu hơn ngưỡng, kiểm tra nó nhận tín hiệu dừng và không còn tiến trình con sót lại.
  2. Thử chạy chồng: kích hoạt hai lượt gần nhau; xác nhận chỉ một lượt xử lý dữ liệu.
  3. Thử áp lực bộ nhớ: tăng kích thước lô có kiểm soát, quan sát bộ nhớ và nguyên nhân kết thúc.
  4. Thử chạy lại: dừng giữa chừng rồi khởi chạy lại; kiểm tra checkpoint và bản ghi trùng.

Với systemd, có thể xem trạng thái và nhật ký bằng:

systemctl status node-sync.service
journalctl -u node-sync.service --since today
systemctl list-timers node-sync.timer

Log ứng dụng nên có mã lượt chạy, thời điểm bắt đầu, thời lượng và số mục đã xử lý; không ghi secret hoặc dữ liệu nhạy cảm. Với cron, cần quản lý xoay vòng log để tránh đầy đĩa. Lỗi thường gặp gồm sai PATH, thiếu quyền ghi, đặt heap sát giới hạn RAM và nhầm việc giảm CPU sẽ khiến job hoàn thành nhanh hơn.

Câu hỏi thường gặp

Chỉ dùng setTimeout trong Node.js có đủ không?

Không. Timer phụ thuộc event loop và không phải giới hạn tài nguyên ở cấp hệ điều hành. Nó hữu ích cho logic ứng dụng nhưng nên kết hợp timeout bên ngoài.

Hosting dùng chung có áp dụng được systemd không?

Thông thường bạn không có quyền quản lý systemd cấp hệ thống. Hãy hỏi nhà cung cấp về giới hạn cron, thời gian tiến trình và quyền dùng công cụ cần thiết; không mặc định có quyền như VPS.

Job hết hạn có nên tự chạy lại ngay không?

Chỉ khi xử lý lại an toàn. Cần giới hạn số lần thử, có khoảng chờ và phân biệt lỗi tạm thời với thiếu tài nguyên kéo dài để tránh vòng lặp thất bại.

Áp dụng cho một job trước khi mở rộng

Hãy chọn một job, đo tải thực tế rồi thử timeout và chống chạy chồng trước. Nếu cần giới hạn tài nguyên rõ ràng hơn, chuyển sang service có kiểm soát và kiểm tra khả năng phục hồi dữ liệu.

Khi cần môi trường chạy phù hợp, bạn có thể tham khảo danh mục VPS hoặc hosting liên quan tại sieuthicode.com. Trước khi mua, hãy xác nhận tài nguyên theo tải, quyền quản trị, cơ chế bảo mật, phạm vi hỗ trợ, giấy phép phần mềm liên quan và khả năng kiểm thử cấu hình cron thực tế.

Chia sẻ bài viết này