一. 什么是消息队列?

消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。

消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。

二. 常用的消息队列有哪些?

RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq。

甚至现在部分NoSQL也可做消息队列,如Redis。

三. 消息队列的使用场景?

  • 异步处理

  • 应用解耦

  • 流量削峰

四. 使用案例

上规模的公司都会有自己的日志分析系统,日志系统是怎么实现的呢?

图解:用户在访问应用的时候,我们要记录下用户的操作记录和系统的异常日志,常规的做法是将系统产生的日志保存到服务器磁盘,在服务器中开启定时任务,定时将磁盘的日志信息传入mq中(生产者),也定时将mq中的消息取出并存到相应的数据库,如ElasticSearch或Hive中。

五. 如何安装RabbitMQ?

上面的案例介绍了MQ的一个使用场景,我这里是用RabbitMQ举例,现实项目中可能用到的是Kafka。

  1. 首先安装brew(mac为例)

    1. /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  2. 安装RabbitMQ

    1. brew install rabbitmq
  3. 运行RabbitMQ

    进入到 /usr/local/Cellar/rabbitmq/3.7.7,执行

    1. sbin/rabbitmq-server
  4. 启动插件

    进入到 /usr/local/Cellar/rabbitmq/3.7.7/sbin

    1. ./rabbitmq-plugins enable rabbitmq_management
  5. 登陆管理界面

    打开浏览器输入:http://localhost:15672,RabbitMQ默认15672端口六. Nodejs操作RabbitMQ

网上可以找到好几个相应的Node SDK,这里推荐amqplib

1. 生产者

  1. /**
  2. * 对RabbitMQ的封装
  3. */
  4. let amqp = require('amqplib');
  5.  
  6. class RabbitMQ {
  7. constructor() {
  8. this.hosts = [];
  9. this.index = 0;
  10. this.length = this.hosts.length;
  11. this.open = amqp.connect(this.hosts[this.index]);
  12. }
  13. sendQueueMsg(queueName, msg, errCallBack) {
  14. let self = this;
  15.  
  16. self.open
  17. .then(function (conn) {
  18. return conn.createChannel();
  19. })
  20. .then(function (channel) {
  21. return channel.assertQueue(queueName).then(function (ok) {
  22. return channel.sendToQueue(queueName, new Buffer(msg), {
  23. persistent: true
  24. });
  25. })
  26. .then(function (data) {
  27. if (data) {
  28. errCallBack && errCallBack("success");
  29. channel.close();
  30. }
  31. })
  32. .catch(function () {
  33. setTimeout(() => {
  34. if (channel) {
  35. channel.close();
  36. }
  37. }, 500)
  38. });
  39. })
  40. .catch(function () {
  41. let num = self.index++;
  42.  
  43. if (num <= self.length - 1) {
  44. self.open = amqp.connect(self.hosts[num]);
  45. } else {
  46. self.index == 0;
  47. }
  48. });
  49. }
  50. }

