mongo变更流使用及windows下副本集五分钟搭建
mongodb的变更流解释:
变更流(Change Streams)允许应用程序访问实时数据变更,从而避免事先手动追踪 oplog 的复杂性和风险。应用程序可使用变更流来订阅针对单个集合、数据库或整个部署的所有数据变更,并立即对它们做出响应。由于变更流采用聚合框架,因此,应用程序还可对特定变更进行过滤,或是随意转换通知。(Change Streams - MongoDB Manual v5.0)
使用场景,需要websocket推送实时数据的时候,我们把数据写入mongo的同时,websocket实时监听mongo数据,拿到后推送到订阅组用户。
这里只做一端新增另一端服务监听测试,及windows下副本集快速搭建流程。

sub端代码
package main import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
) func main() {
// 设置 MongoDB 客户端mongo单机模式不支持这种监听 单机报错 2024/08/10 11:18:54 (Location40573) The $changeStream stage is only supported on replica sets
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}
defer client.Disconnect(context.TODO()) // 获取数据库和集合
collection := client.Database("testdb").Collection("items") // 设置 Change Stream
pipeline := mongo.Pipeline{}
changeStreamOptions := options.ChangeStream().SetFullDocument(options.UpdateLookup)
changeStream, err := collection.Watch(context.TODO(), pipeline, changeStreamOptions)
if err != nil {
log.Fatal(err)
}
defer changeStream.Close(context.TODO()) fmt.Println("开始监听 Change Stream...") // 读取 Change Stream
for changeStream.Next(context.TODO()) {
var changeEvent bson.M
if err := changeStream.Decode(&changeEvent); err != nil {
log.Fatal(err)
} fmt.Printf("检测到更改: %+v\n", changeEvent)
} if err := changeStream.Err(); err != nil {
log.Fatal(err)
}
}
pub端代码
package main import (
"context"
"fmt"
"time" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
) func main() {
// 设置 MongoDB 客户端
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
fmt.Println("连接 MongoDB 失败:", err)
return
}
defer client.Disconnect(context.TODO()) // 获取数据库和集合
collection := client.Database("testdb").Collection("items") // 插入数据
for i := 1; i <= 5; i++ {
item := bson.D{{"name", fmt.Sprintf("item%d", i)}, {"value", i}}
_, err := collection.InsertOne(context.TODO(), item)
if err != nil {
fmt.Println("插入数据失败:", err)
return
}
//fmt.Printf("插入数据: %+v\n", item)
fmt.Printf("插入数据第 %d 条", i)
time.Sleep(2 * time.Second) // 模拟一些延迟
}
}
执行结果 pub端

执行结果 sub端

数据库不用新建集合,自动生成很方便


