通过RabbitMq消息队列实现ES与数据库数据的同步

由于公司业务需要用到es技术,所以就需要考虑到es与数据库的同步问题,下面为记录此次操作,方便后期查看使用,话不多说,干中学,此次业务步骤主要为:

1)数据库数据发生变化的时候,将对应业务数据发送到创建好的业务队列中。

2)队列接收到数据再根据业务对es进行操作。

1、创建交换机、队列、键所用到的静态常量

因为这些数据需要经常使用,防止写错,最好用静态常量写到一个类中,后期方便调佣,此次演示业务包括数据的新增删除操作数据的同步,如下代码所示:

public class MqConstant {
    //交换机
    public static final String EXCHANGE_NAME = "sys_user_topic";

    //新增 编辑队列
    public static final String INSERT_QUEUE_NAME = "sys_user_insert_queue";

    //删除队列
    public static final String DELETE_QUEUE_NAME = "sys_user_delete_queue";

    //新增 编辑队列绑定的key
    public static final String INSERT_KEY_NAME = "sys_user_insert_key";

    //删除队列绑定的key
    public static final String DELETE_KEY_NAME = "sys_user_delete_key";
}

2、创建MQ针对业务对交换机。队列。key进行相关绑定(此步骤也可通过注解实现),代码如下所示:

/**
 * MQ配置类
 */
@Configuration
public class MqConfig {

    //交换机
    @Bean
    public TopicExchange exchange() {
        return new TopicExchange(MqConstant.EXCHANGE_NAME);
    }

    //新增队列
    @Bean
    public Queue insertQueue() {
        return new Queue(MqConstant.INSERT_QUEUE_NAME);
    }

    //删除队列
    @Bean
    public Queue deleteQueue() {
        return new Queue(MqConstant.DELETE_QUEUE_NAME);
    }

    //新增队列键绑定
    @Bean
    public Binding insertBinding() {
        return         BindingBuilder.bind(insertQueue()).to(exchange()).with(MqConstant.INSERT_KEY_NAME);
    }

    //删除队列键绑定
    @Bean
    public Binding deleteBinding() {
        return BindingBuilder.bind(deleteQueue()).to(exchange()).with(MqConstant.DELETE_KEY_NAME);
    }
}

3、创建队列的接收类,根据不同业务对es进行操作,代码如下所示:

import org.example.es_demo.constants.SysUserDoc;
import org.example.es_demo.domain.SysUser;
import org.example.es_demo.service.SysUserService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * mq消息接收类,并针对不同业务对es进行相关操作
 */
@Component
public class MqListener {

    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private  SysUserService sysUserService;

    /**
     * mq新增业务处理
     * @param userId
     * @throws IOException
     */
    @RabbitListener(queues = MqConstant.INSERT_QUEUE_NAME)
    public void insertListener(Long userId) throws IOException {
        SysUser sysUser = sysUserService.getById(userId);
        SysUserDoc sysUserDoc = new SysUserDoc(sysUser);
        //1、准备Request对象
        IndexRequest request = new IndexRequest("sys_user").id(sysUser.getUserId().toString());
        //2、 准备JSon文档
        request.source(JSON.toJSONString(sysUserDoc), XContentType.JSON);
        //3、发送请求
        restHighLevelClient.index(request, RequestOptions.DEFAULT);
    }

    /**
     * mq删除业务处理
     * @param userId
     * @throws IOException
     */
    @RabbitListener(queues = MqConstant.DELETE_QUEUE_NAME)
    public void deleteListener(Long userId) throws IOException {
        //1、准备Request对象
        DeleteRequest request = new DeleteRequest("sys_user", String.valueOf(userId));
        //2、发送请求
        restHighLevelClient.delete(request, RequestOptions.DEFAULT);
    }
}

注:连初始化es,在springboot项目使用es 需要对其进行初始化,建立连接关系,可在启动类增加Bean注解进行初始化:

@Bean
public RestHighLevelClient restHighLevelClient() {
    return new RestHighLevelClient(RestClient.builder(
            new HttpHost("localhost", 9200, "http")));
}

连接mq队列,需在yml文件进行配置:

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /

4、以上四步是接收mq数据并进行操作,下面就是数据库发生操作的时候,我们对mq队列进行数据插入,代码如下所示:

@RestController
@RequestMapping("/sys_user")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 插入数据
    @PostMapping("/insert")
    public void insert(@RequestBody SysUser sysUser) {
        sysUserService.save(sysUser);
//向队列中发送数据
        rabbitTemplate.convertAndSend(MqConstant.EXCHANGE_NAME, MqConstant.INSERT_KEY_NAME, sysUser.getUserId());
    }

    // 删除数据
    @RequestMapping("/delete")
    public void delete(@RequestBody SysUser sysUser) {
        sysUserService.removeById(sysUser.getUserId());
//向队列中发送数据
        rabbitTemplate.convertAndSend(MqConstant.EXCHANGE_NAME, MqConstant.DELETE_KEY_NAME, sysUser.getUserId());
    }
}

以上就完成了当数据库发生变化的时候,同步es中的相关数据业务,默认已经安装了mq以及es。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值