rabbitmq项目应用分析

rabbitmq介绍
MQ全称Message Queue,即消息队列,RabbitMQ是由relang语言开发,基于AMQP(Advanced Message Queuing Protocol 一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计),它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用的非常广泛。

JMS是什么
JMS是java提供的一套消息服务API标准,其目的是为所有的java应用程序提供统一的消息通信的标准,类似java的 jdbc,只要遵循jms标准的应用程序之间都可以进行消息通信。它和AMQP有什么 不同,jms是java语言专属的消息服务标准,它是在api层定义标准,并且只能用于java应用;而AMQP是在协议层定义的标准,是跨语言的 。

开发过程中消息队列的应用场景

  1. 任务异步处理
    将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
  2. 应用程序解耦合
    MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序解耦合

为什么使用RabbitMQ

  1. 使用简单,功能强大
  2. 基于AMQP协议
  3. 社区活跃,文档完善
  4. 高并发性能好,这主要得益于Erlang语言
  5. Spring Boot 默认已集成RabbitMQ

RabbitMQ的工作原理

RabbitMQ的基本结构

组件部分说明如下

  1. Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
  2. Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。
  3. Exchang:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过滤。
  4. Queue:消息队列,储存消息的队列,消息到达队列并转发给指定的消费方。
  5. Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。

消息发布接收流程:

