同步字段变更的方案

多个系统之间需要同步数据,比如A系统需要B系统的商品数据,每次变更和新增都要同步到A系统中。

同步方案

主动推送

B系统新增和更新变化时,直接调用A系统中接口进行新增或更新,同步需要最后更新时间或者是版本号

B系统的伪代码
public void addOrUpdate(){
    // 保存或更新到本地数据库中
    addOrUpdate();
    // 通知到A系统
    notifyA();
}

public void notifyA(){
    // 调用A系统的接口
    resttemplate.syncData();
}


A系统的伪代码
@Post("syncData")
public void syncData(){
    // 同步数据
}

上述方法通过直接调用接口的方式,这种方式耦合性很高,并且A系统挂了或其他错误都会导致B系统的保存和更新不正确,也影响到了B系统接口的响应速度。如果为了不影响B系统可以优化为调用接口以线程执行的方式来完成。

主动拉取

A系统以定时任务主动拉取最新的更新数据

A系统的伪代码

// 定时任务
@Scheduled(cron = "0 1 * * * *")
public void handlerScheduled(){
    // 查询本地数据的最后更新时间
    Date lastTime =  queryLastData(); 
    // 调用系统B接口获取数据
    restTemplate.queryLastTimeData(lastTime);
    // 保存或更新到本地数据库中
    addOrUpdate();
}

public void addOrUpdate(){
   // 保存或更新到本地数据库中 
}

// B系统的伪代码
// B系统的数据更新和保存,都更新lastTime
@Post("queryLastTimeData")
public void queryLastTimeData(Date lastTime){
    // 查询最新时间的数据
    if(lastTime == null) {
        // 拉取全部数据
    } else {
        // 拉取 大于等于 lastTime的数据
    }
}

上述方法B系统的变更不需要通知到A系统,A系统主动查询,控制查询频次。

以中间件的方式通知

B系统新增和更新变化时,通知以中间件的方式来完成,不在直接以接口的调用方式为主。下面是已rocketmq中间件的方式。

B系统的伪代码
public void addOrUpdate(){
    // 保存或更新到本地数据库中
    addOrUpdate();
    // 通知到A系统
    notifyA(data);
}

public void notifyA(data){
    // 将变更通知到rocketmq中
    rocketmq.send(topic, data)
}


A系统的伪代码
// 消费topic
public void syncData(){
    // 同步数据
}

使用canal工具同步

利用binlog日志记录了update,insert,delete的数据的方式,读取binlog,获取更新数据,发送到rocketmq中,A系统消费。开源工具alibaba的canal工具。利用mysql主从备份的机制,canal会发送消息到mysql,我是slave,同步数据,mysql会将binlog发送到canal中
image.png

四种方案优缺点

1方案主动推送耦合性很高,如果使用了线程来通知,此时就无法保证两个系统的数据一致性
2方案定时任务主动查询,实时性依赖于定时任务的查询的频次,频次太高,影响了A和B系统的性能。
3方案是弥补了方案1的缺点,但是需要引入中间件
4方案有大量的数据需要同步,并且不影响各个系统的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值