Skip to content

ADR-0003. Thực thi SLA qua cron monitor lặp lại + escalation worker

TrườngGiá trị
StatusAccepted
Ngày2026-04-10
Người quyết địnhPhat Nguyen
Thay thế-

Bối cảnh

  • Mỗi ticket có hai mốc hạn (phản hồi đầu tiên, xử lý xong) tính từ SlaPolicy của nó. Service phải phát hiện các mốc hạn sắp đến (cảnh báo), các trường hợp vi phạm, và vi phạm nghiêm trọng, rồi gửi thông báo và escalate.
  • Việc phát hiện mốc hạn về bản chất là theo thời gian: không có gì trong luồng request báo cho hệ thống biết "ticket này vừa vượt 75% mức SLA của nó." Các lựa chọn là dùng job trễ theo từng ticket được lên lịch ở mỗi ngưỡng, hoặc dùng một lượt quét định kỳ.
  • Escalation (Level 1→2→3) phải đáng tin cậy và có thể retry, với mức ưu tiên cao hơn các tác vụ thường lệ.

Quyết định

Dùng một job cron BullMQ lặp lại kết hợp một escalation worker chuyên dụng:

  1. QueueComponent.scheduleSlaMonitoring() đăng ký một job lặp lại trên queue helpdesk.sla-monitor với pattern: WORKER_CONFIG.SLA_MONITOR_INTERVAL (mỗi phút) và một jobId: 'sla-monitor-cron' cố định để các bản trùng không thể tích lũy. Khi khởi động, nó gỡ các bản lặp lại cũ trước.
  2. sla-monitor.worker (concurrency 1) chạy RunSlaMonitorUseCase, quét các hàng SlaTracker theo từng lô (SLA_BATCH_SIZE = 100) để tìm trường hợp cảnh báo/vi phạm so với SLA_WARNING_THRESHOLDS (75/90/100/150).
  3. Trường hợp vi phạm sẽ đưa job thông báo và job escalation vào queue helpdesk.escalation (concurrency 5, priority 1, 3 lần retry với backoff theo hàm mũ), được escalation.workerProcessEscalationUseCase tiêu thụ.
  4. Có thể kiểm tra thủ công qua QueueComponent.triggerSlaCheck({ ticketId }) ở mức priority HIGH.

Hệ quả

ƯuNhược
Một lượt cron xử lý mọi ticket - không phát sinh việc lên lịch riêng cho từng ticketĐộ trễ phát hiện lên đến khoảng 1 phút (đúng bằng chu kỳ cron)
Một jobId cố định duy nhất ngăn các bản lặp lại bị trùng qua các lần khởi động lạiChi phí mỗi lượt quét tăng theo số ticket đang mở (đã giảm nhẹ bằng cách chia lô)
Escalation được tách riêng trên một queue ưu tiên cao, có retryMonitor chạy concurrency 1 là giới hạn throughput cho các tenant rất lớn
Có sẵn đường trigger thủ công để kiểm tra lại theo mục tiêu cụ thểWorker process phải đang chạy, nếu không việc thực thi SLA sẽ dừng âm thầm

Lưu ý: việc phân công lại cho senior-agent từ Level 2 trở lên hiện đang bị tắt trong code (lời gọi assignTicketUseCase bị comment) - escalation worker chỉ gửi thông báo. Xem Vận hành → Vấn đề đã biết.

Phương án đã cân nhắc

Tùy chọnVì sao bị từ chối
Job trễ theo từng ticket ở mỗi ngưỡngBùng nổ số job được lên lịch; rối rắm khi phải lên lịch lại lúc đổi policy/priority
Cron bên ngoài / k8s CronJob gọi vào một endpointThêm sự ràng buộc về hạ tầng; bản lặp lại BullMQ giữ việc lên lịch ngay trong ứng dụng và quan sát được
DB trigger / pg_cronĐẩy logic nghiệp vụ vào database; khó kiểm thử và khó quan sát

Tham khảo

  • src/components/queue.component.ts (scheduleSlaMonitoring, triggerSlaCheck)
  • src/components/workers/sla-monitor.worker.ts, escalation.worker.ts
  • src/application/use-cases/sla-policy/run-sla-monitor.use-case.ts, process-escalation.use-case.ts
  • src/shared/common/constants/common.constant.ts (WORKER_CONFIG, SLA_WARNING_THRESHOLDS, ESCALATION_TIMING)

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.