最近的Devops
和微前端已经写得差不多,开始复习下后端相关知识,之前想写的这篇文章,终于落地
如果你想加入前端交流群,可以文末联系我加入
电脑环境 推荐Mac|Linux
安装redis
,并且启动redis
redis-server
启动成功后会如下所示:
redis默认端口6379
下载redis这个库
yarn add redis --save
使用Node.js连接redis
const redis = require('redis');
const client = redis.createClient(6379, '127.0.0.1');
由于是消息队列,于是需要有一个生产者、消费者
❝这里普及下消息队列的使用,跟redis一样,都是属于进程外的服务,就是单独要占用一个端口起服务的
❞
“消息队列”是在消息的传输过程中保存消息的容器。
消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
即有生产者,消费者,发布订阅模式实现
限流削峰(降低成本,不可能按流量最高峰去配备服务器)
生产者
const redis = require('redis');
const client = redis.createClient(6379, '127.0.0.1');
client.on('error', function (err) {
console.log('err' + err);
});
client.on('ready', function () {
client.publish('testFirst', 'hi! first!');
client.publish('testSecond', 'hi! second!');
client.publish('message', 'hi! message!');
});
生产者对特定的channel进行publish,并且附带参数
消费者订阅特定的channel,消费,并且获取数据
const client = require('redis').createClient(6379, '127.0.0.1');
client.on('error', function (err) {
console.log('err' + err);
});
client.subscribe('testSecond');
client.subscribe('message');
client.on('subscribe', function (channel, count) {
console.log('subscribe channel:' + channel + ', count:' + count);
});
client.on('message', function (channel, message) {
console.log('message channel:' + channel + ', msg:' + message);
});
client.on('unsubscribe', function (channel, count) {
console.log('unsubscribe channel:' + channel + ', count:' + count);
});
结果:
我订阅了testsecoud和message两个通道,于是触发了subscribe事件两次,符合预期
加入定时器
const redis = require('redis');
const client = redis.createClient(6379, '127.0.0.1');
client.on('error', function (err) {
console.log('err' + err);
});
client.on('ready', function () {
setInterval(() => {
client.publish('testSecond', 'hi! second!');
client.publish('message', 'hi! message!');
},1000);
});
此时消费者不断打印,触发了message事件
❝这样,我们使用redis发布订阅模式,实现了简单的消息队列
❞
目前我们生产是1S一条消息,但是我想控制成2S消费一次,可以吗?
我们控制下消费频率,首先不改变生产频率
const client = require('redis').createClient(6379, '127.0.0.1');
const ArrayList = [];
client.on('error', function (err) {
console.log('err' + err);
});
client.subscribe('testSecond');
client.subscribe('message');
client.on('subscribe', function (channel, count) {
console.log('subscribe channel:' + channel + ', count:' + count);
});
client.on('message', function (channel, message) {
ArrayList.push({ channel, message });
});
client.on('unsubscribe', function (channel, count) {
console.log('channel:' + channel + ', count:' + count);
});
setInterval(()=>{
console.log(ArrayList,'ArrayList')
},2000)
每2S读取一次队列的数据
模拟的跟实际有什么不一样?
模拟的是在一个进程端口内,属于进程内缓存
真实的是可以通过回复ACK确认消费,独占一个端口进程,属于进程外缓存
源码地址:https://github.com/JinJieTan/MQ
推荐往期精彩原创阅读:
深度:手写一个WebSocket协议 [7000字]
微前端框架chunchao(春潮)开源啦
精读:手写React框架 解析Hooks源码
原创:如何自己实现一个简单的webpack构建工具 【附源码】
记得点个【在看】,关注下【前端巅峰】哦