RabbitMQ的简单使用与应用(发送邮件)

Spring boot集成RabbitMQ的简单使用与应用(发送邮件)

总的来说:就是你生产一个消息发送给交换机,交换机按照规则(配置类)消费消息。

1.简单使用

1.1 Direct模式

  • 配置类
@Configuration
public class DirectConfig {

    //配置消息队列
    @Bean
    Queue directQueue(){
        return new Queue("fanle-queue");
    }

    //如果使用的是direct模式,则下面两个bean可以省略

    //配置交换机
    @Bean
    DirectExchange directExchange(){
        //参数1:交换机的名称  参数2:队列重启后是否删除  参数3:队列长期不用是否自动删除
        return new DirectExchange("fanle-direct",true,false);
    }


    //将消息队列和交换机绑定
    @Bean
    Binding directBinding(){
        return BindingBuilder.bind(directQueue()).to(directExchange()).with("direct");
    }
    
}
  • 消费者
@Component
public class DirectReceiver {

    //监听消息队列
    @RabbitListener(queues = "fanle-queue")
    public void directHandler(String msg){
        System.out.println("msg = " + msg);
    }
}
  • 生产者
public void direct() {
    //- 点对点,直接发送到队列上,不需要交换机参与
    rabbitTemplate.convertAndSend("fanle-queue","hello fanle");
}

1.2 Fanout模式

  • 配置类
@Configuration
public class FanoutConfig {

    @Bean
    Queue queueOne(){
        return new Queue("queue-one");
    }

    @Bean
    Queue queueTwo(){
        return new Queue("queue-two");
    }

    //- fanout的交换机
    @Bean
    FanoutExchange fanoutExchange(){
        return new FanoutExchange("fanle-fanout",true,false);
    }

    //- 将两个队列分别与交换机绑定
    @Bean
    Binding bindingOne(){
        return BindingBuilder.bind(queueOne()).to(fanoutExchange());
    }

    @Bean
    Binding bindingTwo(){
        return BindingBuilder.bind(queueTwo()).to(fanoutExchange());
    }
}
  • 消费者
@Component
public class FanoutReceiver {

    @RabbitListener(queues = "queue-one")
    public void handlerOne(String msg){
        System.out.println("handlerOne----" + msg);
    }

    @RabbitListener(queues = "queue-two")
    public void handlerTwo(String msg){
        System.out.println("handlerTwo---" + msg);
    }
}
  • 生产者
public void fanout(){
    //- fanout模式相当于广播,所以消息只需要发送到交换机上,两个消息队列都能收到
    rabbitTemplate.convertAndSend("fanle-fanout",null,"hello fanout");
}

1.3 Topic模式

  • 配置类
@Configuration
public class TopicConfig {

    @Bean
    Queue xiaomi(){
        return new Queue("xiaomi");
    }

    @Bean
    Queue huawei(){
        return new Queue("huawei");
    }

    @Bean
    Queue phone(){
        return new Queue("phone");
    }

    @Bean
    TopicExchange topicExchange(){
        return new TopicExchange("fanle-topic",true,false);
    }

    @Bean
    Binding xiaomiBinding(){
        //- 将标签(routingKey)为 xiaomi.XXX的消息发送到xiaomi队列
        return BindingBuilder.bind(xiaomi()).to(topicExchange()).with("xiaomi.#");
    }

    @Bean
    Binding huaweiBinding(){
        //- 将标签(routingKey)为 huawei.XXX的消息发送到huawei队列
        return BindingBuilder.bind(huawei()).to(topicExchange()).with("huawei.#");
    }

    @Bean
    Binding phoneBinding(){
        //- 将标签(routingKey)为 XXX.phone.XXX的消息发送到phone队列
        return BindingBuilder.bind(phone()).to(topicExchange()).with("#.phone.#");
    }


}
  • 消费者
@Component
public class TopicReceiver {

    @RabbitListener(queues = "xiaomi")
    public void xiaomi(String msg){
        System.out.println("xiaomi------" + msg);
    }

    @RabbitListener(queues = "huawei")
    public void huawei(String msg){
        System.out.println("huawei-------" + msg);
    }

    @RabbitListener(queues = "phone")
    public void phone(String msg){
        System.out.println("phone-------" + msg);
    }
}
  • 生产者
public void topic(){
        rabbitTemplate.convertAndSend("fanle-topic","xiaomi.news","小米手机才能收到的小米新闻");
        rabbitTemplate.convertAndSend("fanle-topic","huawei.news","华为手机才能收到的华为新闻");
        rabbitTemplate.convertAndSend("fanle-topic","xiaomi.phone.news","小米手机和手机才能收到的新闻");
        rabbitTemplate.convertAndSend("fanle-topic","huawei.phone.news","华为手机和手机才能收到的新闻");
}

1.4 Header模式

  • 配置类
@Configuration
public class HeaderConfig {

    @Bean
    Queue queueAge(){
        return new Queue("queue-age");
    }

    @Bean
    Queue queueName(){
        return new Queue("queue-name");
    }

    @Bean
    HeadersExchange headersExchange(){
        return new HeadersExchange("fanle-headers",true,false);
    }

