Introduction
RabbitMq and ElaticSearch are two frequently used technology in web programming. RabbitMq is an open-source advanced message broker that is extremely helpful in dealing with high concurrency situations like seckill and large-scale web projects. ElasticSearch, on the other hand, is a database dedicated to dealing with text searches. Have you ever used search engines like Google and Baidu and wondered why they could separate your search into words? ElasticSearh uses the same logic as other web search engines. Therefore, this short tutorial will teach you how to handle the ElasticSearch database and RabbitMq using Java properly.
Requirement
The first step of using RabbitMq and the ElasticSearch database is configuring their dependencies. You can insert these two sentences into your SpringBoot properties file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
Then the second step is to understand how RabbitMq work. RabbitMq acts like a broker that can store messages between consumers and producers. There are four types of exchangers that operate in RabbitMq. DirectExchange receives one message from producers and sends it to consumers without checking in or checking out. Moreover, there are ConfirmCallback mechanisms and Acknowledgement Mechanisms that ensure Mq receives and delivers messages successfully.
private RabbitTemplate.ConfirmCallback confirmCallback = ((correlationData, b, s) ->
{
if(b){
TicketBean ticketBean = ticketDao.findDistinctByTicketNumber(correlationData.getId());
ticketBean.setTag(1);
ticketDao.save(ticketBean);
System.out.println("验证成功!");
}
}
//callback mechanism example
Besides using different mechanisms to ensure Mq's proper function, Mq also uses different queue types to link each queue to an exchanger. For instance, DirectExchange applies a specific key while fanout-exchanger uses regex keys. Furthermore, there is a special exchanger called 'D eadMessageExchaner‘. This unique exchanger is used to store messages that are not be taken by any consumers in a limited time.
@Bean
public DirectExchange ticketExchange(){
return new DirectExchange("ticketExchange");
}
@Bean
public DirectExchange deadDirectExchange(){
return new DirectExchange("deadDirectExchange");
}
@Bean
public Queue deadQueue(){
return new Queue("deadQueue");
}
@Bean
public Queue ticketQueue(){
//关联死信交换机
Map<String, Object> args = new HashMap<>(3);
// x-dead-letter-exchange 这里声明当前队列绑定的死信交换机
args.put("x-dead-letter-exchange", "deadDirectExchange");
// x-dead-letter-routing-key 这里声明当前队列的死信路由key
args.put("x-dead-letter-routing-key","dead.order");
// x-message-ttl 声明队列的TTL
args.put("x-message-ttl",5000);
return QueueBuilder.durable("ticketQueue").withArguments(args).build();
}
@Bean
public Binding deadQueueToDirectExchangeDead(Queue deadQueue, DirectExchange deadDirectExchange){
return BindingBuilder.bind(deadQueue).to(deadDirectExchange).with("dead.order");
}
@Bean
public Binding ticketOrderToTicketExchange(Queue ticketQueue,DirectExchange ticketExchange){
return BindingBuilder.bind(ticketQueue).to(ticketExchange).with("ticket.order");
}
Finally, we need to integrate our RabbitMq configuration with our SpringBoot project. The setup is comparatively simple. We can directly use the rabbitTempate as a tool to figure out the majority of the situation.
public String confirmTicket(TicketDto ticketDto) throws JsonProcessingException, InterruptedException {
ticketDto.setTicketNumber(SnowIdUtil.uniqueLongHex());
TicketBean ticketBean = new TicketBean();
BeanUtils.copyProperties(ticketDto,ticketBean);
ticketDao.save(ticketBean);
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(confirmCallback);
CorrelationData correlationData = new CorrelationData(ticketDto.getTicketNumber());
JsonMapper mapper = new JsonMapper();
String js = mapper.writeValueAsString(ticketDto);
rabbitTemplate.convertAndSend("ticketExchange","ticket.order",js,correlationData);
Thread.sleep(2000);
return ticketBean.getTicketNumber();
}
As for the ElasticSearch engine, I will put all the detailed information in the next tutorial.