【后端开发实习】用MongoDB和Redis实现消息队列搭建分布式邮件消息系统

news2024/11/25 14:26:38

用Redis实现消息队列并搭建分布式邮件消息系统

  • 系统介绍
  • Redis实现消息队列
    • 思路分析
    • 代码实现
  • MongoDB监听数据变化
    • 思路分析
    • 代码实现
      • Mongoose测试连接
      • 监听mongodb数据变化
  • 注意点

系统介绍

本次要实现的是一个能够实现实时监控Mongodb中数据变化的系统,要能够在数据发生变动的时候实时将变动消息发送给指定的邮箱。

  • Node.js:用于开发的语言,既能用于前端开发,又能用来做后端开发。
  • Redis:用于搭建消息队列,实现消息的分布式。
  • MongoDB:持久化数据,同时实现触发条件的监听,当MongoDB中有新增数据的时候发送新增数据的邮件消息。

Redis实现消息队列

思路分析

主要使用的就是Redis-smq这个库,下面展示的就是主要使用的消息队列类,其中包括了很多队列种类,有先进先出、优先级先出等方式。
在这里插入图片描述
整个库的原理如下结构图,本次使用到的只有主线,就是发送和接收:
在这里插入图片描述

代码实现

const { transemail } = require('../email_list/email.js');
const redis = require('promise-redis-client');
const redisHost = 'localhost';
const redisPort = 6379;

// 配置 Redis 客户端
const createRedisClient = () => {
    return new Promise((resolve, reject) => {
        let client = redis.createClient({ host: redisHost, port: redisPort });
        client.on('error', err => {
            console.log('Redis 连接出错');
            reject(err);
        });
        client.on('ready', () => {
            console.log('Redis ready');
            resolve(client);
        });
    });
};

async function startWaitMsg(redisClient) {
    while (true) {
        let res = null;
        try {
            res = await redisClient.brpop('bookChanges', 0);
            console.log('收到消息', res);
        } catch (err) {
            console.log('brpop 出错,重新 brpop');
            continue;
        }
        res = res.toString();
        transemail(res);
    }
}

async function listenredis() {
    try {
        // 启动生产者
        // startProducer();

        // 创建 Redis 客户端
        const redisClient = await createRedisClient();

        // 启动消息监听
        startWaitMsg(redisClient);
    } catch (error) {
        console.error('Error:', error);
    }
}
//测试的时候使用的代码
listenredis().catch(console.error);

// 处理退出信号以关闭客户端
process.on('SIGINT', async () => {
    console.log('Closing clients...');
    process.exit(0);
});

MongoDB监听数据变化

思路分析

由于要实现实时检测,经过分析以后使用mongoose中的数据流监控最为合适,但是要实现这个方法需要用到watch方法,这个方法只有在mongodb有副本集的时候才能使用,因此还需要提前配置好mongodb才能进行这里下一步的操作,如果没有配置过mongodb的副本集的可以参考我的这篇博客。

  1. 用mongoose中的watch连接mongodb副本集数据库获取数据变化。
  2. 将数据变化发送到redis消息队列中。

首先在命令行中将服务启动:
在这里插入图片描述

代码实现

Mongoose测试连接

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/test', {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then(() => {
  console.log('Successfully connected to MongoDB');

  const bookSchema = new mongoose.Schema({
    title: String,
    author: String
  });

  const Book = mongoose.model('Book', bookSchema);

  const bookChangeStream = Book.watch();

  bookChangeStream.on('change', (change) => {
    console.log('Collection changed:', change);
    if (change.operationType === 'insert') {
      console.log('New book added:', change.fullDocument);
    }
  });
}).catch((error) => {
  console.log('Error connecting to MongoDB:', error);
});

在这里插入图片描述
测试结果:
在Mongo Campass中添加数据以后,在终端中出现如下消息:
在这里插入图片描述
证明测试成功,可以进行下一步操作啦!

监听mongodb数据变化

const redis = require('redis');
const mongoose = require('mongoose');
// 创建 Redis 客户端
const redisClient = redis.createClient({
	host: 'localhost',
	port: 6379
  });
  
  // 连接到 Redis
redisClient.connect();
  
