Skip to content

Vận hành

1. Deployment

Thuộc tínhGiá trị
Imageregistry/nx-seller-inventory:<tag>
Container Port3000
External Port31050
Snowflake ID5
Replicas (mặc định)1 (dev) / 2+ (staging+)
Resources (req/lim)100m / 500m CPU, 256Mi / 1Gi memory
HPA targetCPU 70% (khi scale)
Migration modeJob RUN_MODE=migrate trước khi rollout; on-boot cho dev
Live probeGET /v1/api/inventory/healthz
Ready probeGET /v1/api/inventory/readyz
Graceful shutdownSIGTERM/SIGINT → đóng Kafka producer + consumer (isForce=false)

Label routing Traefik

yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.inventory.rule=PathPrefix(`/v1/api/inventory`)"
  - "traefik.http.services.inventory.loadbalancer.server.port=3000"

Hạ tầng bắt buộc

Phụ thuộcLý do
PostgreSQLDatastore chính (schema inventory)
Kafka brokersBắt buộc — service từ chối khởi động nếu APP_ENV_KAFKA_BROKERS rỗng
DebeziumBắt buộc cho topic CDC (MERCHANT, PRODUCT_VARIANT)
RedisTùy chọn — auth cache; service vẫn start được nếu thiếu
@nx/identity reachableVerify JWKS trên mọi JWT

2. Observability

Tín hiệuNguồnTìm ở đâu
Logsstdout (structured logger IGNIS, định dạng key: %s)kubectl logs deploy/inventory / Loki
HealthGET /v1/api/inventory/healthz, GET /readyzGateway portal
OpenAPI live specGET /v1/api/inventory/doc/openapi.jsonTrình duyệt gateway portal
MetricsTraefik gateway :30800 (Prometheus scrape)Grafana — dashboard gateway
Kafka lagKafka cluster broker / BurrowTBD

Trường log quan trọng

TrườngNguồnGhi chú
requestIdheader X-Request-IdTruyền cross-service
userIdsubject của JWT
merchantIdscope của request
topic / partition / offsetKafka consumerLog mỗi message
referenceType / referenceIdinventory tracking writesĐể tương quan audit trail

Truy vấn log hữu ích

Câu hỏiTruy vấn
Lỗi trừ stock (oversell-blocked)note=OVERSELL_BLOCKED
Re-deliveriestopic=payment.success AND idempotent skip
Lỗi emit POKafka emit failed AND topic=purchase-order.received

3. Security

ConcernBiện pháp
AuthNJWT (ES256, JWKS lấy từ identity lúc boot + on-demand)
AuthZCasbin qua PolicyDefinitionService; permission cache trong Redis (hoặc in-memory nếu Redis tắt)
Service-to-serviceStrategy BASIC (commerce → inventory direct call trong TX dùng chung)
SecretsK8s Secret mount thành env (APP_ENV_DB_URL, APP_ENV_KAFKA_SASL_PASSWORD, v.v.) — không bao giờ trong code
TLSTerminate ở Nginx → Traefik → service plaintext (intra-cluster)
Rate limitMiddleware Traefik (mặc định 100 rps/IP)
Network policyCilium — chỉ cho phép gateway + Kafka + Postgres + Redis + identity (JWKS)
Soft-deletedeletedAt — không hard-delete mặc định; InventoryTracking bất biến
IdempotencyMọi Kafka handler đều idempotent — an toàn dưới delivery at-least-once

4. Runbook

4.1 Lớp Alert

AlertTriggerKiểm traSửaEscalate
InventoryHighErrorRate5xx >5% trong 5mkubectl logs deploy/inventory | grep level=errorXác định endpoint lỗi; restart nếu kẹton-call backend
InventoryKafkaLagLag consumer group >10k trên topic bất kỳBurrow / Kafka admin toolsScale replicas nếu CPU-bound; kiểm tra lỗi handleron-call SRE
InventoryDBConnectionExhaustedLỗi pool exhaustedpg_stat_activityTăng APP_ENV_DB_POOL_MAX; kiểm tra TX chạy lâuon-call backend
InventoryStockNegativeRow có quantityOnHand < 0 trong DBChạy query reconciliationAudit InventoryTracking để tìm nguyên nhân; adjustment thủ côngon-call backend + finance
InventoryOversellSpikeSố lượng note=OVERSELL_BLOCKED tăngTìm logKiểm tra pattern sale order; cân nhắc bật allowOversell cho item bán nhanhon-call business + backend
InventoryPOEmitFailureLỗi log emit purchase-order.receivedGrep logsJob replay thủ công; verify sức khỏe Kafka clusteron-call SRE

4.2 Thao tác thường gặp

Thao tácLệnh
Tail logskubectl logs -n <ns> -f deploy/inventory
Chạy migration thủ côngkubectl exec -it deploy/inventory -- bun run migrate
Reset offset Kafka consumerDùng Kafka admin: kafka-consumer-groups --reset-offsets --group SVC-00050-INVENTORY_CONSUMER_GROUP --topic <topic> --to-earliest --execute
Replay một PAYMENT_SUCCESS cho một orderRe-emit thủ công message với cùng key từ sale; idempotency lookup sẽ skip nếu đã xử lý
Force re-seed permissionTăng version migration + chạy lại migrate
Inspect stock cho một item ở các locationSELECT * FROM "InventoryStock" WHERE inventory_item_id = '...' AND deleted_at IS NULL;
Audit movement cho một SaleOrderSELECT * FROM "InventoryTracking" WHERE reference_type = 'SALE_ORDER' AND reference_id = '...';

4.3 Kịch bản Recovery

Kịch bảnRecovery
Service crash giữa chừng handlerKafka offset CHƯA commit → message re-deliver khi restart; idempotency lookup skip các entry đã xử lý
DB transaction thành công, Kafka emit lỗi (PO receive)Log ghi nhận emit lỗi; tool replay thủ công publish từ snapshot PurchaseOrder
Phát hiện sai sót đếm stock(1) Pause traffic bán, (2) chạy cycle count qua InventoryTicket type=CYCLE_COUNT, (3) ghi tracking row ADJUSTMENT_NEUTRAL
Mất default location của merchantRe-emit Merchant CDC event → ensureDefaultLocation tạo lại

5. Runbook Cross-Service

Cho sự cố trải dài nhiều service, xem central runbook/:

6. Trang liên quan

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