Bootstrap

RabbitMQ在springboot项目中的应用(实际项目,测试可用)

最近得空,想着把rabbitMQ在项目中的应用记录下来,希望能够帮助需要它的人~~~、
消息队列在我们的业务中主要是用来异步发送邮件,发送短信,文件的导入导出;作用想必大家都知道主要就是为了解耦,做到异步。接下来直接上代码…
噢,稍等!说明一下,以下消息队列的配置使用的是rabbitMQ的路由模式!

1.首先在pom.xml文件中引入依赖
 <!--消息队列依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
2.在项目中新建rabbitMQ的配置信息(声明队列、声明交换机、队列和交换机的绑定)和监听类(消费者)
  • 2.1 在项目中我配置的rabbit的目录结构是这样的
    -
  • 2.2 在config包下面进行rabbitmq的相关配置
    - 在这里插入图片描述

/**
 * @DESCRIPTION: 消息队列配置
 **/
@Configuration
public class RabbitConfig {
    /**
     * 声明email队列
     */
    private static final String EMAIL_TOPIC = "q_topic_email";
    /**
     * 声明短信队列
     */
    private static final String SMS_TOPIC = "q_topic_sms";

    /**
     * @return 邮件队列
     */
    @Bean
    public Queue queueEmail() {
        return new Queue(EMAIL_TOPIC);
    }

    /**
     * @return 短信队列
     */
    @Bean
    public Queue queueSms() {
        return new Queue(SMS_TOPIC);
    }


    /**
     * @return 交换机
     */
    @Bean
    TopicExchange exchange() {
        return new TopicExchange("messageExchange");
    }

    /**
     * 将队列绑定到交换机,并设置该路由为topic.email
     *
     * @param queueEmail 邮件队列
     * @param exchange   交换机
     * @return 队列和交换机绑定
     */
    @Bean
    Binding bindingExchangeEmail(Queue queueEmail, TopicExchange exchange) {
        return BindingBuilder.bind(queueEmail).to(exchange).with("topic.email");
    }

    /**
     * 将队列绑定到交换机,并设置该路由为topic.sms
     *
     * @param queueSms 短信队列
     * @param exchange 交换机
     * @return 队列和交换机绑定
     */
    @Bean
    Binding bindingExchangeSms(Queue queueSms, TopicExchange exchange) {
        return BindingBuilder.bind(queueSms).to(exchange).with("topic.sms");
    }

}

  • 2.3 在监听类(消费者)中写具体的执行逻辑
  • 在这里插入图片描述
import cn.cncommdata.message.model.Email;
import cn.cncommdata.message.service.IEmailService;
import com.alibaba.fastjson.JSONArray;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

@Component
@RabbitListener(queues = "q_topic_email")
public class EmailListener {
    /**
     * emilService
     */
    @Resource
    private IEmailService emailService;


    /**
     * 消息监听类
     *
     * @param message 消息
     */
    @RabbitHandler
    public void process(String message) {
        handler(message);
    }

    /**
     * rabbit监听到信息,异步发送
     *
     * @param message 消息
     */
    private void handler(String message) {
        List<Email> emails = JSONArray.parseArray(message, Email.class);
        if (emails.size() > 0) {
            emailService.sendEmailUtil(emails);
            emailService.updateEmailStatus(emails);
        }
    }
}

注意:消息队列的配置文件和监听类(消费者的对应关系)
在这里插入图片描述
至此,消息队列的队列的声明,交换机的声明,交换机和队列的绑定,以及消息队列的config类和监听类(消费者)的对应关系已经建立完成。

3.还有很重要的一步,就是在yml文件中配置rabbitMQ的连接配置
  # rabbitmq配置
  application:
    name: ring-boot-rabbitmq
  rabbitmq:
    host: ${rabbit_url:你的主机(ip)}
    port: ${rabbit_port:5672}
    username: ${rabbit_username:guest}
    password: ${rabbit_password:guest}
    virtual-host: /
    listener:
      simple:
        retry:
          ## 开启消费者重试
          enabled: true
          ##最大重试次数(默认无数次)
          max-attempts: 5
          ##重试间隔次数
          initial-interval: 3000

特别注意:首先声明,上述的代码中,我采用的 动 态 取 值 的 方 法 , 主 要 考 虑 到 在 部 署 到 多 态 服 务 器 的 时 候 能 够 在 不 改 变 y m l 配 置 的 情 况 下 将 参 数 动 态 传 入 到 y m l 中 , 当 然 了 , 也 可 以 直 接 写 r a b b i t M Q 的 连 接 信 息 , 不 使 用 动态取值的方法,主要考虑到在部署到多态服务器的时候能够在不改变yml配置的情况下将参数动态传入到yml中,当然了,也可以直接写rabbitMQ的连接信息,不使用 ymlymlrabbitMQ使取值。其次要在在yml中配置消息队列的最大重试次数,不配置的话,一旦由于消费者里面的程序出错,就会不断的重试,一直打印日志,直到将服务器撑爆。配置了最大重试次数以后,将会在最大重试次数完成后自动从队列中异常该条消息,也避免了消息的堆积。以上的结论都是本人测试时实际遇到的情况,如果有更好的解决方案,希望能够得到大家的指正!

4.最后一步,看看生产者是怎样将消息发送到消息队列的
           /**
            *  注入RabbitTemplate
            */
       @Autowired
        private RabbitTemplate rabbitTemplate;
        /**
         * 发送邮件信息到rabbit
         * param1:messageExchange  交换机名称
         * param2: topic.email 路由键
         * param3: JSONObject.toJSONString(emailList) 具体的消息
         */
        rabbitTemplate.convertAndSend("messageExchange", "topic.email", JSONObject.toJSONString(emailList));
        

在这里插入图片描述
至此,消息队列的配置、消息生产者发送消息、消息监听者(消费者)的相关配置已经全部完成。以上代码,都是来自本人开发中实际应用的,如果有写的不到位的地方,欢迎指正。

;