1. Bối cảnh doanh nghiệp & phạm vi
Một nhà mạng di động ảo (MVNO) tại Việt Nam phục vụ 4,2 triệu thuê bao trả trước và trả sau, phát sinh trung bình 38 triệu bản ghi chi tiết cuộc gọi (CDR — call detail record) mỗi ngày từ hệ thống chuyển mạch (switch) và cổng dữ liệu (data gateway), chưa kể các CDR roaming quốc tế gửi về theo lô từ đối tác qua giao thức TAP3/NRTRDE với độ trễ vài giờ đến vài ngày. Toàn bộ dòng CDR này phải đi qua một chuỗi xử lý gồm mediation (chuẩn hoá định dạng, loại bỏ bản ghi hỏng, phát hiện trùng lặp), rating (tính cước theo gói cước và bảng giá đang áp dụng tại thời điểm phát sinh cuộc gọi), và billing (trừ vào số dư tài khoản trả trước hoặc cộng dồn vào hoá đơn trả sau). Sai sót ở bất kỳ khâu nào — tính cước sai, tính trùng một CDR, hoặc trừ tiền không khớp với cước đã tính — đều trực tiếp ảnh hưởng đến doanh thu ghi nhận (revenue leakage nếu tính thiếu, hoặc khiếu nại khách hàng ồ ạt nếu tính thừa) và có thể vi phạm quy định của Bộ Thông tin và Truyền thông về minh bạch cước viễn thông.
Phạm vi tự động hoá
- API mediation nhận/chuẩn hoá CDR, phát hiện & loại CDR trùng theo cdrId
- Rating engine: tính cước theo gói cước, bảng giá roaming, quy tắc làm tròn block
- Billing/Balance: top-up, trừ cước, giới hạn khi số dư không đủ, đối soát cuối kỳ
- Ngoài phạm vi: thuật toán định tuyến cuộc gọi trong mạng lõi (core network), UI CSKH
2. Kiến trúc hệ thống & luồng nghiệp vụ
Kiến trúc gồm 5 khối chính nối tiếp nhau: Switch/HLR phát sinh CDR gốc ở định dạng ASN.1/nhị phân, Mediation Layer chuyển đổi sang định dạng chuẩn nội bộ (JSON/Avro), loại bỏ bản ghi lỗi cú pháp và gắn cờ nghi ngờ trùng lặp dựa trên cdrId (do switch cấp) kết hợp hash của (msisdn, startTime, duration, callType), Rating Engine tra bảng giá đang hiệu lực tại thời điểm startTime của CDR (không phải thời điểm xử lý) để tính cước, Billing/Balance Service áp dụng cước vào tài khoản — trừ trực tiếp với thuê bao trả trước hoặc cộng dồn vào bảng invoice_line cho thuê bao trả sau, và cuối cùng Invoice Service tổng hợp theo kỳ cước để xuất hoá đơn. CDR Store đóng vai trò then chốt: đây là nơi duy nhất lưu trạng thái 'đã rate' hay 'chưa rate' của từng cdrId, và mọi thao tác ghi vào đây phải là idempotent — nếu mediation gửi lại cùng một CDR (do retry mạng, do switch gửi trùng), rating engine phải nhận diện và bỏ qua thay vì tính cước lần thứ hai.
- Điểm khó test #1: rating phải dùng bảng giá tại startTime của CDR, không phải thời điểm xử lý batch (dữ liệu roaming có thể trễ vài ngày)
- Điểm khó test #2: idempotency theo cdrId phải đúng ngay cả khi mediation gửi lại do lỗi mạng hoặc do đối tác roaming gửi trùng file TAP3
- Điểm khó test #3: trừ cước và tính cước là 2 bước riêng biệt (rate rồi mới charge) — cần test lệch pha giữa 2 bước khi hệ thống crash giữa chừng
3. Mô hình dữ liệu & bất biến nghiệp vụ (oracle)
Mô hình dữ liệu cốt lõi xoay quanh 5 bảng: `Subscriber` (msisdn, planId, balance, status), `RatingPlan` (planId, freeMinutes, freeData, unitPriceVoice, unitPriceData, roamingPartnerId, effectiveFrom, effectiveTo), `Cdr` (cdrId UNIQUE, msisdn, callType, startTime, duration, dataVolume, roamingCountry, ratedStatus, ratedAmount), `Transaction` (txId, msisdn, type[TOPUP|CHARGE], amount, idempotencyKey UNIQUE, balanceAfter, createdAt), và `Invoice` (invoiceId, msisdn, period, totalAmount, lineItems). Ràng buộc UNIQUE trên `Cdr.cdrId` là tuyến phòng thủ đầu tiên chống tính trùng ở tầng database, nhưng riêng nó chưa đủ vì rating engine có thể đọc CDR, tính cước, rồi crash trước khi cập nhật `ratedStatus` — lúc đó CDR vẫn còn ở trạng thái 'chưa rate' và job retry sẽ tính lại, tạo ra 2 dòng Transaction cho cùng 1 cuộc gọi nếu không có idempotencyKey trên Transaction.
💬 Bình luận (0)
Chưa có bình luận nào. Hãy là người đầu tiên!