下面是windows下安装副本集步骤一字不拉
https://www.mongodb.com/try/download/community 下载zip包解压 bin目录同级创建data-data4(data内部需要创建好db目录),log-log4
MongoDB shell version v5.0.28
注意 data目录下没有db文件夹net start MongoDB执行服务起不来 192.168.2.6 本机ip
mongod.exe --config "E:\mongodb\mongod.conf" --serviceName "MongoDB" --serviceDisplayName "MongoDB" --install mongod.exe --config "E:\mongodb\mongod1.conf" --serviceName "MongoDB1" --serviceDisplayName "MongoDB1" --install mongod.exe --config "E:\mongodb\mongod2.conf" --serviceName "MongoDB2" --serviceDisplayName "MongoDB2" --install mongod.exe --config "E:\mongodb\mongod3.conf" --serviceName "MongoDB3" --serviceDisplayName "MongoDB3" --install net start MongoDB
net start MongoDB1
net start MongoDB2
net start MongoDB3 bin目录下打开cmd执行mongo.exe rs_conf={_id:"rs",
members:[
{_id:0,host:"192.168.2.6:27017",priority:1},
{_id:1,host:"192.168.2.6:27018",priority:2},
{_id:2,host:"192.168.2.6:27019",priority:3},
{_id:4,host:"192.168.2.6:27020", arbiterOnly:true}
]} 返回这个代表成功:
{
"_id" : "rs",
"members" : [
{
"_id" : 0,
"host" : "192.168.2.6:27017",
"priority" : 1
},
{
"_id" : 1,
"host" : "192.168.2.6:27018",
"priority" : 2
},
{
"_id" : 2,
"host" : "192.168.2.6:27019",
"priority" : 3
},
{
"_id" : 4,
"host" : "192.168.2.6:27020",
"arbiterOnly" : true
}
]
} rs.initiate(rs_conf) 执行配置
{"ok":1}
rs.status() 查看状态
{
"set" : "rs",
"date" : ISODate("2024-08-10T02:40:20.391Z"),
"myState" : 2,
"term" : NumberLong(2),
"syncSourceHost" : "192.168.2.6:27019",
"syncSourceId" : 2,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 3,
"writeMajorityCount" : 3,
"votingMembersCount" : 4,
"writableVotingMembersCount" : 3,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"lastCommittedWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"appliedOpTime" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"lastAppliedWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"lastDurableWallTime" : ISODate("2024-08-10T02:40:16.003Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1723257586, 1),
"electionParticipantMetrics" : {
"votedForCandidate" : true,
"electionTerm" : NumberLong(2),
"lastVoteDate" : ISODate("2024-08-10T02:39:15.909Z"),
"electionCandidateMemberId" : 2,
"voteReason" : "",
"lastAppliedOpTimeAtElection" : {
"ts" : Timestamp(1723257547, 5),
"t" : NumberLong(1)
},
"maxAppliedOpTimeInSet" : {
"ts" : Timestamp(1723257547, 5),
"t" : NumberLong(1)
},
"priorityAtElection" : 1,
"newTermStartDate" : ISODate("2024-08-10T02:39:15.997Z"),
"newTermAppliedDate" : ISODate("2024-08-10T02:39:16.928Z")
},
"members" : [
{
"_id" : 0,
"name" : "192.168.2.6:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2677,
"optime" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2024-08-10T02:40:16Z"),
"lastAppliedWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"lastDurableWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"syncSourceHost" : "192.168.2.6:27019",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 1,
"configTerm" : 2,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.2.6:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 85,
"optime" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2024-08-10T02:40:16Z"),
"optimeDurableDate" : ISODate("2024-08-10T02:40:16Z"),
"lastAppliedWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"lastDurableWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"lastHeartbeat" : ISODate("2024-08-10T02:40:19.059Z"),
"lastHeartbeatRecv" : ISODate("2024-08-10T02:40:20.083Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "192.168.2.6:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1,
"configTerm" : 2
},
{
"_id" : 2,
"name" : "192.168.2.6:27019",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 85,
"optime" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1723257616, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2024-08-10T02:40:16Z"),
"optimeDurableDate" : ISODate("2024-08-10T02:40:16Z"),
"lastAppliedWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"lastDurableWallTime" : ISODate("2024-08-10T02:40:16.003Z"),
"lastHeartbeat" : ISODate("2024-08-10T02:40:19.060Z"),
"lastHeartbeatRecv" : ISODate("2024-08-10T02:40:20.022Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1723257555, 1),
"electionDate" : ISODate("2024-08-10T02:39:15Z"),
"configVersion" : 1,
"configTerm" : 2
},
{
"_id" : 4,
"name" : "192.168.2.6:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 85,
"lastHeartbeat" : ISODate("2024-08-10T02:40:19.059Z"),
"lastHeartbeatRecv" : ISODate("2024-08-10T02:40:20.092Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1,
"configTerm" : 2
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1723257616, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1723257616, 1)
}
demo代码链接
go/mongochangestreamsdemo/demo at main · liuzhixin405/go (github.com)
mongo配置链接
config/mongo windows集群 at main · liuzhixin405/config (github.com)
mongo变更流使用及windows下副本集五分钟搭建的更多相关文章
- 《sed的流艺术之四》-linux命令五分钟系列之二十四
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之三》-linux命令五分钟系列之二十三
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之一》-linux命令五分钟系列之二十一
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- zookeeper windows伪集群搭建
1.下载zookeeper http://mirror.bit.edu.cn/apache/zookeeper/ 解压后,目录重命名为zookeeper1,进入 conf目录,把zoo_sample. ...
- 《sed的流艺术之二》-linux命令五分钟系列之二十二
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- MongoDB 变更流(Change Stream)介绍
1. 什么是Change Stream Change Stream 是MongoDB用于实现变更追踪的解决方案,类似于关系数据库的触发器,但原理不完全相同: | | Change Stream | 触 ...
- 在Windows Server 2012 R2中搭建SQL Server 2012故障转移集群
需要说明的是我们搭建的SQL Server故障转移集群(SQL Server Failover Cluster)是可用性集群,而不是负载均衡集群,其目的是为了保证服务的连续性和可用性,而不是为了提高服 ...
- windows+mysql集群搭建-三分钟搞定集群
注:本文来源: 陈晓婵 < windows+mysql集群搭建-三分钟搞定集群 > 一:mysql集群搭建教程-基础篇 计算机一级考试系统要用集群,目标是把集群搭建起来,保证一 ...
- Kettle在windows下分布式集群的搭建
集群的搭建 我这里用的是kettle7.1版本的 下载解压 我们打开kettle的安装目录,进入到data-integration->pwd目录,找到carte-config-master-80 ...
- Solr集群的搭建以及使用(内涵zookeeper集群的搭建指南)
1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候 ...
随机推荐
- vue cli4.0项目引入typescript
现有的项目是采用vue cli4.0脚手架生成的,现在想要引入typescript. 1.执行安装命令 npm install --save-dev typescript npm install -- ...
- springboot+security自定义登录-1-基础-自定义用户和登录界面
为何学习spring security? 理由如下: 1)虽然可以不用,但难免部分客户又要求 2)某种程度上,security还是不错的,譬如csrf,oauth等等,省了一些功夫. 3)虽然spri ...
- Linux内核:regmap机制
背景 在学习SPI框架的时候,看到了有一个rtc驱动用到了regmap,本想通过传统方式访问spi接口的我,突然有点不适应,翻了整个驱动,愣是没有找到读写spi的范式:因此了解了regmap以后,才发 ...
- uboot 修改代码 增加 环境变量
--- title: uboot修改代码增加环境变量 date: 2019-12-27 21:26:39 categories: tags: - uboot --- 以"tftp下载kern ...
- EC热键问题
EC热键问题 ec 问题描述 ACPI事件监控 按键监控 UDEV事件监控 kprobe探测 初步总结热键功能流程 调试记录 PS2 问题描述 系统无触摸板打开和关闭的提示 已知热键功能 快捷键 功能 ...
- 韦东山freeRTOS系列教程之【第八章】事件组(event group)
目录 系列教程总目录 概述 8.1 事件组概念与操作 8.1.1 事件组的概念 8.1.2 事件组的操作 8.2 事件组函数 8.2.1 创建 8.2.2 删除 8.2.3 设置事件 8.2.4 等待 ...
- ChatGPT学习之旅 (8) 单元测试助手
大家好,我是Edison. 本篇我们基于上一篇的基础,来写一个单元测试助手的prompt,让它帮我们写一些我们.NET开发者不太愿意编写的单元测试代码,进而提高我们的代码质量,同时还降低我们的开发工作 ...
- Java报表开发工具总结
Java报表工具,首先可以分成两大类:纯Java报表工具,和支持Java的报表工具. 支持Java的报表工具 支持Java的报表工具.其实就是非Java的报表工具,但是可以在Java程序中调用,这样的 ...
- 文件系统(九):一文看懂yaffs2文件系统原理
liwen01 2024.07.07 前言 yaffs 是专为nand flash 设计的一款文件系统,与jffs 类似,都是属于日志结构文件系统.与jffs 不同的是,yaffs 文件系统利用了na ...
- 首届 DIVE 精彩回顾丨践行企业数字化,基础软件如何创新
"墙高基下,虽得必失."在构建数字企业大厦的工程中,基础软件的重要性不言而喻.但对于各行各业而言,面向传统经营模式设计的基础软件已经难以支撑数字业务的创新,唯有汲取专业团队的经验, ...