Operations
1. Triển khai
Một image duy nhất, deploy tối đa hai role qua
APP_ENV_APPLICATION_ROLES. Roleapiphục vụ REST + enqueue; roleworkerconsume Kafka, render, encrypt, upload, và chạy quét recovery + WebSocket emitter.
| Thuộc tính | Giá trị |
|---|---|
| Image | registry/ledger:<tag> |
| Roles | api, worker, hoặc cả hai (APP_ENV_APPLICATION_ROLES) |
| Container Port | 3000 (ngoài 31060) |
| Probes | GET /healthz (live), GET /readyz (ready) |
| Snowflake ID | 6 (APP_ENV_NODE_ID) |
| Migration mode | RUN_MODE=migrate (migrate.ts) — bỏ qua components/services/controllers |
| Scaling | Scale replica worker và/hoặc APP_ENV_KAFKA_CONSUMER_COUNT cho throughput tạo |
Traefik labels
yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.ledger.rule=PathPrefix(`/v1/api/ledger`)"
- "traefik.http.services.ledger.loadbalancer.server.port=3000"Chỉ role
apicần route ingress. Pod chỉ-workerkhông nhận traffic HTTP.
2. Observability
| Tín hiệu | Nguồn | Xem ở đâu |
|---|---|---|
| Logs | stdout (key-value có cấu trúc) | kubectl logs <pod> / Loki |
| Pha pipeline | dòng log FETCH_* / GENERATE_* / UPLOAD_DONE / COMPLETED / FAILED theo ledgerId | pod worker |
| Health | GET /healthz, GET /readyz | Portal gateway |
| WS emit | dòng [notifyJobStatus] (warn khi emitter chưa sẵn) | pod worker |
Trường log chính
| Trường | Nguồn | Ghi chú |
|---|---|---|
ledgerId | message value | Khoá tương quan chính xuyên pipeline |
merchantId / type / period | sổ đã nạp | Định danh job |
attemptCount | LedgerJob | Số lần retry trọn đời |
errorCode | failureReason | Xem runbook |
3. Bảo mật
| Mối quan tâm | Giảm thiểu |
|---|---|
| AuthN | JWT (ES256, JWKS từ identity) — VerifierApplication |
| AuthZ | Casbin qua PolicyDefinition (cache Redis); mọi endpoint gọi assertMerchantAccess |
| Mã hoá file | AES-256-GCM at-rest trong S3 (APP_ENV_LEDGER_ENCRYPTION_KEY); file chỉ phục vụ qua download có xác thực |
| Gia cố download | Content-Disposition + X-Content-Type-Options: nosniff; decrypt trong bộ nhớ, không URL S3 công khai |
| Secrets | K8s Secret dạng env (APP_ENV_LEDGER_ENCRYPTION_KEY, Kafka SASL, S3 key) |
| Network policy | Cilium — chỉ cho gateway + Kafka + Redis + S3 |
| Soft-delete | deletedAt — không hard-delete sổ |
4. Runbook
4.1 Lớp cảnh báo
| Cảnh báo | Kích hoạt | Kiểm tra | Khắc phục | Leo thang |
|---|---|---|---|---|
ledgerJobRejectedSpike | tỷ lệ LedgerJob.status=REJECTED tăng | logs FAILED/errorCode | retry theo error code (bên dưới) | backend on-call |
ledgerStalledJobs | nhiều job bị reset bởi quét recovery | [RecoveryComponent] Found N stalled job | kiểm sức khoẻ worker / APP_ENV_JOB_TIMEOUT_MS | backend on-call |
ledgerConsumerLag | lag ledger.generate tăng | logs consumer / lag Kafka | scale worker / APP_ENV_KAFKA_CONSUMER_COUNT | SRE on-call |
ledgerWsNotReady | lặp lại WS emitter not ready | kết nối Redis WS của worker | kiểm APP_ENV_WEBSOCKET_REDIS_* | SRE on-call |
4.2 Mã lỗi (failureReason.errorCode)
| Code | Ý nghĩa | Hành động |
|---|---|---|
FETCH_DATA_ERROR | Lấy/parse dữ liệu nguồn thất bại (Zod) | xem dữ liệu nguồn; retry thủ công |
JOB_EXECUTION_FAILED | Lỗi pipeline chung (render/upload) | kiểm logs; retry |
ENQUEUE_FAILED | Kafka producer không publish được | kiểm broker/SASL; retry |
JOB_IN_PROGRESS | Retry/regenerate khi PENDING/PROCESSING | chờ hoàn tất |
JOB_NOT_READY | Download trước khi COMPLETED | chờ/retry tạo |
4.3 Thao tác thường gặp
| Thao tác | Lệnh / Hành động |
|---|---|
| Tail logs worker | kubectl logs -n <ns> -f deploy/ledger-worker |
| Retry thủ công | POST /v1/api/ledger/ledgers/:id/retry |
| Regenerate DRAFT | POST /v1/api/ledger/ledgers/:id/regenerate |
| Ép phục hồi kẹt | chờ quét (APP_ENV_SWEEP_INTERVAL_MS) hoặc restart worker (quét ban đầu lúc boot) |
| Chạy migration | job RUN_MODE=migrate / bun run migrate:dev (dev) |
Tái xử lý không bao giờ tự động — một message Kafka đã commit không được replay. Dùng retry/regenerate hoặc quét recovery.
5. Trang liên quan
- Configuration
- Generation Pipeline
/runbook/— runbook trung tâm cho sự cố xuyên service- Decisions