//连接mongodb数据库并检测变化发送到redis消息队列
async function connectAndMonitorMongoDB(redisClient) {
  try {
    await mongoose.connect('mongodb://localhost/test', {
      useNewUrlParser: true,
      useUnifiedTopology: true
    });
    console.log('Successfully connected to MongoDB');

    const bookSchema = new mongoose.Schema({
      title: String,
      author: String
    });

    const Book = mongoose.model('Book', bookSchema);

    const bookChangeStream = Book.watch();
	try{
		bookChangeStream.on('change', (change) => {
			console.log('Collection changed:', change);
			console.log("type of change:",typeof(change));
			msg = JSON.stringify(change.fullDocument);
			msg = msg.replace(/{|}/g, '');
			msg = "New message received:"+msg;
			console.log("massage:",msg);
			console.log("type of message:",typeof(msg));
			if (change.operationType === 'insert') {
			  console.log('New book added:', msg);
			  redisClient.lPush('bookChanges', msg, function(err, reply) {
				if (err) {
				  console.log('Error storing JSON to Redis:', err);
				} else {
				  console.log('JSON stored successfully, list length:', reply);
				}})
			}
		  });
	}catch (err){
		console.log("error while loading data into redis:", err)
	}
  } catch (error) {
    console.log('Error connecting to MongoDB:', error);
  }
}

// module.exports = { connectAndMonitorMongoDB };
async function main() {
  try {
    await connectAndMonitorMongoDB(redisClient);
    console.log('Monitoring MongoDB changes...');
  } catch (error) {
    console.error('Failed to start monitoring:', error);
  }
}

main();

注意点

在nodejs中将JSON对象转换成字符串的JSON.Stringify函数并不是严格的转换成字符串而是带有一个大括号,然而这个在进行redis进队列的时候会有问题,因此需要用正则表达式去掉大括号:

msg = JSON.stringify(change.fullDocument);
msg = msg.replace(/{|}/g, '');
msg = "New message received:"+msg;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1930319.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电机泵盖机器人打磨去毛刺,选德国进口高精度主轴

机器人打磨去毛刺该如何选择主轴呢?首先我们需要考虑的是工件的材质,电机泵盖通常使用铸铁、不锈钢、合金钢等金属材质,因此这类保持的硬度较高,一般会选择功率、扭矩较大的德国进口高精度主轴Kasite 4060 ER-S。 Kasite 4060 ER-…

持续集成03--Jenkins的安装与配置

前言 在持续集成/持续部署(CI/CD)的实践中,Jenkins作为一个开源的自动化服务器,扮演着至关重要的角色。本篇“持续集成03--Jenkins的安装配置”将带您走进Jenkins的世界,深入了解如何在Linux环境中安装并配置Jenkins。…

redis安装,启动客户端、验证(redis第一次作业)

Redis简介 全称: mote ctionary erver (远程字典服务器)。是完全开源免费的,用 C 语言编写的,遵守 BSD协议。是一个高性能的 (key/value) 分布式内存数据库,基于内存运行并支持持久化的 NoSQL 数据库&#…

react Jsx基础概念和本质

什么是jsx jsx是JavaScript和XML(HTML)的缩写&#xff0c;表示在js代码中编写HTML模板结构&#xff0c;它是react中编写UI模板的方式 const message this is message function App(){return (<div><h1>this is title</h1>{message}</div>) } jsx优…

昇思25天学习打卡营第12天|Vision Transformer图像分类、SSD目标检测

Vision Transformer&#xff08;ViT&#xff09;简介 近些年&#xff0c;随着基于自注意&#xff08;Self-Attention&#xff09;结构的模型的发展&#xff0c;特别是Transformer模型的提出&#xff0c;极大地促进了自然语言处理模型的发展。由于Transformers的计算效率和可扩…

南京邮电大学统计学课程实验2 用EXCEL进行参数估计假设检验 指导

一、实验描述 实验目的 1、学会用Excel进行参数估计&#xff1b; 2、学会用Excel进行z检验-双样本平均差检验&#xff1b; 实验环境 实验中使用以下软件和硬件设备 &#xff08;1&#xff09;Windows XP操作系统&#xff1b; &#xff08;2&#xff09;PC机、EXCEL软件&…

Mysql基础与安装

一、数据库的概念和相关的语法和规范 1、数据库的概念 数据库&#xff1a;组织&#xff0c;存储&#xff0c;管理数据的仓库。 数据库的管理系统&#xff08;DBMS&#xff09;&#xff1a;实现对数据有效组织&#xff0c;管理和存取的系统软件。 数据库的种类&#xff1a; …

Jenkins整合Owasp DependencyCheck实现SCA

简介 Dependency-Check 是 OWASP&#xff08;Open Web Application Security Project&#xff09;的一个实用开源程序&#xff0c;用于识别项目依赖项并检查是否存在任何已知的&#xff0c;公开披露的漏洞。 目前&#xff0c;已支持Java、.NET、Ruby、Node.js、Python等语言编写…

ArkTS学习笔记_UI界面的状态管理简述

