RabbitMQ+SpringBoot学习记录

首先学习先得有环境搭建与部署

linux部署RabbitMQ请参考linux 安装RebbitMQ3.86_yuell102的博客-CSDN博客

开发工具用的是idea 

java是jdk11

pom.xml中必须包含 

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

application.yml 配置rabbitmq服务器的参数

spring:
  application:
    name: rabbitmq-spring
  rabbitmq:
    host: xxxx
    port: xxxx
    username: xxx
    password: xxx
    virtual-host: /

第一种模型 

创建消费者

@Component
@RabbitListener(queuesToDeclare = @Queue("hello"),
 declare = "true",
 autoDelete = "false")//@RabbitListener消费队列 @Queue 队列名称  declare 是否持久化 autoDelete 是否自动删除 
public class HelloCustomer {
    
    @RabbitHandler//处理消息的回调方法
    public void receivel(String msg){
        System.out.println(msg);
    }
}

创建生产者

@SpringBootTest(classes = RabbitmqApplication.class)
class RabbitmqApplicationTests {
    
    @Autowired//spring对类成员变量、方法及构造函数进行标注,完成自动装配的工作
    private RabbitTemplate rabbitTemplate;//springboot为我们封装的rabbitmq

    @Test
    public void test() {
        rabbitTemplate.convertAndSend("hello", "你好");//发布消息
        //routingKey  hello  
        //hello 为队列名称
        //object 你好
        //你好   具体消息    
    }

}

convertSendAndReceive(…):可以同步消费者。使用此方法,当确认了所有的消费者都接收成功之后,才触发另一个convertSendAndReceive(…),也就是才会接收下一条消息。RPC调用方式。

convertAndSend(…):使用此方法,交换机会马上把所有的信息都交给所有的消费者,消费者再自行处理,不会因为消费者处理慢而阻塞线程。

这里要注意,一定要先启动消费者

没有消费者不会构建Queues

运行完后

已经构建出了 hello  Queues

并且已经被消费

第二种模型

生产者

@SpringBootTest(classes = RabbitmqApplication.class)
class RabbitmqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void work() {
        for (int i = 0; i < 10; i++) {
            rabbitTemplate.convertAndSend("work", "我是work生成者"+i);
        }
    }
//    @Test
//    public void test() {
//        rabbitTemplate.convertAndSend("hello", "你好");
//    }
}

 消费者

@Component
public class WorkCustomer {

    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void work1(String msg){
        System.out.println("消费者work1" + msg);
    }

    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void work2(String msg) throws InterruptedException {
        Thread.sleep(2000);
        System.out.println("消费者work2" + msg);
    }
}

 一个生产者 对多个消费者运行结果

第三种模型 

发布者

@SpringBootTest(classes = RabbitmqApplication.class)
class RabbitmqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void fanot(){
        rabbitTemplate.convertAndSend("logs", "", "fanot模型发送的消息");
    }

//    @Test
//    public void work() {
//        for (int i = 0; i < 10; i++) {
//            rabbitTemplate.convertAndSend("work", "我是work生成者"+i);
//        }
//    }
//    @Test
//    public void test() {
//        rabbitTemplate.convertAndSend("hello", "你好");
//    }
}

订阅者

@Component
public class FanoutCustomer {

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "logs", type = "fanout")
            )
    })
    public void fanout1(String msg){
        System.out.println("msg1 = " + msg);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "logs", type = "fanout")
            )
    })
    public void fanout2(String msg){
        System.out.println("msg2 = " + msg);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "logs", type = "fanout")
            )
    })
    public void fanout3(String msg){
        System.out.println("msg3 = " + msg);
    }
}

 运行结果

与前两者的模式相比,此模式是临时队列,主要交换机处理,同一个消息订阅者都能接收到 

第四种模式 

根据路由key订阅消息 

生产者

@SpringBootTest(classes = RabbitmqApplication.class)
class RabbitmqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void direct(){
        rabbitTemplate.convertAndSend("directs", "info", "发送的是info路由消息");
    }

}

 消费者

@Component
public class RouteCustomer {

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "directs", type = "direct"),
                    key = {"info"}
            )
    })
    public void directs1(String msg){
        System.out.println("directs1" + msg);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "directs", type = "direct"),
                    key = {"info","error"}
            )
    })
    public void directs2(String msg){
        System.out.println("directs2" + msg);
    }
}

运行结果

 修改消费者后

@SpringBootTest(classes = RabbitmqApplication.class)
class RabbitmqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void direct(){
        rabbitTemplate.convertAndSend("directs", "error", "发送的是info路由消息");
    }

}

运行结果

第五种模式 

生产者

@SpringBootTest(classes = RabbitmqApplication.class)
class RabbitmqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void topic(){
        rabbitTemplate.convertAndSend("topics", "user.save", "user.save的路由消息");
    }

}

消费者

@Component
public class RouteCustomer {
    //# 代表一个或者多个
    //* 代表一个
    //每个可以以.分割
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(type = "topic", name = "topics"),
                    key = {"user.save", "user.*"}
            )
    })
    public void topics1(String msg){
        System.out.println("topics1" + msg);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(type = "topic", name = "topics"),
                    key = {"#.save", "user.#", "user.insert"}
            )
    })
    public void topics2(String msg){
        System.out.println("topics2" + msg);
    }
}

运行结果

修改生产者后

@SpringBootTest(classes = RabbitmqApplication.class)
class RabbitmqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void topic(){
        rabbitTemplate.convertAndSend("topics", "save", "user.save的路由消息");
    }

}

 运行结果

手动配置yml

spring:
  rabbitmq:
    host: 192.168.0.48
    port: 5672
    username: admin
    password: 123456
    listener:
      type: simple
      simple:
        acknowledge-mode: auto 
     #   acknowledge-mode: manual  #手动
     #   default-requeue-rejected: true  #异常或者拒绝重新回到队列
        retry:                                
     #     max-attempts: 5       #重发次数
          enabled: true         #允许重发
          max-interval: 10000   #重试最大间隔时间
          initial-interval: 2000  #重试初始间隔时间
          multiplier: 2  #间隔时间乘子,间隔时间*乘子=下一次的间隔时间,最大不能超过设置的最大间隔时间

消息确认

  @RabbitListener(queues = "${customs.declare.send_queue}")
    @RabbitHandler
    public void sendProcess(@Payload String message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws IOException {
        //消息为null  过滤掉
        if (StringUtils.isEmpty(message)) return;

        //获取数据
        JSONObject json = JSONObject.parseObject(message);

        //获取key
        String key = json.keySet().iterator().next();

        //获取文本内容
        String msg = json.get(key).toString();

        //添加后缀名
        String fileName = key + XML;

        log.info("开始向tosend文件夹写入文件:{}", fileName);
        //创建FTP并建立连接
        FtpUtil ftpCli = FtpUtil.createFtpCli(hostname, port, username, password, "UTF-8");
        ftpCli.connect();

        if (StringUtils.isNotEmpty(ftpCli)
                && ftpCli.upload(tosend, fileName, msg)) {
            log.info("tosend文件:{} 写入完成", fileName);
            //消息确认
            channel.basicAck(deliveryTag,false);
        } else {
            log.error("tosend文件:{} 写入失败", fileName);
        }
        log.info("结束向tosend文件夹写入:{}", fileName);
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值