架构设计之NodeJS操作消息队列RabbitMQ
一. 什么是消息队列?
消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。
消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。
二. 常用的消息队列有哪些?
RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq。
甚至现在部分NoSQL也可做消息队列,如Redis。
三. 消息队列的使用场景?
异步处理
应用解耦
流量削峰
四. 使用案例
上规模的公司都会有自己的日志分析系统,日志系统是怎么实现的呢?
图解:用户在访问应用的时候,我们要记录下用户的操作记录和系统的异常日志,常规的做法是将系统产生的日志保存到服务器磁盘,在服务器中开启定时任务,定时将磁盘的日志信息传入mq中(生产者),也定时将mq中的消息取出并存到相应的数据库,如ElasticSearch或Hive中。
五. 如何安装RabbitMQ?
上面的案例介绍了MQ的一个使用场景,我这里是用RabbitMQ举例,现实项目中可能用到的是Kafka。
首先安装brew(mac为例)
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安装RabbitMQ
brew install rabbitmq
运行RabbitMQ
进入到 /usr/local/Cellar/rabbitmq/3.7.7,执行
sbin/rabbitmq-server
启动插件
进入到 /usr/local/Cellar/rabbitmq/3.7.7/sbin
./rabbitmq-plugins enable rabbitmq_management
登陆管理界面
打开浏览器输入:http://localhost:15672,RabbitMQ默认15672端口六. Nodejs操作RabbitMQ
网上可以找到好几个相应的Node SDK,这里推荐amqplib
1. 生产者
/**
* 对RabbitMQ的封装
*/
let amqp = require('amqplib'); class RabbitMQ {
constructor() {
this.hosts = [];
this.index = 0;
this.length = this.hosts.length;
this.open = amqp.connect(this.hosts[this.index]);
}
sendQueueMsg(queueName, msg, errCallBack) {
let self = this; self.open
.then(function (conn) {
return conn.createChannel();
})
.then(function (channel) {
return channel.assertQueue(queueName).then(function (ok) {
return channel.sendToQueue(queueName, new Buffer(msg), {
persistent: true
});
})
.then(function (data) {
if (data) {
errCallBack && errCallBack("success");
channel.close();
}
})
.catch(function () {
setTimeout(() => {
if (channel) {
channel.close();
}
}, 500)
});
})
.catch(function () {
let num = self.index++; if (num <= self.length - 1) {
self.open = amqp.connect(self.hosts[num]);
} else {
self.index == 0;
}
});
}
}
2. 消费者
/**
* 对RabbitMQ的封装
*/
let amqp = require('amqplib'); class RabbitMQ {
constructor() {
this.open = amqp.connect(this.hosts[this.index]);
}
receiveQueueMsg(queueName, receiveCallBack, errCallBack) {
let self = this; self.open
.then(function (conn) {
return conn.createChannel();
})
.then(function (channel) {
return channel.assertQueue(queueName)
.then(function (ok) {
return channel.consume(queueName, function (msg) {
if (msg !== null) {
let data = msg.content.toString();
channel.ack(msg);
receiveCallBack && receiveCallBack(data);
}
})
.finally(function () {
setTimeout(() => {
if (channel) {
channel.close();
}
}, 500)
});
})
})
.catch(function () {
let num = self.index++;
if (num <= self.length - 1) {
self.open = amqp.connect(self.hosts[num]);
} else {
self.index = 0;
self.open = amqp.connect(self.hosts[0]);
}
});
}
3. 通过生产者向MQ发送一个消息,并创建队列
let mq = new RabbitMQ();
mq.sendQueueMsg('testQueue', 'my first message', (error) => {
console.log(error)
})
执行之后,我们打开管理平台,发现RabbbitMQ已经接受到了一条消息:
并且RabbbitMQ新增了一个队列testQueue
4. 获取指定队列的消息
let mq = new RabbitMQ();
mq.receiveQueueMsg('testQueue',(msg) =>
{
console.log(msg)
})
// 输出结果:my first message复制代码
此时打开RabbitMQ管理平台,消息数量已经变为0
综上:我们简单讲述了消息队列及RabbitMQ相关的一些知识,以及我们如何通过nodejs来生产与消费消息,上面讲的比较简单,之后会发表更多文章讲述消息队列集群搭建及容灾的实现。
架构设计之NodeJS操作消息队列RabbitMQ的更多相关文章
- nodejs操作消息队列RabbitMQ
一. 什么是消息队列 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已.其主要用途:不同进程Process/ ...
- (二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念
原文:(二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念 没错我还是没有讲怎么安装和写一个HelloWord,不过快了,这一章我们先了解下RabbitMQ的基本概念. Rabbit ...
- openstack (共享服务) 消息队列rabbitmq服务
云计算openstack共享组件——消息队列rabbitmq(3) 一.MQ 全称为 Message Queue, 消息队列( MQ ) 是一种应用程序对应用程序的通信方法.应用程序通过读写出入队 ...
- C#中使用消息队列RabbitMQ
在C#中使用消息队列RabbitMQ 2014-10-27 14:41 by qy1141, 745 阅读, 2 评论, 收藏, 编辑 1.什么是RabbitMQ.详见 http://www.rabb ...
- 消息队列--RabbitMQ(一)
1.消息队列概述 可以理解为保存消息的一个媒介/或者是个容器,与之相关有两个概念(即生产者(Publish)与消费者(Consumer)).所谓生产者,就是生产创造消息的一方,那么,消费者便是从队列中 ...
- 消息队列rabbitmq/kafka
12.1 rabbitMQ 1. 你了解的消息队列 rabbitmq是一个消息代理,它接收和转发消息,可以理解为是生活的邮局.你可以将邮件放在邮箱里,你可以确定有邮递员会发送邮件给收件人.概括:rab ...
- 消息队列rabbitmq rabbitMQ安装
消息队列rabbitmq 12.1 rabbitMQ 1. 你了解的消息队列 生活里的消息队列,如同邮局的邮箱, 如果没邮箱的话, 邮件必须找到邮件那个人,递给他,才玩完成,那这个任务会处理的很麻 ...
- node使用消息队列RabbitMQ一
基础发布和订阅 消息队列RabbitMQ使用 1 安装RabbitMQ服务器 安装erlang服务 下载地址 http://www.erlang.org/downloads 安装RabbitMQ 下载 ...
- (一)RabbitMQ消息队列-RabbitMQ的优劣势及产生背景
原文:(一)RabbitMQ消息队列-RabbitMQ的优劣势及产生背景 本篇并没有直接讲到技术,例如没有先写个Helloword.我想在选择了解或者学习一门技术之前先要明白为什么要现在这个技术而不是 ...
随机推荐
- C语言中两个!!的作用
两个!是为了把非0值转换成1,而0值还是0. 因为C语言中,所有非0值都表示真. 所以!非0值 = 0,而!0 = 1.所以!!非0值 = 1,而!!0 = 0.例如:i=123 !i=0 !!i=1 ...
- cssText基本使用及注意事项
一.cssText之起步 那些年,我们是这样设置样式的: xxx.style.width = "233px"; xxx.style.position = "fixed&q ...
- SpringMVC中 Session的使用情况
在SpringMVC中,使用Session可以用通过两种方式 1.servlet-api 即HttpSession session.setAttritute(),session.getAttribut ...
- 图论:Prufer编码-Cayley定理
BZOJ1430:运用Cayley定理解决树的形态统计问题 由Prufer编码可以引申出来一个定理:Cayley 内容是不同的n结点标号的树的数量为n^(n-2) 换一种说法就是一棵无根树,当知道结点 ...
- java collection (二)
1.集合的概念: (1)现实生活中:很多的事物凑在一起. (2)数学中的集合:具有共同属性的事物的总体. (3java 中的集合类: 是一种工具类,就像是容器,存储任意数量的具有共同属性的对象.(集合 ...
- java 8新特性 instant
Java 8目前已经开始进入大众的视线,其中笔者在写本文之前,留意到其中Java 8预览版中将会出现新的关于日期和时间的API(遵守JSR310规范).在本系列文章中,将对这些新的API进行举例说明. ...
- java中各种循环
简单介绍一下java中的一些循环 package test; import org.apache.log4j.Logger; import org.junit.Test; public class F ...
- 【NOIP】2013提高组 花匠(摆花)
[算法]DP||贪心 [题解] (1)动态规划: 令f[i][0..1]为两种条件下前i株花的最大保留数量,状态转移方程: f[i][0]=max(f[j][1]+1) (j=i-1...1)(h[i ...
- MYSQL查找总结
a.条件判断where select * from 表 where id > 1 and name != 'alex' and num = 12; select * from 表 where ...
- HDU 1087 Super Jumping! Jumping! Jumping! --- DP入门之最大上升子序列
题目链接 DP基础题 求的是上升子序列的最大和 而不是最长上升子序列LIS DP[i]表示以a[i]结尾所能得到的最大值 但是a[n-1]不一定是整个序列能得到的最大值 #include <bi ...