–发送消息–

  1. 生产者 和Broker建立TCP连接
  2. 生产者和Broker 建立通道
  3. 生产者通过通道消息发送给Broker,由Exchange将消息进行转发。( 声明队列
  4. Exchange将消息转发到指定的Queue队列。( 发送消息

–接收消息–

  1. 消费者和Broker简历TCP连接。( 创建连接)
  2. 消费者和Broker建立通道( 创建通道
  3. 消费者监听指定的Queue(队列)( 声明队列
  4. 当有消息到达Queue时Broker默认将消息推送给消费者( 监听队列
  5. 消费者接收到消息( 接收消息

rabbitMQ有以下几种工作模式

  1. work queues
  2. publish/subscribe
  3. routing
  4. topics
  5. headers
  6. rpc

在项目中的使用
系统管理发布页面-发送消息给mq消息队列-门户服务器接收消息然后从gridfs获取页面-门户得到发布的课程资源
在这里插入图片描述

流程

创建消费方并部署在多个服务器上,它负责接收到页面发布的消息后从GridFS中下载文件在本地保存。

  1. 配置交换机、队列名称和路由key(站点ID)。
@Configuration
public class RabbitmqConfig {
    //队列的名称
    public static final String QUEUE_CMS_POSTPAGE = "queue_cms_postpage";
    //交换机的名称
    public static final String EX_ROUTING_CMS_POSTPAGE="ex_routing_cms_postpage";
    //队列的名称
    @Value("${xuecheng.mq.queue}")
    public String queue_cms_postpage_name;
    //routingKey 即站点Id
    @Value("${xuecheng.mq.routingKey}")
    public String routingKey;
    /**
     * 交换机配置使用direct类型
     * @return the exchange
     */
    @Bean(EX_ROUTING_CMS_POSTPAGE)
    public Exchange EXCHANGE_TOPICS_INFORM() {
        return ExchangeBuilder.directExchange(EX_ROUTING_CMS_POSTPAGE).durable(true).build();

    }
    //声明队列
    @Bean(QUEUE_CMS_POSTPAGE)
    public Queue QUEUE_CMS_POSTPAGE(){
        Queue queue = new Queue((queue_cms_postpage_name));
        return queue;
    }
    /**
     * 绑定队列到交换机
     *
     * @param queue the queue
     * @param exchange the exchange
     * @return the binding
     */
    @Bean
    public Binding BINDING_QUEUE_INFORM_SMS(@Qualifier(QUEUE_CMS_POSTPAGE) Queue queue,
                                            @Qualifier(EX_ROUTING_CMS_POSTPAGE) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(routingKey).noargs();
    }


}
  1. 连接RabbitMQ并监听各自的“队列”。接收页面发布队列的消息。
@Component
public class ConsumerPostPage {
    //日志
    private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerPostPage.class);

    @Autowired
    CmsPageRepository cmsPageRepository;

    @Autowired
    PageService pageService;

    @RabbitListener(queues={"${xuecheng.mq.queue}"})
    public void postPage(String msg){
        //解析消息
        Map map=JSON.parseObject(msg, Map.class);
        LOGGER.info("recieve cms post page:{}",msg.toString());
        //取出页面id
        String pageId=(String) map.get("pageId");
        //查询页面信息
        Optional<CmsPage> optional = cmsPageRepository.findById(pageId);
        if(!optional.isPresent()){
            LOGGER.error("recieve post msg is null:{}", msg.toString());
            return;
        }
        //将页面保存到服务器的物理路径
        pageService.savePageToServerPath(pageId);
    }
}
  1. 根据消息(页面id)从mongodb数据库下载页面到本地
 //将页面保存到服务器的物理路径
        pageService.savePageToServerPath(pageId);

cms系统作为页面发布的生产方

  1. 前端请求cms页面发布接口
  2. 、cms页面发布接口执行页面静态化,并将静态化页面存储至GridFS中。
  3. 静态化成功后,向消息队列发送页面发布的消息。
 //页面发布
    public ResponseResult post(String pageId){
        //执行页面静态化
        String pageHtml = this.getPageHtml(pageId);
        //将静态化文件存储到gridFs中
        CmsPage cmsPage = saveHtml(pageId, pageHtml);
        //向MQ发消息
        sendPostPage(pageId);
        return new ResponseResult(CommonCode.SUCCESS);
    }
  • 配置交换机
@Configuration
public class RabbitmqConfig {
    //交换机的名称
    public static final String EX_ROUTING_CMS_POSTPAGE="ex_routing_cms_postpage";

    /**
     * 交换机配置使用direct类型
     * @return the exchange
     */
    @Bean(EX_ROUTING_CMS_POSTPAGE)
    public Exchange EXCHANGE_TOPICS_INFORM() {
        return ExchangeBuilder.directExchange(EX_ROUTING_CMS_POSTPAGE).durable(true).build();

    }
}
  • 获取页面的信息及页面所属站点ID。
  • 设置消息内容为页面ID。(采用json格式,方便日后扩展)
  • 发送消息给ex_cms_postpage交换机,并将站点ID作为routingKey。
  //向mq發消息
    public void sendPostPage(String pageId){
        //得到頁面信息
        CmsPage cmsPage = this.getById(pageId);
        if(cmsPage==null){
            ExceptionCast.cast(CmsCode.INVALID_PARAM);
        }
        //创建消息对象
        Map<String, String> msg = new HashMap<>();
        msg.put("pageId", pageId);
        //转成json串
        String jsonString = JSON.toJSONString(msg);
        //发送给mq
        String siteId = cmsPage.getSiteId();
        rabbitTemplate.convertAndSend(RabbitmqConfig.EX_ROUTING_CMS_POSTPAGE,siteId, jsonString );

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ 是一个开源的消息队列间件,它广泛应用于各种项目。以下是一些 RabbitMQ 运用项目示例: 1. 分布式系统:RabbitMQ 可以用于分布式系统的消息传递和解耦。不同的服务可以通过 RabbitMQ 发送和接收消息,实现服务之间的异步通信,提高系统的可伸缩性和可靠性。 2. 微服务架构:在微服务架构RabbitMQ 可以用作服务之间的通信机制。每个微服务可以发布和订阅消息,实现服务之间的解耦和灵活性。 3. 异步任务处理:RabbitMQ 可以用于处理异步任务。例如,当用户提交一个任务时,可以将任务放入 RabbitMQ 的消息队列,然后由后台的工作节点异步处理任务,提高系统的响应速度和并发性能。 4. 日志收集与分发:RabbitMQ 可以用于日志收集和分发。应用程序可以将日志消息发送到 RabbitMQ,然后由日志消费者处理和存储。这样可以集管理日志,并且通过订阅消息的方式实时监控和分析日志。 5. 实时数据处理:RabbitMQ 可以用于实时数据处理。例如,传感器数据可以通过 RabbitMQ 发送到数据处理节点,然后进行实时的数据分析和计算。 这些只是 RabbitMQ 的一些常见应用场景,实际上,RabbitMQ 还可以用于事件驱动架构、任务调度、消息通知等各种场景。它提供了丰富的功能和灵活的配置选项,可以根据具体项目的需求进行定制和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值