RabbitMQ全家桶

1.概念

生产者:
需要将消息发送到消费者进行异步处理的一方,通常是一个微服务的接口,上游的业务流程;
rabbitMQ队列:
由于消费者处理消息较慢,需要异步进行,该队列用于缓存消息;
消费者:
接收rabbitMQ队列发送的消息,然后进行下游业务流程处理,通常是另一个为服务的接口;

2.与其它MQ对比的优势

本人之前使用过Kafka,对比Kafka,rabbitmq配置相对简单,并且接口更加易用;

3.与其他MQ对比的劣势

参考链接:https://blog.csdn.net/weixin_34161064/article/details/93742823

个人体验:

经过一个项目的使用,体验如下:
1)消息队列容易丢失数据;
2)消息处理速度慢;

4.docker 安装

4.1

将下面的xxxxxxxxxxx替换为你拉取镜像生成的ID

docker pull rabbitmq:3.7.7-management
docker run -d --name rabbitmq3.7.7 -p 5672:5672 -p 15672:15672 -v `pwd`/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin xxxxxxxxxxx

4.2测试

在这里插入图片描述

5.springboot项目中的配置

5.1 pom

        <!--消息队列依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        

5.2 yml

配置参数严格按照,生成容器的参数配置

  rabbitmq:
    host: ${rabbit_url:127.0.0.1}
    port: ${rabbit_port:5672}
    username: ${rabbit_username:admin}
    password: ${rabbit_password:admin}
    virtual-host: my_vhost
    # 设置消息的确认模式为auto
    listener:
      simple:
        retry:
          ## 开启消费者重试
          enabled: true
          ##尝试投递消息的最大数量(默认3次)
          max-attempts: 10
          ##第一次与第二次投递尝试的时间间隔
          initial-interval: 3000ms

5.2多队列配置

1)声明交换机,声明队列,声明路由,绑定队列到交换机在指定路由下

package cn.cncommdata.form.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author libing.niu
 * @description: 消息队列配置(队列声明,交换机声明,队列和交换机进行绑定)
 * @date: 2019/05/07  22:04
 */
@Configuration
public class RabbitMQConfig {

    /**
     * 声明交换机
     */
    public static final String FORM_EXCHNGE = "form_exchange";
    /**
     * 声明Tree的交换机
     */
    public static final String TREE_EXCHANGE = "tree_exchange";
    /**
     * 声明审核回调队列
     */
    public static final String APPROVALED_CALLBACK_TOPIC = "form_approvalCallBack";
    /**
     * 声明修改form工程的物料数据队列
     */
    public static final String MODIFY_MATERIAL_QUEUE = "modify_material_queue";
    /**
     * 声明form的rountingkey
     */
    public static final String FROM_ROUTING_KEY = "topic.form.callback";
    /**
     * 修改form工程的物料数据的路由
     */
    public static final String MODIFY_MATERIAL_ROUTING_KEY = "modify.material";
    /**
     * 重试修改form工程的物料数据的路由
     */
    public static final String MODIFY_MATERIAL_RETRY_ROUTING_KEY = "retry.modify.material";

    /**
     * @return 声明交换机
     */
    @Bean
    public TopicExchange exchange() {
        return new TopicExchange(FORM_EXCHNGE);
    }

    /**
     * @return Tree的交换机
     */
    @Bean
    public TopicExchange treeExchange() {
        return new TopicExchange(TREE_EXCHANGE);
    }

    /**
     * @return 修改物料数据队列
     */
    @Bean
    public Queue modifyMaterial() {
        return new Queue(MODIFY_MATERIAL_QUEUE, true);
    }

    /**
     * @return 修改物料数据队列
     */
    @Bean
    public Queue retryModifyMaterial() {
        return new Queue(MODIFY_MATERIAL_RETRY_ROUTING_KEY, true);
    }

    /**
     * @return 声明审核回调队列
     */
    @Bean
    public Queue approvalCallBack() {
        return new Queue(RabbitMQConfig.APPROVALED_CALLBACK_TOPIC);
    }

    /**
     * 将queueExportData队列绑定到交换机 并设置路由为topic.exportData
     *
     * @param approvalCallBack 回调队列
     * @param exchange         交换机
     * @return 返回
     */
    @Bean
    Binding bindingExchangeExportData(Queue approvalCallBack, TopicExchange exchange) {
        return BindingBuilder.bind(approvalCallBack).to(exchange).with(FROM_ROUTING_KEY);
    }

