Operations
1. Deployment
| Thuộc tính | Giá trị |
|---|---|
| Image | registry/outreach:<tag> |
| Replicas (mặc định) | 1 (lưu lượng thấp; API không trạng thái) |
| Resources (req/lim) | nhỏ - CPU/bộ nhớ theo baseline của cluster |
| HPA target | CPU (tuỳ chọn; lưu lượng tăng đột biến khi chạy chiến dịch) |
| Probes | GET /healthz (live), GET /readyz (ready) |
| Snowflake ID | 10 (APP_ENV_NODE_ID) |
| Chế độ migration | bun run migrate:dev / job khi khởi động; seed idempotent (alwaysRun) |
Traefik labels
yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.outreach.rule=PathPrefix(`/v1/api/outreach`)"
- "traefik.http.services.outreach.loadbalancer.server.port=3000"Chạy nhiều replica là an toàn: WebSocket emitter dựa trên Redis, nên bất kỳ replica nào cũng có thể phát tới mọi subscriber. Snowflake worker
10phải là duy nhất cho từng process đang chạy nếu mở rộng quá một - cần điều phốiAPP_ENV_NODE_ID.
2. Observability
| Tín hiệu | Nguồn | Nơi xem |
|---|---|---|
| Logs | stdout (key-value có cấu trúc) | kubectl logs <pod> / Loki |
| Metrics | Prometheus /metrics (nếu bật) | Grafana |
| Traces | không hoạt động (chưa nối tracer) | - |
| Health | GET /healthz, GET /readyz | Gateway portal |
| API spec | GET /v1/api/outreach/doc/openapi.json, /doc (Scalar) | Browser |
Trường log quan trọng
| Trường | Nguồn | Ghi chú |
|---|---|---|
requestId | header X-Request-Id | Truyền xuyên các service |
inquiryId | thông báo WS | Inquiry SENT | inquiryId: %s | rooms: %j |
rooms | thông báo WS | Các phòng quan sát đích |
3. Security
| Mối quan tâm | Biện pháp |
|---|---|
| Xác thực (AuthN) | JWT (ES256, JWKS từ identity) trên CRUD + thống kê |
| Endpoint công khai | /inquiries/submit, /subscribers/subscribe, /subscribers/unsubscribe không xác thực theo thiết kế |
| Lạm dụng / spam | Không có rate limit tích hợp - dựa vào middleware Traefik + WAF đặt trước các endpoint submit/subscribe công khai |
| Token huỷ đăng ký | Snowflake unsubscribeToken, ẩn khỏi response của API; chỉ token hợp lệ mới vô hiệu hoá được - xem ADR-0001 |
| Phân quyền (AuthZ) | Permission của Casbin được seed cho OWNER/EMPLOYEE/CASHIER |
| Bí mật | K8s Secret được mount thành biến môi trường (DB, mật khẩu Redis) |
| TLS | Kết thúc tại gateway |
| Network policy | Cilium - cho phép gateway + identity JWKS + Redis + Postgres |
| Soft-delete | deletedAt; không hard-delete theo mặc định |
4. Runbook
4.1 Các loại cảnh báo
| Cảnh báo | Kích hoạt khi | Kiểm tra | Khắc phục | Báo lên |
|---|---|---|---|---|
outreachHighErrorRate | 5xx >5% trong 5 phút | log level=error | kiểm tra kết nối DB / Redis | trực backend |
outreachSubmitFlood | RPS submit tăng đột biến | metric Traefik | bật/tăng rate limit tại gateway | trực SRE |
outreachWSNotReady | cảnh báo lặp lại Socket event service not ready | tình trạng Redis | khởi động lại pod / kiểm tra Redis | trực backend |
4.2 Thao tác thường gặp
| Thao tác | Lệnh |
|---|---|
| Theo dõi log | kubectl logs -n <ns> -f deploy/outreach |
| Chạy lại seed | chạy migration (seed alwaysRun, idempotent) - chỉ người vận hành chạy |
| Kiểm tra spec trực tiếp | mở /v1/api/outreach/doc |
| Xử lý spam | đánh dấu các yêu cầu vi phạm thành CANCELLED qua CRUD của admin |
Service này không có Kafka replay và không có BullMQ queue - không có gì để rút cạn hay phát lại.
5. Trang liên quan
- Configuration
/runbook/- runbook trung tâm cho các sự cố liên-service- Decisions