2. 消费者

  1. /**
  2. * 对RabbitMQ的封装
  3. */
  4. let amqp = require('amqplib');
  5.  
  6. class RabbitMQ {
  7. constructor() {
  8. this.open = amqp.connect(this.hosts[this.index]);
  9. }
  10. receiveQueueMsg(queueName, receiveCallBack, errCallBack) {
  11. let self = this;
  12.  
  13. self.open
  14. .then(function (conn) {
  15. return conn.createChannel();
  16. })
  17. .then(function (channel) {
  18. return channel.assertQueue(queueName)
  19. .then(function (ok) {
  20. return channel.consume(queueName, function (msg) {
  21. if (msg !== null) {
  22. let data = msg.content.toString();
  23. channel.ack(msg);
  24. receiveCallBack && receiveCallBack(data);
  25. }
  26. })
  27. .finally(function () {
  28. setTimeout(() => {
  29. if (channel) {
  30. channel.close();
  31. }
  32. }, 500)
  33. });
  34. })
  35. })
  36. .catch(function () {
  37. let num = self.index++;
  38. if (num <= self.length - 1) {
  39. self.open = amqp.connect(self.hosts[num]);
  40. } else {
  41. self.index = 0;
  42. self.open = amqp.connect(self.hosts[0]);
  43. }
  44. });
  45. }

3. 通过生产者向MQ发送一个消息,并创建队列

  1. let mq = new RabbitMQ();
  2. mq.sendQueueMsg('testQueue', 'my first message', (error) => {
  3. console.log(error)
  4. })

执行之后,我们打开管理平台,发现RabbbitMQ已经接受到了一条消息:

并且RabbbitMQ新增了一个队列testQueue

4. 获取指定队列的消息

  1. let mq = new RabbitMQ();
  2. mq.receiveQueueMsg('testQueue',(msg) =>
  3. {
  4. console.log(msg)
  5. })
  6. // 输出结果:my first message复制代码

此时打开RabbitMQ管理平台,消息数量已经变为0

综上:我们简单讲述了消息队列及RabbitMQ相关的一些知识,以及我们如何通过nodejs来生产与消费消息,上面讲的比较简单,之后会发表更多文章讲述消息队列集群搭建及容灾的实现。

架构设计之NodeJS操作消息队列RabbitMQ的更多相关文章

  1. nodejs操作消息队列RabbitMQ

    一. 什么是消息队列 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已.其主要用途:不同进程Process/ ...

  2. (二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念

    原文:(二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念 没错我还是没有讲怎么安装和写一个HelloWord,不过快了,这一章我们先了解下RabbitMQ的基本概念. Rabbit ...

  3. openstack (共享服务) 消息队列rabbitmq服务

    云计算openstack共享组件——消息队列rabbitmq(3)   一.MQ 全称为 Message Queue, 消息队列( MQ ) 是一种应用程序对应用程序的通信方法.应用程序通过读写出入队 ...

  4. C#中使用消息队列RabbitMQ

    在C#中使用消息队列RabbitMQ 2014-10-27 14:41 by qy1141, 745 阅读, 2 评论, 收藏, 编辑 1.什么是RabbitMQ.详见 http://www.rabb ...

  5. 消息队列--RabbitMQ(一)

    1.消息队列概述 可以理解为保存消息的一个媒介/或者是个容器,与之相关有两个概念(即生产者(Publish)与消费者(Consumer)).所谓生产者,就是生产创造消息的一方,那么,消费者便是从队列中 ...

  6. 消息队列rabbitmq/kafka

    12.1 rabbitMQ 1. 你了解的消息队列 rabbitmq是一个消息代理,它接收和转发消息,可以理解为是生活的邮局.你可以将邮件放在邮箱里,你可以确定有邮递员会发送邮件给收件人.概括:rab ...

  7. 消息队列rabbitmq rabbitMQ安装

    消息队列rabbitmq   12.1 rabbitMQ 1. 你了解的消息队列 生活里的消息队列,如同邮局的邮箱, 如果没邮箱的话, 邮件必须找到邮件那个人,递给他,才玩完成,那这个任务会处理的很麻 ...

  8. node使用消息队列RabbitMQ一

    基础发布和订阅 消息队列RabbitMQ使用 1 安装RabbitMQ服务器 安装erlang服务 下载地址 http://www.erlang.org/downloads 安装RabbitMQ 下载 ...

  9. (一)RabbitMQ消息队列-RabbitMQ的优劣势及产生背景

    原文:(一)RabbitMQ消息队列-RabbitMQ的优劣势及产生背景 本篇并没有直接讲到技术,例如没有先写个Helloword.我想在选择了解或者学习一门技术之前先要明白为什么要现在这个技术而不是 ...

随机推荐

  1. std::string在多字节字符集环境下substr的实现方法

    昨天写到<使用多字节字符集的跨平台(PC.Android.IOS.WP)编码/解码方法>中提到服务端使用std::string处理字符串,std::string对多字节字符集支持并不是很完 ...

  2. 允许Traceroute探测

    允许Traceroute探测 漏洞描述: 允许Traceroute探测 漏洞描述 本插件使用Traceroute探测来获取扫描器与远程主机之间的路由信息.攻击者也可以利用这些信息来了解目标网络的网络拓 ...

  3. [技巧篇]17.那些年一直再逃避的问题,还债Web阶段!

    四海行唐的一阶段和二阶段的时候,再使用数据的时候总是使用List<Map<String,Object>>的东西,但是胖先生一直不怎么喜欢! 所以我再凌云17的Web阶段的时候, ...

  4. PAT (Top Level)1002. Business DP/背包

    As the manager of your company, you have to carefully consider, for each project, the time taken to ...

  5. [洛谷P2596] [ZJOI2006]书架

    洛谷题目链接:书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后 ...

  6. HTML5实体刮刮乐效果!

    先来看DEMO吧,http://codepen.io/jonechen/pen/ZOyxmq HTML部分: <div class="msg"> <a href= ...

  7. 【BZOJ】1455 罗马游戏

    [算法]可并堆(左偏树) #include<cstdio> #include<algorithm> using namespace std; ; int l[maxn],r[m ...

  8. 简易微信小程序签到功能

    一.效果图 点击签到后 二.数据库 用一张数据表存用户签到的信息,每次用户签到都会往表中添加一条记录了用户id和签到日期的数据,如下图 三.后端 后端写两个接口,一个用于查询用户今日是否签到和签到记录 ...

  9. [转]python os模块 常用命令

    python编程时,经常和文件.目录打交道,这是就离不了os模块.os模块包含普遍的操作系统功能,与具体的平台无关.以下列举常用的命令 1. os.name()——判断现在正在实用的平台,Window ...

  10. 【bzoj1072】SCOI2007排列

    状压dp,f[i][j]表示当前取了i,模数余j的状态. 然后向后推,枚举可能的数即可. 注意每个数存在重复,最后要除以相应出现次数的阶乘. #include<bits/stdc++.h> ...