Rabbitmq-springboot集成

1、添加依赖

springboot版本

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>

需要的依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

 

2、生产端配置

application.yml

server:
  port: 8080

spring:
  rabbitmq:
    host: 118.89.196.99 #服务地址
    port: 5672 #端口
    username: suzhe #用户名
    password: suzhe #密码
    virtual-host: /hello #虚拟主机
    publisher-confirms: true #如果要进行消息回调,则这里必须要设置为true
    publisher-returns: true  #开启publisher Return机制
    template:
      mandatory: true #开启mandatory

通过RabbitAdmin 提供的api 来初始化交换机队列并绑定。这里通过实现InitializingBean接口 ,在该类初始化后会执行afterPropertiesSet()这个方法。

下面主要声明了一个交换机order.topic,并声明了队列point.queue和cash.queue绑定到该交换机。其中point.queue设置了死信交换机的参数,同时也可以给队列设置过期时间,这里注释掉了。

@Configuration
public class RabbitmqConfig implements InitializingBean {

    @Autowired
    RabbitAdmin rabbitAdmin;

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }
    @Override
    public void afterPropertiesSet() throws Exception {

        //声明一个死信交换机和一个队列 并绑定
        rabbitAdmin.declareExchange(new TopicExchange("dlx.topic", true, false));
        rabbitAdmin.declareQueue(new Queue("dlx.point.queue", true, false, false));
        rabbitAdmin.declareBinding(new Binding("dlx.point.queue",
                Binding.DestinationType.QUEUE,
                "dlx.topic", "order.success", new HashMap<>()));
        //声明一个交换机
        rabbitAdmin.declareExchange(new TopicExchange("order.topic", true, false));
        //声明一个point队列
        Map<String, Object> pointArgs = new HashMap<>();
        //pointArgs.put("x-message-ttl" , 30000);//可以设置队列里消息的ttl的时间30s
        //设置死信交换机 并指定 routing_key 为order.success
        pointArgs.put( "x-dead-letter-exchange","dlx.topic");
        pointArgs.put( "x-dead-letter-routing-key","order.success");
        rabbitAdmin.declareQueue(new Queue("point.queue", true, false, false, pointArgs));
        //绑定point
        rabbitAdmin.declareBinding(new Binding("point.queue",
                Binding.DestinationType.QUEUE,
                "order.topic", "order.success", new HashMap<>()));
        //声明cash队列
        rabbitAdmin.declareQueue(new Queue("cash.queue", true, false, false));
        //绑定cash
        rabbitAdmin.declareBinding(new Binding("cash.queue",
                Binding.DestinationType.QUEUE,
                "order.topic", "order.success", new HashMap<>()));
    }
}

封装一个发送者对象

主要是RabbitTemplate 提供的api,这里发送对象时注入了两个回调。

@Component
@Slf4j
public class RabbitSender {

	//自动注入RabbitTemplate模板类
	@Autowired
	private RabbitTemplate rabbitTemplate;  
	
	//回调函数: confirm确认
	final ConfirmCallback confirmCallback = new ConfirmCallback() {
		@Override
		public void confirm(CorrelationData correlationData, boolean ack, String cause) {
			log.info("ack:{},CorrelationData:{}",ack,correlationData);
			if(!ack){
				log.error("异常处理");
			}
		}
	};
	
	//回调函数: return返回
	final ReturnCallback returnCallback = new ReturnCallback() {
		@Override
		public void returnedMessage(org.springframework.amqp.core.Message message, int replyCode, String replyText,
				String exchange, String routingKey) {
			log.info("return exchange:{},routingKey:{},replyCode:{},replyText:{}",exchange,routingKey,replyCode,replyText);
		}
	};


	//发送消息方法调用: 构建Message消息
	public void send(String exchange,String routingKey,String msg) {
		rabbitTemplate.setConfirmCallback(confirmCallback);
		rabbitTemplate.setReturnCallback(returnCallback);
		rabbitTemplate.convertAndSend(exchange, routingKey, msg);
	}
	
}

测试Controller

@RestController
public class OrderController {
    @Autowired
    RabbitSender rabbitSender;

    @GetMapping("/order")
    public ResponseEntity order(){
        String orderId = UUID.randomUUID().toString();
        rabbitSender.send("order.topic","order.success",orderId);
        return ResponseEntity.ok("success");
    }

}

启动springboot应用程序 可以看到对应的交换机和队列创建成功

ad8ee6d1aae4b217dd357feb0afa3ca8232.jpg

点击可以查看到对应交换机的绑定信息

f5a84786b091d5ed4ec96b923594e3e8148.jpg

同时也可以查看到队列也创建成功了,查看一下point.queue这个队列的参数。

19993a57d70e17b3cece65d3b040dc3f48d.jpg

 

3、消费端配置

这里开启消费端的重试机制,当消费端超过5次还没有消费成功,则做出作出nack或reject等行为. 这时候消息将进入死信队列,需要注意的是这里配置的重发是在消费端应用内处理的,不是rabbitmq重发。

spring:
  rabbitmq:
    host: 192.168.6.133 #服务地址
    username: suzhe #用户名
    password: suzhe #密码
    virtual-host: /hello #虚拟主机
    connection-timeout: 5000ms #连接超时参数单位为毫秒:设置为“0”代表无穷大
    listener:
      simple:
        retry:
          enabled: true #是否开启消费者重试(为false时关闭消费者重试,这时消费端代码异常会一直重复收到消息)
          max-attempts: 5 #默认是3

监听队列

SpringBoot Rabbit使用手工应答机制, 当@RabbitListener修饰的方法被调用且没有抛出异常时, Spring Boot会为我们自动应答. 否则会根据设定的重试机制而作出nack或reject等行为.  point.queue这个队列的监听会抛出异常。

@Component
@Slf4j
public class Listener {
    @RabbitListener(queues="point.queue")
    public void point(String msg){
        log.info("point.queue 接收到消息:{}",msg);
        int i = 1/0;

    }
    @RabbitListener(queues="cash.queue")
    public void cash(String msg){
        log.info("cash.queue 接收到消息:{}",msg);
    }
}

启动消费者
生产者访问:http://localhost:8080/order  这里会发送消息到order.topic。

可以看到point.queue收到了5次消息,然后抛出了异常

968fe407171fa731c23dd98372bdb2ff36a.jpg

查看死信队列

d902980e73e70468e7e7d6fe39faa9301f1.jpg

获取消息,可以看到该条消息的信息。

d972678d2d8a34564a53cd3c76411040649.jpg

 

详细源码地址:

https://github.com/suzhe2018/rabbitmq-item

 

b343eda16faea01bc727de7c76a560b4b4e.jpg

转载于:https://my.oschina.net/suzheworld/blog/3004357

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值