系统设计实战:担保业务核心系统架构设计
大约 13 分钟
前言
担保业务系统是典型的金融核心系统,对数据一致性、高可用、风控合规有极高要求。本文将分享一套经过实践验证的担保核心系统架构方案,从业务流程到技术选型,帮助你理解"金融级"系统是如何设计的。
第一部分:担保业务核心流程
1.1 业务流程全景
担保业务全生命周期:
申请阶段 审批阶段 签约阶段 保后管理
│ │ │ │
▼ ▼ ▼ ▼
┌──────┐ ┌────────────┐ ┌────────────┐ ┌─────────────┐
│客户 │ │风控审核 │ │电子签约 │ │还款跟踪 │
│提交 │→│·反欺诈检查 │→│·合同生成 │→│·还款提醒 │
│担保 │ │·信用评估 │ │·客户签署 │ │·逾期监控 │
│申请 │ │·额度审核 │ │·担保生效 │ │·代偿处置 │
└──────┘ │·人工复核 │ └────────────┘ │·追偿管理 │
└────────────┘ └─────────────┘
放款环节:
┌──────┐ ┌──────────┐ ┌─────────┐
│银行 │←──→│ 担保公司 │──→│ 客户 │
│放款 │ │ 收取保费 │ │ 获得贷款│
└──────┘ └──────────┘ └─────────┘
1.2 核心流程详解
流程 1:担保申请
客户提交担保申请 → 系统校验客户资质 → 风控引擎评估 → 生成授信额度 → 客户确认担保方案
流程 2:风控审批
风控规则匹配 → 反欺诈检测 → 信用评分 → 额度计算 → 人工复核(大额)→ 审批结论
流程 3:电子签约
合同模板选择 → 填充业务数据 → 生成电子合同 → 客户签署(人脸识别+短信验证)→ 合同归档 → 担保生效
流程 4:保后管理
定期风险监控 → 还款提醒 → 逾期预警 → 代偿处理 → 追偿管理 → 担保终止
第二部分:系统架构全景图
2.1 整体分层架构
┌─────────────────────────────────────────────────────────────────┐
│ 接入层 (Gateway) │
│ API Gateway (Kong/Spring Cloud Gateway) │
│ · 统一鉴权 · 限流熔断 · 协议转换 · 流量染色 │
├─────────────────────────────────────────────────────────────────┤
│ 业务服务层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │客户服务 │ │额度服务 │ │审批服务 │ │签约服务 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │放款服务 │ │保后服务 │ │产品服务 │ │账务服务 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 领域支撑层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │风控引擎 │ │规则引擎 │ │流程引擎 │ │消息中心 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │Nacos │ │Sentinel │ │RocketMQ │ │Seata │ │
│ │注册/配置 │ │限流/熔断 │ │消息队列 │ │分布式事务│ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 数据层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │MySQL │ │Redis │ │ES │ │OSS │ │
│ │业务数据 │ │缓存/分布式│ │日志检索 │ │文件存储 │ │
│ │ │ │锁 │ │ │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────┘
2.2 微服务划分
服务 核心职责 数据库
────────────────────────────────────────────────────────────
customer-service 客户信息、实名认证、信用评级 customer_db
product-service 担保产品配置、费率管理 product_db
credit-service 授信申请、额度管理、额度变更 credit_db
guarantee-service 担保申请、担保审核、担保变更 guarantee_db
risk-service 风控规则、反欺诈、信用评分 risk_db
approval-service 审批流程、多级审批、审批意见 approval_db
contract-service 合同生成、电子签章、合同归档 contract_db
loan-service 放款申请、放款确认、还款计划 loan_db
post-loan-service 保后监控、逾期管理、代偿追偿 post_loan_db
account-service 保费计算、账务处理、资金清算 account_db
notification-service 短信、邮件、站内信、推送 notification_db
第三部分:核心服务设计
3.1 客户服务(customer-service)
/**
* 客户聚合根 - 担保业务中的客户
*
* 关键约束:
* 1. 客户必须完成实名认证
* 2. 一个证件号只能注册一个客户
* 3. 黑名单客户不能创建担保
*/
public class Customer {
private CustomerId id;
private CustomerType type; // PERSONAL / ENTERPRISE
// 基本信息
private String name;
private IdCard idCard; // 值对象:身份证号
private PhoneNumber phone;
// 认证信息
private boolean realNameVerified;
private LocalDateTime verifiedAt;
private String verifiedBy;
// 信用信息
private CreditRating creditRating;
private CustomerStatus status;
// 关联信息
private List<CustomerRelation> relations; // 关联人(配偶、担保人等)
/**
* 实名认证
*/
public void verifyRealName(RealNameInfo info) {
if (this.realNameVerified) {
throw new DomainException("已通过实名认证,无需重复认证");
}
// 验证姓名与证件号一致性
if (!info.matchesNameAndId(this.name, this.idCard)) {
throw new DomainException("姓名与证件号不匹配");
}
this.realNameVerified = true;
this.verifiedAt = LocalDateTime.now();
this.verifiedBy = info.getChannel();
}
/**
* 加入黑名单
*/
public void blacklist(String reason) {
if (hasActiveGuarantee()) {
throw new DomainException("存在生效中的担保,不能加入黑名单");
}
this.status = CustomerStatus.BLACKLISTED;
registerEvent(new CustomerBlacklistedEvent(this.id, reason));
}
public boolean canApplyGuarantee() {
return this.status == CustomerStatus.ACTIVE
&& this.realNameVerified
&& this.creditRating != CreditRating.D;
}
}
3.2 额度服务(credit-service)
/**
* 授信额度聚合
*
* 业务流程:
* 客户申请 → 系统评估 → 额度审批 → 额度生效 → 额度使用/释放 → 额度到期
*/
public class CreditLine {
private CreditLineId id;
private CustomerId customerId;
private GuaranteeProductId productId;
private Money totalAmount;
private Money usedAmount;
private Money frozenAmount;
private CreditLineStatus status;
private DateRange effectivePeriod;
private List<CreditUsageRecord> usageRecords;
/**
* 占用额度(担保申请时调用)
*/
public CreditUsageRecord reserve(Money amount, GuaranteeId guaranteeId) {
assertActive();
assertWithinPeriod();
Money available = getAvailableAmount();
if (amount.greaterThan(available)) {
throw new InsufficientCreditException(
String.format("额度不足:需要 %s,可用 %s", amount, available));
}
// 先冻结
this.frozenAmount = this.frozenAmount.add(amount);
CreditUsageRecord record = new CreditUsageRecord(
this.id, guaranteeId, amount, CreditUsageType.RESERVE);
this.usageRecords.add(record);
registerEvent(new CreditReservedEvent(
this.id, this.customerId, guaranteeId, amount));
return record;
}
/**
* 确认占用 → 转为已使用
*/
public void confirmUsage(CreditUsageRecord record) {
this.frozenAmount = this.frozenAmount.subtract(record.getAmount());
this.usedAmount = this.usedAmount.add(record.getAmount());
record.confirm();
}
/**
* 释放冻结额度
*/
public void releaseFrozen(Money amount, GuaranteeId guaranteeId) {
this.frozenAmount = this.frozenAmount.subtract(amount);
CreditUsageRecord record = new CreditUsageRecord(
this.id, guaranteeId, amount, CreditUsageType.RELEASE);
this.usageRecords.add(record);
}
public Money getAvailableAmount() {
return this.totalAmount.subtract(this.usedAmount)
.subtract(this.frozenAmount);
}
private void assertActive() {
if (this.status != CreditLineStatus.ACTIVE) {
throw new DomainException("授信状态无效:" + this.status);
}
}
private void assertWithinPeriod() {
if (this.effectivePeriod.isExpired()) {
throw new DomainException("授信已过期");
}
}
}
3.3 审批服务(approval-service)
/**
* 审批流程聚合
*
* 支持多级审批:
* ≤ 50 万:一级审批
* 50-200 万:二级审批
* > 200 万:三级审批(含风控总监)
*/
public class ApprovalProcess {
private ApprovalId id;
private BusinessType businessType; // GUARANTEE, CREDIT_LINE, etc.
private String businessId;
private ApprovalLevel requiredLevel;
private List<ApprovalNode> nodes;
private ApprovalStatus overallStatus;
/**
* 创建审批流程
*/
public static ApprovalProcess create(
BusinessType type, String businessId, Money amount) {
ApprovalLevel level = determineLevel(amount);
ApprovalProcess process = new ApprovalProcess();
process.id = new ApprovalId(IDGenerator.next());
process.businessType = type;
process.businessId = businessId;
process.requiredLevel = level;
process.nodes = createNodes(level);
process.overallStatus = ApprovalStatus.PENDING;
return process;
}
private static ApprovalLevel determineLevel(Money amount) {
Money threshold = amount;
if (threshold.lessThanOrEqual(Money.rmb("500000"))) {
return ApprovalLevel.LEVEL_1;
} else if (threshold.lessThanOrEqual(Money.rmb("2000000"))) {
return ApprovalLevel.LEVEL_2;
}
return ApprovalLevel.LEVEL_3;
}
/**
* 提交审批意见
*/
public void submitOpinion(Approver approver, ApprovalOpinion opinion) {
ApprovalNode currentNode = getCurrentNode();
if (currentNode == null) {
throw new DomainException("当前没有待审批节点");
}
currentNode.approve(approver, opinion);
if (opinion.isRejected()) {
// 驳回 → 整个流程结束
this.overallStatus = ApprovalStatus.REJECTED;
registerEvent(new ApprovalRejectedEvent(this.id, this.businessId,
currentNode.getLevel(), opinion.getReason()));
} else if (isAllLevelsApproved()) {
// 全部通过
this.overallStatus = ApprovalStatus.APPROVED;
registerEvent(new ApprovalApprovedEvent(this.id, this.businessId));
}
// 否则继续下一级审批
}
private ApprovalNode getCurrentNode() {
return nodes.stream()
.filter(n -> n.getStatus() == NodeStatus.PENDING)
.findFirst().orElse(null);
}
private boolean isAllLevelsApproved() {
return nodes.stream()
.allMatch(n -> n.getStatus() == NodeStatus.APPROVED);
}
}
/**
* 审批节点
*/
public class ApprovalNode {
private ApprovalLevel level;
private String approverRole; // 审批角色
private Approver approver; // 实际审批人
private ApprovalOpinion opinion;
private NodeStatus status;
private LocalDateTime operatedAt;
}
3.4 签约服务(contract-service)
/**
* 签约流程
*/
@Service
public class ContractApplicationService {
@Transactional
public ContractSignResult sign(SignContractCommand command) {
// 1. 加载担保申请
GuaranteeApplication guarantee = guaranteeRepository
.findById(new GuaranteeId(command.getGuaranteeId()))
.orElseThrow(() -> new DomainException("担保申请不存在"));
// 2. 验证签约条件
guarantee.assertSignable();
// 3. 生成合同(使用模板引擎)
Contract contract = contractFactory.create(
guarantee, command.getTemplateId());
// 4. 发起电子签章(调用第三方电子签章平台)
SignResult signResult = eSignPlatformClient.createSignTask(
contract.getContractNo(),
contract.getParties(),
contract.getDocumentUrl()
);
// 5. 记录签约状态
contract.recordSignTask(signResult.getTaskId());
contractRepository.save(contract);
return ContractSignResult.pending(contract.getContractNo(),
signResult.getSignUrl()); // 返回给客户签署的 URL
}
}
第四部分:风控引擎设计
4.1 风控引擎架构
┌─────────────────────────────────────────────────────────┐
│ 风控引擎 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 反欺诈模块 │ │ 信用评估模块 │ │ 额度计算模块 │ │
│ │ │ │ │ │ │ │
│ │·黑名单检查 │ │·人行征信 │ │·基础额度 │ │
│ │·设备指纹 │ │·多头借贷 │ │·系数调整 │ │
│ │·关系图谱 │ │·收入评估 │ │·封顶限制 │ │
│ │·行为分析 │ │·评分模型 │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 规则引擎 (Drools/Easy Rules) │ │
│ │ │ │
│ │ RULE: 高风险行业拒绝 │ │
│ │ WHEN: industry in ["博彩","P2P","虚拟币"] │ │
│ │ THEN: reject("行业风险过高") │ │
│ │ │ │
│ │ RULE: 大额担保加强验证 │ │
│ │ WHEN: amount > 1000000 │ │
│ │ THEN: requireAdditionalVerification() │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
4.2 风控规则代码示例
/**
* 风控规则引擎
*/
@Service
public class RiskEngine {
private final List<RiskRule> rules;
private final KieContainer kieContainer; // Drools 规则引擎
public RiskEvaluationResult evaluate(RiskEvaluationRequest request) {
RiskContext context = new RiskContext(request);
// 1. 反欺诈检查(硬规则)
AntiFraudResult fraudResult = antiFraudCheck(context);
if (fraudResult.isFraudulent()) {
return RiskEvaluationResult.rejected("反欺诈命中:" + fraudResult.getReason());
}
// 2. 信用评分
CreditScore creditScore = creditScore(context);
// 3. 额度计算
Money creditAmount = calculateCreditAmount(context, creditScore);
// 4. 执行 Drools 规则
KieSession session = kieContainer.newKieSession();
session.insert(context);
session.insert(creditScore);
session.fireAllRules();
// 5. 汇总结果
return buildResult(context, creditScore, creditAmount);
}
private AntiFraudResult antiFraudCheck(RiskContext context) {
// 黑名单检查
if (blacklistService.contains(context.getCustomerId())) {
return AntiFraudResult.fraud("客户在黑名单中");
}
// 设备指纹检查
if (deviceFingerprintService.isRisky(context.getDeviceId())) {
return AntiFraudResult.fraud("设备风险评分过高");
}
// 关联关系图谱检查
if (relationGraphService.hasFraudRelation(context.getCustomerId())) {
return AntiFraudResult.fraud("关联关系存在风险");
}
return AntiFraudResult.pass();
}
}
第五部分:数据一致性保证
5.1 分布式事务方案选择
在担保核心系统中,不同场景适用不同的分布式事务方案:
| 场景 | 方案 | 理由 |
|---|---|---|
| 放款确认(资金类) | TCC / Seata AT | 需要强一致,资金不能出错 |
| 担保创建+额度占用 | RocketMQ 事务消息 | 异步解耦,允许最终一致 |
| 签约+担保生效 | Saga 编排 | 多步骤长流程,需补偿 |
| 保后数据同步 | 本地消息表 | 对时延不敏感 |
5.2 放款流程的 TCC 实现
/**
* 放款流程 TCC 实现
* Try: 冻结资金
* Confirm: 实际扣款
* Cancel: 解冻资金
*/
@Service
public class LoanTccService {
@Autowired private AccountClient accountClient;
@Autowired private GuaranteeClient guaranteeClient;
/**
* Try 阶段:资源预留
*/
public LoanTryResult tryLoan(LoanRequest request) {
// 1. 冻结担保公司的资金
FreezeResult freezeResult = accountClient.freeze(
request.getCompanyAccountId(), request.getAmount());
if (!freezeResult.isSuccess()) {
return LoanTryResult.fail("资金冻结失败");
}
// 2. 检查担保状态
GuaranteeDTO guarantee = guaranteeClient
.getGuarantee(request.getGuaranteeId());
if (!guarantee.isActive()) {
// 解冻资金
accountClient.unfreeze(freezeResult.getFreezeId());
return LoanTryResult.fail("担保未生效");
}
return LoanTryResult.success(freezeResult.getFreezeId());
}
/**
* Confirm 阶段:确认执行
*/
@Transactional
public void confirmLoan(LoanConfirmRequest request) {
// 实际扣款(从担保公司账户 → 客户账户)
accountClient.confirmTransfer(request.getFreezeId());
// 记录放款
loanRepository.save(LoanRecord.success(request));
}
/**
* Cancel 阶段:取消回滚
*/
@Transactional
public void cancelLoan(LoanCancelRequest request) {
// 解冻资金
accountClient.unfreeze(request.getFreezeId());
// 记录放款失败
loanRepository.save(LoanRecord.failed(request));
}
}
5.3 对账机制
-- 每日对账:检查担保状态与额度占用的一致性
-- 担保生效但额度未确认占用 → 异常
SELECT g.guarantee_id, g.status, c.used_amount
FROM t_guarantee g
LEFT JOIN t_credit_line c ON g.credit_line_id = c.id
WHERE g.status = 'ACTIVE'
AND g.credit_amount != c.used_amount_for_guarantee;
-- 担保已结清但额度未释放 → 异常
SELECT g.guarantee_id, g.status, c.used_amount
FROM t_guarantee g
LEFT JOIN t_credit_line c ON g.credit_line_id = c.id
WHERE g.status = 'CLOSED'
AND c.used_amount > 0;
第六部分:高可用设计
6.1 同城双活架构
┌─────────────┐
│ DNS/GSLB │ (智能 DNS 分流)
└──────┬──────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 机房 A │ │ 机房 B │ │ 机房 C │
│ (主) │ │ (主) │ │ (异地灾备)│
│ │ │ │ │ │
│ 100%流量 │ │ 50%流量 │ │ 冷备 │
└──────────┘ └──────────┘ └──────────┘
│ │
└─────┬──────┘
│
┌──────────┴──────────┐
│ MySQL 主主复制 │
│ Redis Cluster │
│ RocketMQ Cluster │
└─────────────────────┘
6.2 关键设计要点
1. 无状态设计
// 所有业务服务无状态,Session 信息存在 Redis
@Configuration
public class SessionConfig {
@Bean
public RedisHttpSessionConfiguration redisSession() {
return new RedisHttpSessionConfiguration();
}
}
// Token 基于 JWT,服务自身不需要存储 Session
2. 优雅关闭
@Component
public class GracefulShutdown {
@PreDestroy
public void onShutdown() {
log.info("开始优雅关闭...");
// 1. 停止接收新请求(标记服务为 OUT_OF_SERVICE)
nacosServiceRegistry.setStatus(InstanceStatus.DOWN);
// 2. 等待正在处理的请求完成(最多 30 秒)
awaitTermination(30, TimeUnit.SECONDS);
// 3. 关闭连接池
dataSource.close();
rocketMQTemplate.destroy();
log.info("优雅关闭完成");
}
}
3. 限流与熔断
// Sentinel 限流配置
@RestController
public class GuaranteeController {
@PostMapping("/guarantees")
@SentinelResource(
value = "createGuarantee",
blockHandler = "createGuaranteeBlockHandler",
fallback = "createGuaranteeFallback"
)
public Result<GuaranteeResponse> create(
@RequestBody GuaranteeRequest request) {
return Result.success(guaranteeService.create(request));
}
// 限流降级
public Result<GuaranteeResponse> createGuaranteeBlockHandler(
GuaranteeRequest request, BlockException e) {
return Result.error(ErrorCode.TOO_MANY_REQUESTS, "系统繁忙,请稍后重试");
}
// 熔断降级
public Result<GuaranteeResponse> createGuaranteeFallback(
GuaranteeRequest request, Throwable e) {
log.error("担保创建异常", e);
return Result.error(ErrorCode.SYSTEM_ERROR, "系统异常,我们正在处理");
}
}
4. 数据库高可用
# MySQL MHA + 读写分离
spring:
datasource:
master:
url: jdbc:mysql:replication://master1:3306,master2:3306/guarantee_db
slave:
url: jdbc:mysql:loadbalance://slave1:3306,slave2:3306/guarantee_db
第七部分:关键技术选型说明
7.1 技术选型全景
| 类别 | 选型 | 版本 | 说明 |
|---|---|---|---|
| 基础框架 | Spring Boot | 3.x | 主流企业框架 |
| 微服务框架 | Spring Cloud Alibaba | 2023.x | 与阿里云生态集成 |
| 注册/配置 | Nacos | 2.x | 统一注册与配置中心 |
| 服务调用 | OpenFeign + LoadBalancer | - | 声明式 HTTP 调用 |
| 限流熔断 | Sentinel | 1.8.x | 阿里开源,控制台强大 |
| API 网关 | Spring Cloud Gateway | 4.x | 响应式网关 |
| 消息队列 | RocketMQ | 5.x | 金融级事务消息 |
| 分布式事务 | Seata | 1.7.x | AT 模式轻量接入 |
| ORM | MyBatis-Plus | 3.5.x | 简化 CRUD |
| 缓存 | Redis (Lettuce) | 7.x | 高性能缓存 |
| 搜索引擎 | Elasticsearch | 8.x | 日志检索 |
| 规则引擎 | Drools | 8.x | 风控规则 |
| 流程引擎 | Flowable | 7.x | 审批流程 |
| 监控 | Prometheus + Grafana | - | 指标监控 |
| 链路追踪 | OpenTelemetry + Jaeger | - | 分布式追踪 |
| 日志收集 | Filebeat + ELK | 8.x | 日志平台 |
7.2 关键选型理由
为什么选 RocketMQ 而不是 Kafka?
| 考量 | RocketMQ | Kafka |
|---|---|---|
| 事务消息 | 原生支持,简单可靠 | 需要额外配置 |
| 顺序消息 | 支持消费端顺序 | 分区内有序,消费者端复杂 |
| 消息回溯 | 支持时间维度回溯 | 支持,但运维成本高 |
| 延迟消息 | 内置 18 个延迟级别 | 不原生支持 |
| 金融合规 | 阿里/蚂蚁背书 | 需自行保证 |
为什么选 Seata AT 而不是 XA?
- XA 协议性能极差(两阶段提交的长锁)
- Seata AT 只需一个小型 undo_log 表
- 对业务代码侵入性低(注解即可)
第八部分:架构评审常见问题预设
问题 1:为什么有这么多微服务?会不会拆太细了?
答:担保业务本身流程复杂,每个环节有独立的团队、独立的变更频率和独立的扩展需求。16 个微服务不是一蹴而就的,是随着业务发展逐步拆分出来的。如果从零开始,可从 5-6 个核心服务做起。
问题 2:分布式事务性能如何?
答:根据实测,Seata AT 模式的额外开销约为单机事务的 15-30%。对于日均十万级的担保业务来说,这个开销完全可以接受。对于极致性能要求的场景(如秒杀),会采用 RocketMQ 事务消息 + 异步处理。
问题 3:数据库如何扩容?
答:MySQL 主主复制 + 读写分离处理常规流量。当单库容量达到瓶颈时,使用 ShardingSphere 按客户维度分库分表(如按 customer_id % 16 分 16 个库)。
问题 4:风控引擎如何热更新规则?
答:使用 Drools 的 KieScanner 自动监听规则文件变化,无需重启服务。规则文件存储在 Nacos 配置中心,修改后自动推送生效。
@Configuration
public class DroolsConfig {
@Bean
public KieContainer kieContainer() {
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem();
// 从 Nacos 读取规则文件
String rules = nacosConfigService.getConfig("risk-rules.drl", "RISK_GROUP", 5000);
kfs.write("src/main/resources/rules/risk-rules.drl", rules);
ks.newKieBuilder(kfs).buildAll();
KieContainer container = ks.newKieContainer(
ks.getRepository().getDefaultReleaseId());
// 自动扫描更新
KieScanner scanner = ks.newKieScanner(container);
scanner.start(10000L); // 每 10 秒检查一次
return container;
}
}
问题 5:系统如何保证 99.99% 的可用性?
答:
- 同城双机房 + 异地灾备,任意单机房故障不影响业务
- 核心服务最小 3 副本部署(每个机房至少 1 个)
- 自动故障转移(Nacos 心跳检测 + 自动摘除)
- 限流熔断保护雪崩
- 完善的监控告警体系
- 定期容灾演练(每季度一次)
总结
担保核心系统架构设计的核心要点:
- 业务流程驱动架构:先理解业务全生命周期,再设计服务边界
- 分层解耦:网关层 → 业务服务层 → 领域支撑层 → 基础设施层,层层解耦
- 分布式事务分场景选型:资金类用 TCC/Seata,流程类用 RocketMQ 事务消息,数据同步用本地消息表
- 高可用三层防护:同城双活 + 异地灾备 + 限流熔断
- 风控独立为引擎:规则引擎热更新,不耦合业务代码
架构的本质是取舍。好的架构师不是把所有"最好"的技术堆在一起,而是在约束条件下做出最合适的决策。
参考资料
- Alibaba, 《企业级互联网架构白皮书》
- 凤凰架构, 《构建可靠的大型分布式系统》
- Seata 官方文档
- Spring Cloud Alibaba 官方文档