消息中间件 RabbitMQ

使用 RabbitMQ
这几年很火的一个概念微服务,在一个大型业务系统架构中,会被拆分成很多小的业务系统,这些业务系统之间如何建立通信,熟知的 HTTP、RPC 可以实现不同系统、不同语言之间的通信,除了这些往往还会使用消息队列(RabbitMQ、ActiveMQ、Kafafa 等)将这些系统链接起来,达到各系统间的解耦。通常关注下游执行结果的用RPC,不关注下游执行结果的用MQ。

RabbitMQ 应用场景

  1. 同步转异步

在项目中对于一些没必要同步处理的,可以借助 MQ 进行异步处理,例如,我们的短信发送就可以通过 MQ 队列来做。

  1. 应用解耦

例如商城业务场景中,订单系统与库存系统,下单的同步可能也要去减少库存,将原本耦合在一块的逻辑可以通过消息队列进行,订单系统发布消息,库存系统订阅消息,这样的好处是一般库存系统出现问题也不会影响到订单系统。
MQ能够做到上下游物理上和逻辑上都解耦:
物理上解耦,增加MQ之后,上游互不知道彼此的存在,不会建立物理连接了,大家都只与MQ建立物理连接。
逻辑上解耦,事件发布方甚至不用知道哪些下游订阅了这个消息,新增消息的订阅方只需要连接MQ就行了,不需要上游关注。
3. 流量削峰

流量削峰在一些营销活动、秒杀活动场景中应用还是比较广泛的,如果短时间流量过大,可以通过设置阀值丢弃掉一部分消息或者根据服务的承受能力设置处理消息限制,也就是限流,之后也会单独进行讲解。

MQ 的空间与时间解耦
从空间上来看,消息的生产者无需提前知道消费者的存在,反之消费者亦是,两者之间得到了解耦,不会强依赖,从而实现空间上的解耦。

从时间上来看,消息的生产者只负责生产数据将数据放入队列,之后无需关心消费者什么时间去消费,消费则可以根据自己的业务需要来选择实时消费还是延迟消费,两者都拥有了自己的生命周期,从而实现了时间上的解耦。

主流消息中间件一览
在这里插入图片描述
一,Ubuntu 18.04安装RabbitMQ
由于RabbitMQ需要erlang语言的支持,在安装RabbitMQ之前需要安装erlang

首先配置源

echo "deb https://dl.bintray.com/rabbitmq/debian trusty main" | sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list
echo "deb http://packages.erlang-solutions.com/ubuntu trusty contrib" | sudo tee -a /etc/apt/sources.list.d/erlang_solutions.list

导入对应的键

wget -c -O- http://packages.erlang-solutions.com/ubuntu/erlang_solutions.asc | sudo apt-key add -
wget -O- https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc |sudo apt-key add -

开始安装erlang和RabbitMQ

sudo apt-get update
sudo apt-get install erlang-nox
sudo apt-get install rabbitmq-server

安装完之后RabbitMQ便已经自动启动了,可以使用如下的命令对RabbitMQ进行操作:


sudo service rabbitmq-server start # 启动
sudo service rabbitmq-server stop # 停止
sudo service rabbitmq-server restart # 重启
sudo service rabbitmq-server status # 查看当前状态

以下列举一些在终端常用的操作命令
whereis rabbitmq:查看 rabbitmq 安装位置
rabbitmqctl start_app:启动应用
whereis erlang:查看erlang安装位置
rabbitmqctl start_app:启动应用
rabbitmqctl stop_app:关闭应用
rabbitmqctl status:节点状态
rabbitmqctl add_user username password:添加用户
rabbitmqctl list_users:列出所有用户
rabbitmqctl delete_user username:删除用户
rabbitmqctl add_vhost vhostpath:创建虚拟主机
rabbitmqctl list_vhosts:列出所有虚拟主机
rabbitmqctl list_queues:查看所有队列
rabbitmqctl -p vhostpath purge_queue blue:清除队列里消息
配置RabbitMQ
添加管理员用户,密码设置为admin。

