金融系统对架构有极高的要求,包括高可用、高性能、强一致性和安全性。
本文系统介绍金融级分布式架构的核心设计原则、关键技术和实战案例,帮助你构建可靠的金融系统。
| 要求 | 说明 | 指标 |
|---|
| 高可用 | 系统持续可用 | 99.99%以上 |
| 高性能 | 快速响应 | P99 < 100ms |
| 强一致性 | 数据准确无误 | 最终一致性 |
| 安全性 | 防止欺诈和攻击 | 多层防护 |
| 可审计 | 操作可追溯 | 完整日志 |
金融系统挑战:
1. 交易一致性
├─ 资金安全
├─ 数据一致
└─ 事务完整性
2. 高并发处理
├─ 秒杀场景
├─ 实时交易
└─ 批量处理
3. 风险控制
├─ 反欺诈
├─ 反洗钱
└─ 风险预警
4. 监管合规
├─ 数据报送
├─ 审计追溯
└─ 隐私保护
金融系统分层架构:
┌─────────────────────────────────────────────────────────────┐
│ 接入层 │
│ ├─ API网关 ├─ 鉴权认证 ├─ 流量控制 │
├─────────────────────────────────────────────────────────────┤
│ 业务层 │
│ ├─ 核心业务 ├─ 风控业务 ├─ 营销业务 │
├─────────────────────────────────────────────────────────────┤
│ 能力层 │
│ ├─ 账户能力 ├─ 支付能力 ├─ 风控能力 │
├─────────────────────────────────────────────────────────────┤
│ 数据层 │
│ ├─ 核心数据 ├─ 分析数据 ├─ 日志数据 │
├─────────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ ├─ 数据库 ├─ 缓存 ├─ 消息队列 │
└─────────────────────────────────────────────────────────────┘
| 原则 | 说明 |
|---|
| 资金安全 | 资金操作必须准确无误 |
| 最终一致 | 业务最终一致,避免强一致 |
| 异步解耦 | 核心链路异步化 |
| 幂等设计 | 操作可重复执行 |
| 审计追溯 | 操作可追溯 |
账户体系设计:
┌─────────────────────────────────────────────────────────────┐
│ 账户体系 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 总账账户 │ │ 明细账户 │ │ 辅助账户 │ │
│ │ (科目) │ │ (客户) │ │ (内部) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 会计分录 │
│ ├─ 借方科目 ├─ 贷方科目 ├─ 金额 │
└─────────────────────────────────────────────────────────────┘
设计原则:
├─ 复式记账:每笔交易同时记录借贷双方
├─ 科目体系:清晰的科目层级结构
├─ 实时清算:交易实时清算
└─ 定期对账:定期核对账务
// 支付系统架构
@Service
public class PaymentService {
@Autowired
private AccountService accountService;
@Autowired
private RiskService riskService;
@Autowired
private MessageQueue mq;
@GlobalTransactional
public PaymentResult pay(PaymentRequest request) {
// 1. 风控检查
riskService.check(request);
// 2. 账户扣款
accountService.deduct(request.getFromAccount(), request.getAmount());
// 3. 账户入账
accountService.add(request.getToAccount(), request.getAmount());
// 4. 发送支付成功消息
mq.send("payment.success", request);
return PaymentResult.success();
}
}
// TCC分布式事务
@LocalTCC
public interface AccountTccService {
@TwoPhaseBusinessAction(name = "deduct", commitMethod = "confirm", rollbackMethod = "cancel")
boolean tryDeduct(@BusinessActionContextParameter(paramName = "accountId") String accountId,
@BusinessActionContextParameter(paramName = "amount") BigDecimal amount);
boolean confirm(BusinessActionContext context);
boolean cancel(BusinessActionContext context);
}
// 使用
@GlobalTransactional
public void transfer(String from, String to, BigDecimal amount) {
accountTccService.tryDeduct(from, amount);
accountTccService.tryAdd(to, amount);
}
// 幂等键设计
@Component
public class IdempotentService {
@Autowired
private RedisTemplate redis;
public boolean tryAcquire(String idempotentKey) {
// 尝试获取幂等键
Boolean result = redis.opsForValue()
.setIfAbsent("idempotent:" + idempotentKey, "1", 24, TimeUnit.HOURS);
return Boolean.TRUE.equals(result);
}
public void release(String idempotentKey) {
redis.delete("idempotent:" + idempotentKey);
}
}
// 使用
public PaymentResult pay(PaymentRequest request) {
String idempotentKey = request.getOrderId() + ":" + request.getAmount();
if (!idempotentService.tryAcquire(idempotentKey)) {
throw new BusinessException("重复支付");
}
try {
return doPay(request);
} catch (Exception e) {
idempotentService.release(idempotentKey);
throw e;
}
}
-- 资金对账
SELECT
a.account_id,
a.balance as core_balance,
b.balance as business_balance,
(a.balance - b.balance) as diff
FROM core_account a
JOIN business_account b ON a.account_id = b.account_id
WHERE ABS(a.balance - b.balance) > 0.01;
-- 差异处理
INSERT INTO reconciliation_diff
SELECT * FROM (
SELECT
a.account_id,
a.balance as core_balance,
b.balance as business_balance
FROM core_account a
JOIN business_account b ON a.account_id = b.account_id
WHERE ABS(a.balance - b.balance) > 0.01
) t;
// 支付系统架构
@Component
public class PaymentSystem {
@Autowired
private OrderService orderService;
@Autowired
private PaymentService paymentService;
@Autowired
private NotifyService notifyService;
// 支付流程
public PaymentResult processPayment(PaymentRequest request) {
// 1. 创建支付单
PaymentOrder paymentOrder = createPaymentOrder(request);
// 2. 风控检查
riskService.check(paymentOrder);
// 3. 执行支付
PaymentResult result = paymentService.pay(paymentOrder);
// 4. 更新订单状态
orderService.updateStatus(request.getOrderId(), result.getStatus());
// 5. 通知商户
notifyService.notifyMerchant(paymentOrder, result);
return result;
}
}
// 风控系统
@Component
public class RiskControlSystem {
@Autowired
private RiskRuleEngine ruleEngine;
@Autowired
private BlacklistService blacklistService;
public RiskResult check(PaymentRequest request) {
// 1. 黑名单检查
if (blacklistService.isBlocked(request.getUserId())) {
return RiskResult.block("用户在黑名单中");
}
// 2. 规则检查
List<RiskRule> rules = ruleEngine.evaluate(request);
// 3. 风险评估
int riskScore = calculateRiskScore(rules);
if (riskScore > 80) {
return RiskResult.block("风险评分过高");
} else if (riskScore > 60) {
return RiskResult.review("需要人工审核");
}
return RiskResult.pass();
}
}
| 原则 | 说明 |
|---|
| 资金安全第一 | 资金操作必须准确 |
| 最终一致性 | 避免强一致性能 |
| 异步解耦 | 核心链路异步化 |
| 幂等设计 | 操作可重复执行 |
| 问题 | 原因 | 解决方案 |
|---|
| 资金差异 | 数据不一致 | 实时对账 |
| 支付超时 | 系统响应慢 | 异步化处理 |
| 重复支付 | 幂等失效 | 幂等键控制 |