    @Bean
    Binding bindingAge(){
        Map<String, Object> map=  new HashMap<>();
        map.put("age",99);
        //- match():当消息头中包含age并且它的值为99,才会路由到age队列
        return BindingBuilder.bind(queueAge()).to(headersExchange()).whereAny(map).match();
    }

    @Bean
    Binding bindingName(){
        //- exist():消息头中存在name属性就可以转发到name队列
        return BindingBuilder.bind(queueName()).to(headersExchange()).whereAny("name").exist();
    }


}
  • 消费者
@Component
public class HeaderReceiver {

    @RabbitListener(queues = "queue-age")
    public void age(String msg){
        System.out.println("age------" + msg);
    }

    @RabbitListener(queues = "queue-name")
    public void name(String msg){
        System.out.println("name------" + msg);
    }
}
  • 生产者
public void header(){
        //Name队列只要name属性存在于消息头中即可
        Message nameMsg = MessageBuilder.withBody("hello name".getBytes(StandardCharsets.UTF_8)).setHeader("name","fanle").build();
        rabbitTemplate.send("fanle-headers",null,nameMsg);
        //Age队列需要消息的消息头中有age属性,并且要它的value值为99
        Message ageMsg = MessageBuilder.withBody("hello age".getBytes(StandardCharsets.UTF_8)).setHeader("age",88).build();
        Message ageMsg = MessageBuilder.withBody("hello age".getBytes(StandardCharsets.UTF_8)).setHeader("age",99).build();
        rabbitTemplate.send("fanle-headers",null,ageMsg);
}

2.应用

以springboot发送邮件为例:

  1. 引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
  1. 配置文件

怎么找授权码:以QQ邮箱为例

进入QQ邮箱网页端,设置账户


在这里插入图片描述
在这里插入图片描述

spring:
  mail:
    host: smtp.qq.com
    username: 邮箱名
    password: 授权码
    default-encoding: utf-8
    port: 465
    properties:
      mail:
        smtp:
          socketFactory:
            class: javax.net.ssl.SSLSocketFactory
        debug: true
  1. 配置类
@Configuration
public class RabbitMQConfig {
    @Bean
    public Queue emailQueue() {
        return new Queue("email-queue", true);
    }

    @Bean
    public FanoutExchange emailExchange() {
        return new FanoutExchange("email-exchange", true, false);
    }

    @Bean
    public Binding bindingEmailDirect() {
        return BindingBuilder.bind(emailQueue()).to(emailExchange());
    }

}
  1. 消费者
@Component
@RabbitListener(queues = EMAIL_QUEUE)
public class EmailConsumer {

    /**
     * 邮箱号
     */
    @Value("${spring.mail.username}")
    private String email;

    @Autowired
    private JavaMailSender javaMailSender;

    @RabbitHandler
    public void process(byte[] data) {
        EmailDTO emailDTO = JSON.parseObject(new String(data), EmailDTO.class);
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(email);
        message.setTo(emailDTO.getEmail());
        message.setSubject(emailDTO.getSubject());
        message.setText(emailDTO.getContent());
        javaMailSender.send(message);
    }
}
  1. 生产者
@Override
public void sendCode(String username) {
      // 校验账号是否合法
      if (!checkEmail(username)) {
        throw new BizException("请输入正确邮箱");
      }
      // 生成六位随机验证码发送
      String code = getRandomCode();
      // 发送验证码
      EmailDTO emailDTO = EmailDTO.builder()
        .email(username)
        .subject("验证码")
        .content("您的验证码为 " + code + " 有效期15分钟,请不要告诉他人哦!")
        .build();
      rabbitTemplate.convertAndSend("email-exchange", "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
      // 将验证码存入redis,设置过期时间为15分钟
      redisService.set(USER_CODE_KEY + username, code, CODE_EXPIRE_TIME);
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
RabbitMQ是一个开源的消息代理,它实现了高级消息队列协议(AMQP)并支持多种消息传递模式。RabbitMQ使用场景包括但不限于以下几个方面: 1. 解耦:RabbitMQ可以作为一个中间件,将应用程序解耦,提高应用程序的可维护性和可扩展性。例如,当一个应用程序需要与另一个应用程序通信时,可以使用RabbitMQ作为中间件来传递消息,而不是直接调用另一个应用程序的API。 2. 异步处理:RabbitMQ可以用于异步处理,例如将请求放入队列中,然后在后台处理请求。这种方式可以提高应用程序的性能和可伸缩性。 3. 日志处理:RabbitMQ可以用于日志处理,例如将日志消息发送到RabbitMQ队列中,然后使用消费者将日志消息写入文件或数据库中。 4. 负载均衡:RabbitMQ可以用于负载均衡,例如将请求发送到多个消费者,以便更快地处理请求。 5. 消息通知:RabbitMQ可以用于消息通知,例如将通知消息发送到队列中,然后使用消费者将通知消息发送到用户的移动设备或电子邮件中。 以下是一个使用RabbitMQ进行消息传递的Python代码示例: ```python import pika # 连接到RabbitMQ服务器 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 创建一个名为“hello”的队列 channel.queue_declare(queue='hello') # 发送消息到队列中 channel.basic_publish(exchange='', routing_key='hello', body='Hello World!') print(" [x] Sent 'Hello World!'") # 关闭连接 connection.close() ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值