合同管理系统灾备方案:从数据备份到异地多活的实践
时间:2025-04-23 人气:

一、灾备等级设计

基于合同业务特性的容灾标准制定:

1.1 容灾指标矩阵

灾备等级RPORTO技术实现合同场景适用
冷备份24小时12小时磁带备份历史合同归档
热备份15分钟1小时主从复制非核心业务
双活架构秒级5分钟数据同步签署服务
异地多活030秒单元化部署核心签署流程

1.2 合同业务容灾等级

容灾等级图

  1. L0核心业务:签署服务(多活)、支付服务(双活)

  2. L1重要业务:审批服务(热备)、模板服务(热备)

  3. L2普通业务:日志服务(冷备)、报表服务(冷备)

二、数据备份方案

合同数据的全生命周期备份策略:

2.1 备份策略矩阵

备份类型技术实现存储周期恢复测试
全量备份XtraBackup1年季度演练
增量备份Binlog同步7天月度演练
差异备份LVM快照30天季度演练
归档备份S3 Glacier10年年度演练

2.2 MySQL数据备份

自动化备份脚本:

#!/bin/bash
# 全量备份脚本
BACKUP_DIR="/backups/mysql/full"
DATE=$(date +%Y%m%d)
LOG_FILE="/var/log/backup_${DATE}.log"

# 执行全量备份
innobackupex --user=backup --password=$PASSWD \
    --stream=xbstream $BACKUP_DIR | \
    gzip > $BACKUP_DIR/full_${DATE}.xbstream.gz 2>>$LOG_FILE

# 备份校验
if [ $? -eq 0 ]; then
    aws s3 cp $BACKUP_DIR/full_${DATE}.xbstream.gz \
        s3://contract-backup/mysql/ --sse AES256
    find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
else
    mailx -s "MySQL备份失败" ops@example.com < $LOG_FILE
fi

# Binlog增量备份(每小时)
#!/bin/bash
LAST_BINLOG=$(mysql -ubackup -p$PASSWD -e "SHOW MASTER STATUS" | awk 'NR==2{print $1}')
POSITION=$(mysql -ubackup -p$PASSWD -e "SHOW MASTER STATUS" | awk 'NR==2{print $2}')

rsync -avz /var/lib/mysql/$LAST_BINLOG \
    backup@remote:/backups/binlog/ --password-file=/etc/rsync.passwd

# 写入备份元数据
echo "${DATE} ${LAST_BINLOG} ${POSITION}" >> /backups/binlog/index.txt

数据恢复流程:

  1. 1. 准备阶段:申请恢复资源,停止相关服务

  2. 2. 全量恢复:innobackupex --apply-log /backups/full_20230101

  3. 3. 增量恢复:mysqlbinlog binlog.000123 | mysql -uroot

  4. 4. 验证阶段:数据校验,服务功能测试

  5. 5. 恢复上线:流量切换,监控观察

数据恢复流程图

三、异地多活架构

基于单元化部署的合同多活方案:

3.1 多活设计原则

设计原则技术实现合同场景用例挑战解决方案
业务隔离单元化部署按企业ID分片跨单元查询
数据同步DTS+MQ签署状态同步最终一致性
流量调度DNS+SLB故障自动切换会话保持
监控切换健康检查机房级容灾脑裂处理

3.2 多活架构实现

单元化部署方案:

# 单元路由规则(ShardingSphere配置)
spring:
  shardingsphere:
    sharding:
      tables:
        contract:
          actual-data-nodes: ds_$->{0..3}.contract_$->{0..15}
          database-strategy:
            complex:
              sharding-columns: enterprise_id,user_id
              algorithm-class-name: com.example.UnitRouteAlgorithm

# 单元路由算法
public class UnitRouteAlgorithm implements ComplexKeysShardingAlgorithm {
    @Override
    public CollectiondoSharding(Collectiontargets, 
        ComplexKeysShardingValue shardingValue) {
        
        // 按企业ID首字母分单元
        String enterpriseId = ((List)shardingValue.getColumnNameAndShardingValuesMap()
            .get("enterprise_id")).get(0);
        int unitNo = Math.abs(enterpriseId.charAt(0)) % 4;
        
        return targets.stream()
            .filter(e -> e.endsWith("_" + unitNo))
            .collect(Collectors.toList());
    }
}