    /**
     * 将修改物料数据的队列和交换机进行绑定
     *
     * @param modifyMaterial modifyMaterial
     * @param treeExchange   exchange
     * @return bindingExchangeModifyMaterial
     */
    @Bean
    Binding bindingExchangeModifyMaterial(Queue modifyMaterial, TopicExchange treeExchange) {
        return BindingBuilder.bind(modifyMaterial).to(treeExchange).with(MODIFY_MATERIAL_ROUTING_KEY);
    }

    /**
     * 将修改物料数据的队列和交换机进行绑定
     *
     * @param retryModifyMaterial modifyMaterial
     * @param treeExchange        exchange
     * @return bindingExchangeModifyMaterial
     */
    @Bean
    Binding bindingExchangeRetryModifyMaterial(Queue retryModifyMaterial, TopicExchange treeExchange) {
        return BindingBuilder.bind(retryModifyMaterial).to(treeExchange).with(MODIFY_MATERIAL_RETRY_ROUTING_KEY);
    }
}

2) 发送数据到队列


import cn.cncommdata.form.rabbitmq.config.RabbitMQConfig;
import cn.cncommdata.form.service.IFormApprovalService;
import cn.cncommdata.form.service.IFormService;
import cn.cncommdata.form.service.ISaveService;
import cn.cncommdata.form.vo.BaseVO;
import cn.cncommdata.form.vo.FormDataVO;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

    /**
     * 审批完成后回调接口,修改源数据 -
     * <p>
     *
     * @param tenantId 租户Id
     * @param formId   表单Id
     * @param dataId   数据Id
     * @param result   confirm审核同意/reject驳回/refuse拒绝
     * @param type     审核类型 create/edit/delete
     * @return baseVO
     * @author libing.niu
     */
    @ApiOperation("回调接口")
    @GetMapping("/data/approve/callback")
    public BaseVO callback(@ApiParam(value = "租户Id", required = true) @RequestHeader("tenant_id") Long tenantId,
                           @ApiParam(value = "表单Id", required = true) @RequestParam("form_id") Long formId,
                           @ApiParam(value = "数据Id", required = true) @RequestParam("data_id") Long dataId,
                           @ApiParam(value = "审核结果", required = true) @RequestParam String result,
                           @ApiParam(value = "审核类型", required = true) @RequestParam String type) {

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("tenantId", tenantId);
        jsonObject.put("formId", formId);
        jsonObject.put("dataId", dataId);
        jsonObject.put("result", result);
        jsonObject.put("type", type);
        log.info("rabbitMQ消息:开始进入rabbitMQ队列,formDataId是==》" + dataId.toString());
        rabbitTemplate.convertAndSend(RabbitMQConfig.FORM_EXCHNGE, RabbitMQConfig.FROM_ROUTING_KEY, jsonObject);
        return new BaseVO(BaseVO.SUCCESS_CODE, "操作成功!");

    }

3) 接收处理队列消息

package cn.cncommdata.form.rabbitmq;

import cn.cncommdata.form.rabbitmq.config.RabbitMQConfig;
import cn.cncommdata.form.service.IFormApprovalService;
import cn.cncommdata.form.util.constant.Const;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ClassName: ApprovalCallBackListerner
 * @Description: 审核回调接口监听类
 * @Author: libing.niu
 * @Date: 2019/7/9 19:07
 * @Version: 1.0
 */
@Slf4j
@Component
@RabbitListener(queues = RabbitMQConfig.APPROVALED_CALLBACK_TOPIC)
public class ApprovalCallBackListerner {
    /**
     * fromData SEVICE层接口
     */
    @Autowired
    private IFormApprovalService formApprovalService;

    /**
     * rabbitMQ异步处理 Form审批的回调业务逻辑
     *
     * @param jsonObject 业务参数
     */
    @RabbitHandler
    private void approvalCallBack(JSONObject jsonObject) {

        //解析参数
        Long tenantId = (Long) jsonObject.get("tenantId");
        Long formId = (Long) jsonObject.get("formId");
        Long dataId = (Long) jsonObject.get("dataId");
        String result = (String) jsonObject.get("result");
        String type = (String) jsonObject.get(Const.TYPE);

        log.info("rabbitMQ消息:从rabbitMQ队列获取数据,formDataId是==》" + dataId.toString());
        formApprovalService.callback(tenantId, formId, dataId, result, type);
    }
}
发布了93 篇原创文章 · 获赞 20 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/leinminna/article/details/102940276
今日推荐