sudo rabbitmqctl add_user  admin  admin  

授予权限

sudo rabbitmqctl set_user_tags admin administrator 

奖励虚拟主机中所有资源的配置,写,读权限管理其中的资源

sudo rabbitmqctl  set_permissions -p / admin '.*' '.*' '.*'

管理RabbitMQ
RabbitMQ提供了一个Web管理工具(rabbitmq_management),方便在浏览器端管理

sudo rabbitmq-plugins enable rabbitmq_management

之后在浏览器访问[http:// server-ip:15672 /],账号和密码都是刚才设置的admin
在这里插入图片描述
生产者步骤

创建链接工厂
通过链接工厂创建链接
通过链接创建通道(channel)
通过 channel 发送数据
关闭链接
消费者步骤

创建链接工厂
通过链接工厂创建链接
通过链接创建通道(channel)
声明一个队列
创建消费者
设置 channel
Node.js 版本
amqplib 客户端

Github: https://github.com/squaremo/amqp.node
配置

 OPTIONS: {
    protocol: 'amqp',
    hostname: '127.0.0.1', // 连接地址
    port: 5672,
    username: 'txapi',
    password: '123456',
    locale: 'en_US',
    frameMax: 0,
    heartbeat: 0,
    vhost: 'txapi',
  },
  
  EXCHANGE_TYPE: {
    topic: 'direct',
    ex:     'tx',
  },

构建消费者

class Consumer {
  constructor(key) {
    this.q = key;
    this.key =key;

    this.ex = RABBITMQ_CONFIG.EXCHANGE_TYPE.ex;
  }

  async receive(callback) {
    /* 
    1. 建立连接
    2. 创建信道
    3. 声明队列
    4. 声明交换机
    5. 队列绑定交换机
    6. 接收消息
    */
    try {
      const conn = await mqServer.connect(OPTIONS);
      const ch = await conn.createChannel();
      process.once('SIGINT', function () {
        console.log('意外退出');
        ch.close();
        conn.close();
      });

      // durable 持久化
      let ok = ch.assertExchange(this.ex, EXCHANGE_TYPE.topic, {
        durable: true,
      });

      ok = ok.then(() => {
        // exclusive 独占
        return ch.assertQueue(this.q, { exclusive: false });
      });

      ok = ok.then((qok) => {
        const { queue } = qok;
        return ch.bindQueue(queue, this.ex, this.key).then(() => queue);
      });

      ok = ok.then(function (queue) {
        return ch.consume(queue, callback, { noAck: true });
      });

      return ok.then(function () {
        console.log(' [*] Waiting for logs. To exit press CTRL+C');
      });

    } catch (error) {
      console.error(error);
      process.exit(1);
    }
  }

}

构建生产者

class Producer {
  constructor(mqKey) {
    this.ex = RABBITMQ_CONFIG.EXCHANGE_TYPE.ex;
    this.key = mqKey;
  }

  async send(msg) {
    /* 
    1. 建立连接
    2. 创建信道
    3. 声明队列
    4. 声明交换机
    5. 队列绑定交换机
    5. 发送消息 --- 向所有消息队列发送消息
      1. 关闭通道
    */
    try {
      const conn = await mqServer.connect(OPTIONS);
      // 进程关闭的时候,关闭连接通道
      process.once('SIGINT', () => {
        console.log('意外退出');
        conn.close();
      });
      const ch = await conn.createChannel();
      let ok = ch.assertExchange(this.ex, EXCHANGE_TYPE.topic, {
        durable: true,
      });

      return ok.then(() => {
        // 向交换机指定路由发送信息
        console.log('发送消息到消息队列');
        var strMsg = JSON.stringify(msg); 
        ch.publish(this.ex, this.key, Buffer.from(strMsg));
        return ch.close();
      });
    } catch (error) {
      console.error(error);
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值