使用Node.js驅動Redis,實現一個消息隊列!

寫在開頭

  • 最近的Devops和微前端已經寫得差很少,開始複習下後端相關知識,以前想寫的這篇文章,終於落地
  • 若是你想加入前端交流羣,能夠文末聯繫我加入

正式開始

  • 電腦環境 推薦Mac|Linux
  • 安裝redis,而且啓動redis
`redis-server`
  • 啓動成功後會以下所示:

  • redis默認端口6379

開始寫Node.js代碼

  • 下載redis這個庫
yarn add redis --save
  • 使用Node.js鏈接redis
const redis = require('redis');

const client = redis.createClient(6379, '127.0.0.1');
  • 因爲是消息隊列,因而須要有一個生產者、消費者

這裏普及下消息隊列的使用,跟redis同樣,都是屬於進程外的服務,就是單獨要佔用一個端口起服務的前端

git

什麼是消息隊列?

  • 「消息隊列」是在消息的傳輸過程當中保存消息的容器。
  • 消息被髮送到隊列中。「消息隊列」是在消息的傳輸過程當中保存消息的容器。消息隊列管理器在將消息從它的源中繼到它的目標時充當中間人。隊列的主要目的是提供路由並保證消息的傳遞;若是發送消息時接收者不可用,消息隊列會保留消息,直到能夠成功地傳遞它。
  • 即有生產者,消費者,發佈訂閱模式實現

消息隊列使用場景

  • 業務解耦
  • 異步處理提高性能

  • 限流削峯(下降成本,不可能按流量最高峯去配備服務器)

開始實現

  • 生產者
`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發佈訂閱模式,實現了簡單的消息隊列github

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確認消費,獨佔一個端口進程,屬於進程外緩存

一個簡單的經過redis實現消息隊列就完成了

  • 源碼地址:https://github.com/JinJieTan/MQ
相關文章
相關標籤/搜索