建springboot工程
主要引入springweb 及rabbitmq。
pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
yml
server:
port: 8074
spring:
rabbitmq:
username: admin
password: admin
port: 5672
host: localhost
config
- 增加交换机。
- 增加队列。
- 绑定队列到交换机。
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description TODO
* @Author chanyu
* @Date 2022/5/27 16:57
* @Version 1.0
**/
@Configuration
public class RabbitConfiguration {
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("fanout_order_exchange",true,false);
}
@Bean
public Queue smsQueue(){
Queue queue = new Queue("smsQueue",true);
return queue;
}
@Bean
public Queue emailQueue(){
Queue queue = new Queue("emailQueue",true);
return queue;
}
@Bean
public Binding smsBinding(){
return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
}
@Bean
public Binding reduceBinding(){
return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
}
}
模拟业务处理
假设订单服务,增加一个订单后发送消息。发送消息本身与订单业务不需要强一致性,通过队列来处理。
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.UUID;
/**
* @Description TODO
* @Author chanyu
* @Date 2022/5/27 16:52
* @Version 1.0
**/
@Slf4j
@Service
public class OrderService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void order(String userId , String goodsId , int num , String unit){
// 订单写入
String orderId = UUID.randomUUID().toString();
String msg = "创建订单"+orderId+",用户"+userId+"购买"+num+unit+"商品"+"goodsId";
log.info("创建订单{},用户{}购买{}{}商品{}",orderId,userId,num,unit,goodsId);
// 扣减库存
String exchangeName = "fanout_order_exchange";
String routingKey = "";
// 发布消息
rabbitTemplate.convertAndSend(exchangeName,routingKey,msg);
}
}
消费端消费
消费端与生产端工程是同样的建法,消费端监听队列处理消息。
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @Description TODO
* @Author chanyu
* @Date 2022/5/27 17:34
* @Version 1.0
**/
@Slf4j
@RabbitListener(queues = {"emailQueue"})
@Service
public class EmailService {
@RabbitHandler
public void handlerMsg(String msg){
log.info(msg);
}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @Description TODO
* @Author chanyu
* @Date 2022/5/27 17:34
* @Version 1.0
**/
@Slf4j
@RabbitListener(queues = {"smsQueue"})
@Service
public class SmsService {
@RabbitHandler
public void handlerMsg(String msg){
log.info(msg);
}
}
测试
在生产端进行单元测试。
import com.cy.rabbitmqproducer.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.TimeUnit;
@SpringBootTest
class RabbitmqProducerApplicationTests {
@Autowired
private OrderService orderService;
@Test
void contextLoads() throws InterruptedException {
orderService.order("1","1",3,"件");
TimeUnit.SECONDS.sleep(1);
orderService.order("1","2",1,"个");
TimeUnit.SECONDS.sleep(1);
orderService.order("1","3",2,"条");
TimeUnit.SECONDS.sleep(1);
orderService.order("1","4",1,"件");
TimeUnit.SECONDS.sleep(1);
}
}