简单使用rabbitMq对ES和数据库完成数据同步

99 阅读2分钟
  1. 导入rabbitmq与es的依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
    </dependency>

2.修改配置文件 rabbitmq简单配置

rabbitmq:
  host: 192.168.115.131 # 主机名
  port: 5672 # 端口
  virtual-host: / # 虚拟主机
  username: itcast # 用户名
  password: 123321 # 密码

3.配置RestHighLevelClient的bean用于连接ES数据库完成请求的发送

@Configuration
public class RestHighLevelClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
           //该bean对象主要用于连接es数据库
        return new RestHighLevelClient(RestClient.builder(HttpHost.create(EsConstant.ES_IP)));
    }
}

4.创建一个类,声明队列交换机名称 package cn.itcast.hotel.constatnts;

public class MqConstants {
/**
 * 交换机
 */
public final static String HOTEL_EXCHANGE = "hotel.topic";
/**
 * 监听新增和修改的队列
 */
public final static String HOTEL_INSERT_QUEUE = "hotel.insert.queue";
/**
 * 监听删除的队列
 */
public final static String HOTEL_DELETE_QUEUE = "hotel.delete.queue";
/**
 * 新增或修改的RoutingKey
 */
public final static String HOTEL_INSERT_KEY = "hotel.insert";
/**
 * 删除的RoutingKey
 */
public final static String HOTEL_DELETE_KEY = "hotel.delete";

} 5.生产者发送mq消息(这里采用的topic类型)

@PostMapping
public void saveHotel(@RequestBody Hotel hotel) {
    hotelService.save(hotel);
    //生产者发送消息到rabbitmq,参数为交换机,路由key,消息内容
    rabbitTemplate.convertAndSend(mqConstant.HOTEL_EXCHANGE, mqConstant.HOTEL_INSERT_KEY, hotel.getId());
}

@PutMapping()
public void updateById(@RequestBody Hotel hotel) {
    if (hotel.getId() == null) {
        throw new InvalidParameterException("id不能为空");
    }
    hotelService.updateById(hotel);
    //新增文档和修改文档共用一套生产者与消费者,因为在新增文档操作时,传入的hotel有新的id时就是新增文档,有出现过的id就是修改文档
    rabbitTemplate.convertAndSend(mqConstant.HOTEL_EXCHANGE, mqConstant.HOTEL_INSERT_KEY, hotel.getId());
}

@DeleteMapping("/{id}")
public void deleteById(@PathVariable("id") Long id) {
    hotelService.removeById(id);
    rabbitTemplate.convertAndSend(mqConstant.HOTEL_EXCHANGE, mqConstant.HOTEL_DELETE_KEY, id);
}

6.消费者监听收到mq消息(这里采用的注解来绑定队列和交换机关系以及路由key)

@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = mqConstant.HOTEL_INSERT_QUEUE),
        exchange = @Exchange(name = mqConstant.HOTEL_EXCHANGE, type = ExchangeTypes.TOPIC),
        key = mqConstant.HOTEL_INSERT_KEY)})
public void saveHotelListener(Long id) {
    log.info("saveHotelListener成功监听到,参数为[{}]",id);
    iHotelService.saveById(id);
}

@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = mqConstant.HOTEL_DELETE_QUEUE),
        exchange = @Exchange(name = mqConstant.HOTEL_EXCHANGE, type = ExchangeTypes.TOPIC),
        key = mqConstant.HOTEL_DELETE_KEY)})
public void deleteHotelListener(Long id) {
    log.info("deleteHotelListener成功监听到,参数为[{}]",id);
    iHotelService.deleteById(id);
}

7.利用收到的消息数据来完成新增修改和删除文档

@Autowired
private RestHighLevelClient client;

@Override
public void saveById(Long id) {
    try {
        // 0.根据id查询酒店数据
        Hotel hotel = getById(id);
        // 转换为文档类型
        HotelDoc hotelDoc = new HotelDoc(hotel);

        // 1.准备Request对象  需要设置request的索引库名称,文档id,这里就用hotel的id(也就是数据id)来使用
        IndexRequest request = new IndexRequest(EsConstant.HOTEL_INDEX).id(hotel.getId().toString());
        // 2.准备Json文档。。。文档数据,json格式
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        // 3.发送请求
        client.index(request, RequestOptions.DEFAULT);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

@Override
public void deleteById(Long id) {
    try {
        // 1.准备Request
        DeleteRequest request = new DeleteRequest(EsConstant.HOTEL_INDEX, id.toString());
        // 2.发送请求
        client.delete(request, RequestOptions.DEFAULT);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}