ArkTS学习笔记_UI界面的状态管理简述 背景&#xff1a; 我们在UI开发中&#xff0c;绝大多数的UI界面都是动态的、有用户交互的&#xff0c;为了实现动态交互&#xff0c;引入了一个概念“状态”&#xff0c;它主要是用来记录管理UI界面的状态变化&#xff08;数据变化&#x…

【EXCELL技巧篇】使用Excel公式,获取当前 Excel的Sheet页的名字

【通知】&#xff1a; 正式跟大家说个难过的消息&#xff0c;本来在「中国朝代史」结束后&#xff0c;开启的下一个专栏「中国近代史」前面几期做的还好好的&#xff0c;可是今天起正式通知审核不过&#xff0c;因为一些原因。 其实我对于历史这一块我还是很感兴趣的&#xff0…

Abaqus基于CT断层扫描的三维重建插件CT2Model 3D

插件介绍 AbyssFish CT2Model 3D V1.0 插件可将采用X射线等方法获取的计算机断层扫描&#xff08;CT&#xff09;图像在Abaqus有限元软件内进行三维重建&#xff0c;进而高效获取可供模拟分析的有限元模型。插件可用于医学影像三维重构、混凝土细观三维重建、岩心数字化等领域…

Qcom平台通过Hexagon IDE 测试程序性能指导

Qcom平台通过Hexagon IDE 测试程序性能指导 1 安装Hexagon IDE工具2 测试工程2.1 打开Hexagon IDE2.2 新建工程2.3 添加测试案例2.3.1 方法一&#xff1a;新建2.3.2 方法二&#xff1a;拷贝 2.4 配置测试环境2.4.1 包含头文件2.4.2 添加程序优化功能(需先bulid一下)2.4.3 添加g…

nodejs安装+踩坑报错解决

下载Node.js安装包 官网下载地址&#xff1a;http://nodejs.cn/download/&#xff0c;根据自己电脑选择32位还是64位&#xff0c; 下载地址 选择合适的版本下载 X86是32位的&#xff0c;X64是64位的&#xff0c;我们一般是下载win版X64的msi文件的是点击可以直接启动安装程序的…

框架设计MVC

重点&#xff1a; 1.用户通过界面操作&#xff0c;传输到control&#xff0c;control可以直接去处理View&#xff0c;或者通过模型处理业务逻辑&#xff0c;然后将数据传输给view。 2.control包含了model和view成员。 链接&#xff1a; MVC框架详解_mvc架构-CSDN博客 MVC架…

使用 Python 爬虫实现自动获取天气信息并语音播报

简介 在本文中&#xff0c;我将介绍如何使用 Python 编写一个简单的爬虫程序&#xff0c;该程序可以自动获取某个城市的天气信息&#xff0c;并使用语音库将这些信息播报出来。我们将使用 pyttsx3 库进行语音播报&#xff0c;以及 requests 和 lxml 库来获取和解析网页数据。 …

深度刨析程序中的指针

前面我们已经学习过了指针的一下性质&#xff1a; 指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识的一块内存空间指针的大小是固定的4/8个字节&#xff08;32位平台/64位平台&#xff09;指针是有类型&#xff0c;指针的类型决定了指针的加减整数的步长&…

C语言------指针讲解(2)

目录 一、数组名的理解 二、使用指针访问数组 三、一维数组传参的本质 四、冒泡排序 五、二级指针 六、指针数组 七、指针数组模拟二维数组 一、数组名的理解 通过学习&#xff0c;我们知道&#xff1a;数组名和数组首元素的地址打印出来的结果一模一样&#xff0c;数组…

C语言函数:编程世界的魔法钥匙(1)

目录 1.C语言中的函数是什么&#xff1f; 2.函数的分类&#xff1a; 2.1 标准库函数 2.1.1 库函数的诞生&#xff1a; 2.1.2 库函数的作用&#xff1a; 2.1.3 如何学习使用库函数 2.2 自定义函数 2.2.1 函数的组成&#xff1a; 2.2.2 自定义函数的优点 2.2.3 例题 3…

Windows下安装Mujoco1.50

Windows下安装Mujoco1.50复现强化学习论文 很多经典强化学习算法&#xff08;DDPG、PPO&#xff09;使用Mujoco环境进行实验和评估&#xff0c;配置复现环境非常困难&#xff0c;有以下几点原因&#xff1a; 年代久远&#xff0c;Mujoco-py的依赖管理做的不好&#xff0c;仅限…

Apache trino的ldap认证开启

作者&#xff1a;櫰木 1、背景 由于trino 默认没有开启用户认证体系&#xff0c;需要ldap用户进行认证。开启tls和ldap用户认证&#xff0c;提高安全性。 2、配置 前置条件。 trino 集群已经部署完成 ldap 服务 openjdk 版本大于11.0.17 生成证书 keytool -genkeypair…