SpringBoot+RabbitMQ实现消息队列发邮件

在我的之前写的轻博客中,当用户注册时需要发送一封邮件到用户注册的邮箱来激活账号,因为是同步方法,所以响应很慢,得等到邮件发送成功才有响应,所以打算使用RabbiMQ来异步发送邮件,提高响应速度

本次是简单使用RabbitMQ作个简单的发送邮件Demo,告诉大家基本的使用方法

  • 首先使用IDEA创建两个模块
    SpringBoot+RabbitMQ实现消息队列发邮件_第1张图片
    email-producer模拟注册功能,接收用户注册的邮箱地址,把邮箱地址存入到消息队列中,email-consumer模拟发送邮件功能,当消息队列有消息时,消费消息,根据消息中的邮箱地址发送邮件。
    创建的时候添加Web和RabbitMQ的依赖
    SpringBoot+RabbitMQ实现消息队列发邮件_第2张图片
    发送邮件可以使用javamail,我选择的是使用Hutool的邮件工具,需要在email-consumer中引入下来两个依赖
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-extraartifactId>
            <version>5.3.8version>
        dependency>
        <dependency>
            <groupId>javax.mailgroupId>
            <artifactId>mailartifactId>
            <version>1.4.7version>
        dependency>

Email-Producer

  • 配置RabbitMQ
spring:
  rabbitmq:
    host: 一般为localhost,我是放在了服务器上所以是服务器地址
    username: guest
    password: guest
    port: 5672
server:
  port: 7777
  • 接着就是创建队列,交换器,路由键等
@Configuration
public class RabbitmqConfig {

    // 队列名称
    public static final String QUEUE_NAME = "email_queue";
    
    // 交换器名称
    public static final String EXCHANGE = "email_exchange";

    // 路由键名称
    public static final String ROUTEKEY = "email_routekey";

    @Autowired
    private Environment environment;

    /**
    * @Description: 创建队列
    * @Param: []
    * @return: org.springframework.amqp.rabbit.annotation.Queue
    * @Author: 林北
    * @Date: 2020-07-09
    */
    @Bean
    Queue queue(){
        // 是否持久化
        boolean durable = true;
        // 仅创建者可以使用的私有队列,断开后自动删除
        boolean exclusive = false;
        // 当所有消费客户端连接端库后,是否自动删除队列
        boolean autoDelete = false;
        return new Queue(QUEUE_NAME, durable,exclusive,autoDelete);
    }

    /**
    * @Description: 创建Topic交换器
    * @Param: []
    * @return: org.springframework.amqp.core.TopicExchange
    * @Author: 林北
    * @Date: 2020-07-10
    */
    @Bean
    TopicExchange exchange(){
        return new TopicExchange(EXCHANGE,true,false);
    }

    /**
    * @Description: 绑定交换器和队列通过路由键
    * @Param: []
    * @return: org.springframework.amqp.core.Binding
    * @Author: 林北
    * @Date: 2020-07-10
    */
    @Bean
    Binding binding(){
        return BindingBuilder.bind(queue()).to(exchange()).with(ROUTEKEY);
    }

    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

}
  • 创建方法接口,和实现类,通过SpringBoot中自带的RabbitTemplate把消息存入消息队列中
public interface EmailService {

    /**
    * @Description: 发送邮箱地址到消息队列中
    * @Param: [message]
    * @return: void
    * @Author: 林北
    * @Date: 2020-07-09
    */
    void sendEmailMessage(String message);
}


@Service
@Slf4j
public class EmailServiceImpl implements EmailService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void sendEmailMessage(String message) {
        rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE,RabbitmqConfig.ROUTEKEY, message);
        log.info("邮件: "+message);
    }
}
  • 编写Controller类,模拟注册接口,接收用户注册的邮箱地址
@RestController
public class EmailController {

    @Autowired
    private EmailService emailService;

    @RequestMapping("/reg")
    public String reg(@RequestParam("email") String email){
        emailService.sendEmailMessage(email);
        return "邮件已经发送";
    }
}

Email-Consumer

  • 配置RabbitMQ和邮箱
spring:
  rabbitmq:
    host: 一般为localhost,我是放在了服务器上所以是服务器地址
    username: guest
    password: guest
    port: 5672
server:
  port: 7777

邮箱配置,可以查看Hutool如何配置邮箱

  • 配置RabbitMQ
@Configuration
public class RabbitmqConfig {

    // 队列名称
    public static final String QUENE_NAME="email_queue";

    /**
    * @Description: 创建队列
    * @Param: []
    * @return: org.springframework.amqp.core.Queue
    * @Author: 林北
    * @Date: 2020-07-10
    */
    @Bean
    Queue queue(){
        return new Queue(QUENE_NAME);
    }

    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}
  • 创建方法接口,和实现类,监听队列,当队列有消息时消费消息
public interface EmailService {

    void printEmail(String message);
}

@Service
@Slf4j
public class EmailServiceImpl implements EmailService{


    @Override
    public void printEmail(String message) {
        int result = (int) ((Math.random()*9+1)*1000);
        log.info("发送邮箱地址: "+message);
        MailUtil.send(message, "验证码", String.valueOf(result), false);
        log.info("验证码: "+result);
    }

    @RabbitListener(queues = RabbitmqConfig.QUENE_NAME)
    private void consumerEmail(String message){
        printEmail(message);
    }
}

@RabbitListener该注解用在方法上,当指定的队列有消息时,就会执行该方法。当接收到消息后,就会随机产生四位数字,作为邮件内容发送到接收到邮箱地址。发送邮件的发送可以看Hutool。

使用Postman模拟调用接口

SpringBoot+RabbitMQ实现消息队列发邮件_第3张图片
参数带上指定的邮箱地址
RabbitMQ中已经有存有对应的邮箱地址
SpringBoot+RabbitMQ实现消息队列发邮件_第4张图片
当消息队列中有消息时,email-consumer就会消息该消息,并发送邮件
SpringBoot+RabbitMQ实现消息队列发邮件_第5张图片

你可能感兴趣的:(spring,boot学习,rabbitmq,spring,boot)