RabbitMQ基础系列:原理及工作过程

1 结构

1.0 RabbitMQ结构及流程图

在这里插入图片描述

图1 RabbitMQ结构示意图

1.2 组件

  • (1)Broker
    RabbitMQ服务器,用于对外提供服务,客户端(生产者及消费者)使用RabbitMQ消息中间件均需要连接到Broker,使用Rabbit的消息队列服务
  • (2)Virtual Host
    Broker(服务器)的虚拟机,提供多租户,实现租户的权限分离
  • (3)Publiser
    消息生产者
  • (4)Connection
    客户端与RabbitMQ服务器连接服务(TCP),其中Connection中可建立多个Chennel,在生成和消费消息过程中,客户端无需与服务器建立多次TCP连接,通过共用Connection中的Channel(虚拟TCP连接),降低多次TCP连接及断开的性能消耗
  • (5)Exchange
    消息交换器,指定消息发送规则及发送到指定的消息队列
  • (6)Binding
    绑定,即把交换器与消息队列进行绑定,用于队列向队列存储消息
  • (7)Queue
    消息队列,存储消息
  • (8)Consumer
    消息消费者
  • (9)WebServiceClient
    Web服务,对于RabbitMQ而言是客户端

2 工作过程

2.1 部署RabbitMQ

  • 安装erlang
sudo apt-get install erlang-nox
  • 安装RabbitMQ
sudo apt-get install rabbitmq-server
  • 查看RabbitMQ状态
service rabbitmq-server status

在这里插入图片描述

图2.1 RabbitMQ运行状态
  • 添加用户
sudo rabbitmqctl add_user admin admin
  • 用户授权
sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
  • 开启Web端监控
sudo rabbitmq-plugins enable rabbitmq_management

在这里插入图片描述

图2.2 开启Web管理
  • 登录RabbitMQ管理平台
http://localhost:15672

在这里插入图片描述

图2.3 登录RabbitMQ

在这里插入图片描述

图2.4 RabbitMQ详情
  • RabbitMQ密令
序号描述命令
1启动sudo rabbitmq-server start
2停止sudo rabbitmq-server stop
3重启sudo rabbitmq-server restart
4状态sudo rabbitmqctl status

2.2 消息传递过程

RabbitMQ消息传递流程如图1所示,详细解析如下:

  • (1)生产消息客户端通过Connection与Broker连接
  • (2)客户端中的租户信息与Virtual Host匹配,连接到Virtual Host
  • (3)生产的消息经过交换器
  • (4)交换器绑定到特定的消息队列
  • (5)生产者生产的消息存储到消息队列
  • (6)消费者通过Connection与Broker连接
  • (7)消费者通过配置的队列信息,从消息队列中获取数据

2.3 租户及队列配置信息

  • 租户:admin
  • 队列:testqueue
  • 交换机方式:dircet
{"rabbit_version":"3.6.10","users":[{"name":"admin","password_hash":"1/hXieLSCl6dpkUWcXhBXvCq1R0BOKSEjpo8GtX9PMzw1MQJ","hashing_algorithm":"rabbit_password_hashing_sha256","tags":"administrator"},{"name":"guest","password_hash":"Wy4saet6gG7VqxTMLnaXdrgnWwUyz3npPPuQVEgb7wsuP5cr","hashing_algorithm":"rabbit_password_hashing_sha256","tags":"administrator"}],"vhosts":[{"name":"/"}],"permissions":[{"user":"guest","vhost":"/","configure":".*","write":".*","read":".*"},{"user":"admin","vhost":"/","configure":".*","write":".*","read":".*"}],"parameters":[],"global_parameters":[{"name":"cluster_name","value":"rabbit@xdq"}],"policies":[],"queues":[{"name":"testqueue","vhost":"/","durable":true,"auto_delete":false,"arguments":{}}],"exchanges":[],"bindings":[]}

2.4 交换机消息传递方式

  • 直连direct(默认)
    消息队列直接绑定到交换机上,交换机将消息发送至与特定的路由完全匹配的队列中,如特定消息队列为queue1,则只有queue1队列可以接收到消息,其他队列无法收到消息
  • 主题topic
    主题交换器,交换器将消息发送至与路由匹配模式相同的所有队列,如队列模式(ROUTING_KEY)为test.queue,交换器将分发消息至*.queue,test.queue, *.* ,及#.test.queue,其中,*为任意词组,#为匹配0个或多个词组
  • 标题headers
    消息体的header匹配(忽略)
  • 分发fanout
    广播交换器,此时的ROUTING_KEY无效,因为交换机会将消息发送给所有绑定的队列

2.5 消息确认

RabbitMQ消息确认方式有三种,即不确认(none),手动确认(manual),自动确认(auto),若客户端不确认接收到消息,RabbitMQ不会清除当时已被消费过的消息,知道客户端消息确认后,才会将消息队列中的消息移除(remove),否则,每次只要客户端重连到RabbitMQ都会重新收到消息队列中的消息.

  • 未确认消息
    在这里插入图片描述

    图2.5 客户端未确认接受的消息

  • 已确认消息

在这里插入图片描述

图2.6 客户端确认接受的消息

2.5.1 手动确认

  • 配置文件
spring:
  profiles: dev
  application: 
    name: quartz-cluster-node-second
  rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: admin
    publisher-confirms: true 
    publisher-returns: true
    listener:
      direct:
        acknowledge-mode: manual
      simple: 
        acknowledge-mode: manual
  • 接收消息及手动确认
package com.company.web.service;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.beans.factory.annotation.Autowired;
import com.rabbitmq.client.Channel;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.amqp.rabbit.annotation.RabbitListener;

import java.util.Map;
/**
 * @author xindaqi
 * @description 消息消费者
 * @date 2020-06-29
 */
@Component
public class MQReceiveService {
    @Autowired
    private AmqpTemplate template;
    @Autowired 
    private RabbitTemplate rabbitTempalte;

    @RabbitListener(queues="testqueue")
    public String receive(String msg, @Headers Map<String, Object> headers, Channel channel){
        try{
            System.out.println("msg:"+msg);
            Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
            // 消息手动确认
            channel.basicAck(deliveryTag, false);
            //TODO 写入数据库等其他操作
            return msg;
        }catch(Exception e){
            e.printStackTrace();
        }
        return "ERROR";
    } 
}

2.2 自动确认消息

  • 配置信息
spring:
  profiles: dev
  application: 
    name: quartz-cluster-node-second
  rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: admin
    publisher-confirms: true 
    publisher-returns: true
    listener:
      direct:
        acknowledge-mode: auto
      simple: 
        acknowledge-mode: auto

[参考文献]
[1]https://my.oschina.net/u/2364788/blog/2875902
[2]https://blog.csdn.net/yangshengwei230612/article/details/105913074
[3]https://www.jianshu.com/p/24e541170ace
[4]https://blog.csdn.net/xiaobaixiongxiong/article/details/89071917
[5]http://www.uml.org.cn/zjjs/201909092.asp
[6]https://www.cnblogs.com/ybjourney/p/12130985.html
[7]https://www.cnblogs.com/gne-hwz/p/10717473.html
[8]https://www.cnblogs.com/nizuimeiabc1/p/9397326.html
[9]https://blog.csdn.net/Xin_101/article/details/107026296

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值