# 跨单元数据同步(Canal配置)
canal.instance.filter.regex = .*\\..*_enterprise_(1001|1002).*

多活数据同步:

// 基于MQ的最终一致性
@Transactional
public void signContract(String contractId) {
    // 1. 本地事务
    contractDao.updateStatus(contractId, "SIGNED");
    
    // 2. 发送可靠消息
    transactionTemplate.execute(status -> {
        mqTemplate.send("contract-sign-topic", 
            new SignMessage(contractId, "SIGNED"));
        return null;
    });
}

// 消息消费者
@RocketMQMessageListener(topic = "contract-sign-topic", consumerGroup = "sign-sync")
public class SignSyncConsumer implements RocketMQListener{
    @Override
    public void onMessage(SignMessage message) {
        // 3. 同步到其他单元
        contractSyncService.syncStatus(
            message.getContractId(), 
            message.getStatus());
    }
}

// 冲突解决策略
public void syncStatus(String contractId, String status) {
    // 基于时间戳的最终一致性
    Contract local = contractDao.get(contractId);
    if (local.getUpdateTime().before(message.getUpdateTime())) {
        contractDao.updateStatus(contractId, status);
    }
}

四、容灾切换演练

基于混沌工程的故障模拟体系:

4.1 演练场景

故障类型模拟工具影响范围恢复策略
机房断网ChaosBlade单区域服务DNS切换+数据补偿
数据库宕机Kill -9核心业务主从切换+事务恢复
磁盘损坏dd if=/dev/zero持久化数据从备份恢复
网络分区iptables微服务通信熔断降级

4.2 混沌工程实施

演练计划示例:

# 月度演练计划
- 目标:验证签署服务多活切换能力
- 场景:模拟华东1区机房网络中断
- 步骤:
  1. 09:00 启动监控基线记录(正常指标)
  2. 09:30 执行故障注入(切断华东1区网络)
  3. 09:35 验证自动切换(流量路由到华东2区)
  4. 10:00 恢复故障注入
  5. 10:30 验证数据补偿机制
  6. 11:00 演练总结会议

# ChaosBlade命令示例
blade create network loss --percent 100 --interface eth0 --timeout 300

# 监控指标验证
- 签署成功率 ≥99.9%
- RTO ≤30秒
- 数据补偿延迟 ≤5秒
- 错误告警准确率 100%

自动化演练平台:

// 演练场景定义
{
  "scenario": "region-network-outage",
  "steps": [
    {
      "action": "inject",
      "target": "network",
      "params": {
        "region": "east-1",
        "duration": "5m"
      }
    },
    {
      "action": "verify",
      "metrics": [
        {
          "name": "sign_success_rate",
          "expected": ">=99.9%",
          "duration": "1m"
        }
      ]
    }
  ]
}

// 演练执行引擎
public class DrillEngine {
    public void execute(Scenario scenario) {
        scenario.getSteps().forEach(step -> {
            if ("inject".equals(step.getAction())) {
                chaosService.injectFault(step.getTarget(), step.getParams());
            }
            
            if ("verify".equals(step.getAction())) {
                monitoringService.verifyMetrics(step.getMetrics());
            }
        });
    }
}

五、灾备工具包

开箱即用的灾备建设资源集合:

5.1 推荐工具集

工具领域开源方案商业产品合同场景适用
数据备份XtraBackupVeeamMySQL热备
数据同步CanalAWS DMS异地多活
混沌工程ChaosBladeGremlin故障演练

5.2 开发资源包

▶ 免费获取资源:

关注「高可用架构」公众号领取:
               • 《灾备演练checklist》
               • 多活架构设计模板
               • 数据恢复操作手册

山西肇新科技logo

山西肇新科技

专注于提供合同管理领域,做最专业的合同管理解决方案。

备案号:晋ICP备2021020298号-1 晋公网安备 14010502051117号

请备注咨询合同系统