.NET Core+MongoDB集群搭建与实战

安装 MongoDB

安装 MongoDB 网上有很多教程,MongoDB 官方文档:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

笔者这里简单写一下安装过程,笔者使用 ubuntu 系统。

要按照的目标版本:MongoDB 4.4 Community Edition

支持的系统:

  • 20.04 LTS (“Focal”)
  • 18.04 LTS (“Bionic”)
  • 16.04 LTS (“Xenial”)

更新软件源

sudo apt update
sudo apt upgrade

apt 直接安装(方法1)

如果你要安装稳定版本,则直接使用一条命令安装:

sudo apt install mongodb

执行命令检查 MingoDB 的状态:

sudo systemctl status mongodb

apt 仓库安装(方法2)

此种方式可以让你安装最新版本的 MongoDB 。

导入包管理系统使用的公钥

wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -

添加 MongoDB 的仓库源文件

 /etc/apt/sources.list.d/mongodb-org-4.4.list

添加 MongoDB 的仓库源地址

# ubuntu 16.04
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

# ubuntu 18.04
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

# ubuntu 20.04
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

加载 MongoDB 的软件包

sudo apt-get update

安装最新稳定版本的 MongoDB

sudo apt-get install -y mongodb-org

如果你想安装指定版本:

sudo apt-get install -y mongodb-org=4.4.1 mongodb-org-server=4.4.1 mongodb-org-shell=4.4.1 mongodb-org-mongos=4.4.1 mongodb-org-tools=4.4.1

方法1、2启动 MongoDB

执行命令检查 MongoDB 的状态

sudo systemctl status mongodb

启动 MongoDB

sudo systemctl start mongod

开机启动 MongoDB

sudo systemctl enable mongod

查看 MongoDB 版本

mongo --version
mongod --version

注意:由于 Linux/Unix 系统会对文件描述符的数量或者线程数量加以限制,如果安装过程或者启动时报错,需要自行另外查找方法解决,这里不再赘述。

通过二进制包安装(方法3)

适合网络不会或者离线安装,有 tgzdebsource code 等方法安装,这里只使用 tgz 方式。

安装依赖

# ubuntu 16.04
sudo apt-get install libcurl3 openssl liblzma5

# ubuntu 18.04 & 20.04
sudo apt-get install libcurl4 openssl liblzma5

选择合适的系统下载二进制包

https://www.mongodb.com/try/download/community?tck=docs_server

Package 可以选择包的形式,如 shell(deb)、shell(tgz)。

注意,要在服务器下载的话,就不要点击 Download,而是点击 Copy Link 复制二进制包的下载链接。

请注意下载的软件版本,mongos 、tagz 包含全部功能;

其它的是单独提供 server 或者 client(shell) 功能。

本小节将提供安装 .deb 和 tgz 包的说明,请自行选择要安装的包!(建议直接下载 tgz)。

不同种类的软件包

deb 安装 MongoDB

如果下载了 .deb 文件,请使用下面命令安装。

wget {下载地址}
sudo dpkg -i {软件包名}.deb

tgz 安装 MongoDB

如果下载了 .tar.gz 文件,请使用下面命令安装。

tar -zxvf mongodb-{版本}.tgz

# 下面是示例
cd mongodb-linux-x86_64-ubuntu1604-4.4.1
... ...
|-- bin
|   `-- mongo
|-- LICENSE-Community.txt
|-- MPL-2
|-- README
`-- THIRD-PARTY-NOTICES

打开解压的目录,执行:

sudo cp bin/* /usr/local/bin/
# 实际上就是将二进制可执行文件放到 bin 目录

启动 MongoDB

创建数据存放目录

sudo mkdir -p /var/lib/mongo

创建日志存放目录:

sudo mkdir -p /var/log/mongodb

如果不是使用 root 用户登录,则需要获取文件权限:

# whoami是你的用户名
sudo chown `whoami` /var/lib/mongo
sudo chown `whoami` /var/log/mongodb

运行 MongoDB:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

之后终端会提示已经成功启动;也可以查看 /var/log/mongodb/mongod.log 日志文件中的内容确定 MongoDB 的运行情况;

cat /var/log/mongodb/mongod.log 日志文件,会发现第一行:

pid=22639 port=27017

port 即 MongoDB 的连接端口。

卸载方法

apt 卸载方法

适合使用 镜像仓库安装的 MongoDB。

sudo apt-get purge mongodb mongodb-clients mongodb-server mongodb-dev
sudo apt-get purge mongodb-10gen
sudo apt-get autoremove

注:执行过程报错不用管。

tgz 卸载方法

适合卸载使用 .tar.gz 安装的包。

rm /usr/local/bin/mongo*

指定启动的配置

通过配置文件

如果前面提到过配置文件 /etc/mongod.conf,如果通过配置文件启动,则会方便很多,使用配置文件启动 MongoDB 的方法:

mongod --config /etc/mongod.conf

通过参数

通过参数启动 MongoDB 的话,每次启动都比较麻烦:

mongod  --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

MongoDB 绑定IP、端口

查看 MongoDB 配置:

# 进入 shell
mongo

# 执行
use admin
db.runCommand( { getParameter : '*' } )

默认 MongoDB 是本地服务,外界无法访问主机的 MongoDB 服务,这里来配置一下,使其能够被外网访问。

在 MongoDB 启动后,执行以下命令修改配置。

# 绑定所有地址
mongod --bind_ip_all

# 修改端口
mongod --port 27017

或者停了 MongoDB 服务后,使用以下命令启动:

mongod  --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

或者手动修改 /etc/mongod.conf 配置文件,把其中一段改成 0.0.0.0

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0  

修改完毕后,需要关闭 MongoDB,再开启,请参考后面 ”停止 MongoDB“ 一节。

测试远程 IP 连接

测试连接指定 IP 和 port 的 MongoDB 服务:

mongo {你的服务器公网IP}:27017

加上密码验证

设置账号密码

mongo

# 进入 MongoDB shell 后
use admin
db.createUser({user:"admin",pwd:"123456",roles:[{role:"root",db:"admin"}]})

如果不生效,请自行找方法解决,这里不再赘述~

开启登录验证

然后打开 /etc/mongod.conf 文件,将 #security: 改成:

security:
  authorization: enabled

如果不生效,请自行找方法解决,这里不再赘述~

停止 MongoDB

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown

搭建集群

按照此方法,再炮制一台服务器就行。

建议使用 docker 一次性搞好,自己手动在物理机上面安装,太折腾了。

接下来,我们要根据官方文档,搭建简单的副本集群。

官方文档地址:https://docs.mongodb.com/manual/replication/

副本集

副本集是一组 MongoDB 实例来维护相同数据集。

官网文档解释:一个副本集包含多个数据承载节点和一个仲裁器节点(可选)。在数据承载节点中,只有一个成员被视为主要节点,而其他节点则被视为次要节点。

用一下官方的图:

mongoDB副本集

故障转移

图中有三台 MongoDB 实例,当 Primary 挂了后,Secondary 可以换掉挂了的服务器,成为新的 Primary。

故障转移

由于我只有两台服务器,因此只能组双机热备。

方案

主节点(Primary)

对外接收所有请求,然后将修改同步到所有 Secondary 中。

当 主节点(Primary) 挂了后,其它 Secondary 或者 Arbiter 节点就会重新选举一个主节点出来。

副本节点(Secondary)

副本节点是备胎,数据集跟主节点(Primary)一致,当主节点挂了后,有机会成为正胎(Primary)。

仲裁者(Arbiter)

不保存数据集,也不能成为(Primary)。作用是当主节点挂了后,投票给 Secondary,让 Secondary 成为 Primary。

但是怎么配置原有的 MongoDB 实例,使其成为 Primary - Secondary 集群呢?Google 了很久。

找到 MongoDB 官方的文档:

https://docs.mongodb.com/manual/tutorial/deploy-replica-set/

设计实例名称

在 primary 机器和 secondary 机器上,分别打开 /etc/mongod.conf 文件,找到 #replication,设置节点名称。

replication:
  replSetName: {名称}

primary 机器设置 primary,secondary 机器设置 beitai

replSetName 的作用解释如下:

https://docs.mongodb.com/manual/reference/configuration-options/#replication.replSetName

也可以在启动 MongoDB 时加上 --replSet "beitai" 的参数。

mongod --replSet "beitai" ... ...

请停止 MongoDB 后,使用长命令的方法启动 MongoDB

请在要设置为 Primary 的机器,执行:

mongod --replSet "primary" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

请在要设置为 Secondary 的机器,执行:

mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

如何创建集群

必须要做到以下两点配置:

  • Add Members to a Replica Set
  • Deploy a Replica Set

笔者在这里踩了很大的坑,试了很多种方法和配置才成功。

启动两个实例(配置)

提前说明,如果使用 rs. 指令配置实例,想重新配置,出现 ”"errmsg" : "already initialized"“,可以使用 rs.reconfig() 清除配置。

rsconf = rs.conf()
rsconf.members = [{_id: 1,host: "本机的ip:27017"}]
rs.reconfig(rsconf,{force: true})

在 Secondary 机器,执行命令停止运行:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown

重新启动 Secondary 机器:

mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

设置为 Secondary 节点:

rs.initiate(
   {
      _id: "beitai",version: 1,members: [
         { _id: 0,host : "primary的ip:27017" }
         { _id: 1,host : "secondary的ip:27017" }
      ]
   }
)

注:id是优先级。

在 primary 机器,执行命令停止运行:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown

重新启动 primary:

mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

在 primary 进入 shell:

mongo

执行命令进行初始化并设置自己为 primary:

rs.initiate(
   {
      _id: "primary",host : "primary的ip:27017" },{ _id: 1,host : "secondary的ip:27017" }
      ]
   }
)

分别在两个实例打开 mongo shell,执行:

rs.status()

发现:

beitai:SECONDARY> 
...
primary:PRIMARY>

使用工具连接 MongoDB 并创建一个名为 Test 的数据库:

连接MongoDB

副本集状态查看

查看复制延迟:

rs.printSlaveReplicationInfo()

执行结果:

WARNING: printSlaveReplicationInfo is deprecated and may be removed in the next major release. Please use printSecondaryReplicationInfo instead.
source: *.*.*.*:27017
	syncedTo: Sat Oct 17 2020 20:02:49 GMT+0800 (CST)
	0 secs (0 hrs) behind the freshest member (no primary available at the moment)
source: *.*.*.*:27017
	syncedTo: Thu Jan 01 1970 08:00:00 GMT+0800 (CST)
	1602936169 secs (445260.05 hrs) behind the freshest member (no primary available at the moment)

.NET Core 连接 MongoDB

.NET 程序要连接 MongoDB ,需要通过 Nuget 包安装 MongoDB.Driver 驱动。

我们来创建一个控制台程序,Nuget 搜索 MongoDB.Driver 并安装,接下来一步步使用连接 MongoDB。

文档地址:https://mongodb.github.io/mongo-csharp-driver/2.10/getting_started/

添加 using 引用:

using MongoDB.Bson;
using MongoDB.Driver;

连接 MongoDB

var client = new MongoClient("mongodb://primary的ip:27017,secondary的ip:27017");

获取数据库

IMongoDatabase database = client.GetDatabase("Test");

获取文档集合

var collection = database.GetCollection<BsonDocument>("MyCollection");

插入文档(json)

            var document = new BsonDocument
            {
                { "name","MongoDB" },{ "type","Database" },{ "count",1 },{ "info",new BsonDocument
                {
                    { "x",203 },{ "y",102 }
                }}
            };

其源结构的 json 如下:

{
     "name": "MongoDB","type": "database","count": 1,"info": {
         x: 203,y: 102
     }
}

将文档插入到集合中:

            collection.InsertOne(document);
            // 使用异步 await collection.InsertOneAsync(document);

然后执行程序,一会儿后,打开 MongoDB 管理器,查看集合。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在上文中,我介绍了事件驱动型架构的一种简单的实现,并演示了一个完整的事件派发、订阅和处理的流程。这种实现太简单了,百十行代码就展示了一个基本工作原理。然而,要将这样的解决方案运用到实际生产环境,还有很长的路要走。今天,我们就研究一下在事件处理器中,对象生命周期的管理问题。事实上,不仅仅是在事件处理器
上文已经介绍了Identity Service的实现过程。今天我们继续,实现一个简单的Weather API和一个基于Ocelot的API网关。 回顾 《Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)》 Weather API Weather
最近我为我自己的应用开发框架Apworks设计了一套案例应用程序,并以Apache 2.0开源,开源地址是:https://github.com/daxnet/apworks-examples,目的是为了让大家更为方便地学习和使用.NET Core、最新的前端开发框架Angular,以及Apwork
HAL(Hypertext Application Language,超文本应用语言)是一种RESTful API的数据格式风格,为RESTful API的设计提供了接口规范,同时也降低了客户端与服务端接口的耦合度。很多当今流行的RESTful API开发框架,包括Spring REST,也都默认支
在前面两篇文章中,我详细介绍了基本事件系统的实现,包括事件派发和订阅、通过事件处理器执行上下文来解决对象生命周期问题,以及一个基于RabbitMQ的事件总线的实现。接下来对于事件驱动型架构的讨论,就需要结合一个实际的架构案例来进行分析。在领域驱动设计的讨论范畴,CQRS架构本身就是事件驱动的,因此,
HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单、统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable)更强,并具有自描述的特点。使用了HAL的API会更容易地被第三方开源库所调用,并且使用起来也很方便
何时使用领域驱动设计?其实当你的应用程序架构设计是面向业务的时候,你已经开始使用领域驱动设计了。领域驱动设计既不是架构风格(Architecture Style),也不是架构模式(Architecture Pattern),它也不是一种软件开发方法论,所以,是否应该使用领域驱动设计,以及什么时候使用
《在ASP.NET Core中使用Apworks快速开发数据服务》一文中,我介绍了如何使用Apworks框架的数据服务来快速构建用于查询和管理数据模型的RESTful API,通过该文的介绍,你会看到,使用Apworks框架开发数据服务是何等简单快捷,提供的功能也非常多,比如对Hypermedia的
在上一讲中,我们已经完成了一个完整的案例,在这个案例中,我们可以通过Angular单页面应用(SPA)进行登录,然后通过后端的Ocelot API网关整合IdentityServer4完成身份认证。在本讲中,我们会讨论在当前这种架构的应用程序中,如何完成用户授权。 回顾 《Angular SPA基于
Keycloak是一个功能强大的开源身份和访问管理系统,提供了一整套解决方案,包括用户认证、单点登录(SSO)、身份联合、用户注册、用户管理、角色映射、多因素认证和访问控制等。它广泛应用于企业和云服务,可以简化和统一不同应用程序和服务的安全管理,支持自托管或云部署,适用于需要安全、灵活且易于扩展的用
3月7日,微软发布了Visual Studio 2017 RTM,与之一起发布的还有.NET Core Runtime 1.1.0以及.NET Core SDK 1.0.0,尽管这些并不是最新版,但也已经从preview版本升级到了正式版。所以,在安装Visual Studio 2017时如果启用了
在上文中,我介绍了如何在Ocelot中使用自定义的中间件来修改下游服务的response body。今天,我们再扩展一下设计,让我们自己设计的中间件变得更为通用,使其能够应用在不同的Route上。比如,我们可以设计一个通用的替换response body的中间件,然后将其应用在多个Route上。 O
不少关注我博客的朋友都知道我在2009年左右开发过一个名为Apworks的企业级应用程序开发框架,旨在为分布式企业系统软件开发提供面向领域驱动(DDD)的框架级别的解决方案,并对多种系统架构风格提供支持。这个框架的开发和维护我坚持了很久,一直到2015年,我都一直在不停地重构这个项目。目前这个项目在
好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名《Angular单页面应用基于Ocelot API网关与IdentityServer4ʺSP.NET Identity实现身份认证与授权》,然而如你所见,这样的名字实在是太长了。所以,我不得不缩写“单页面应用”几个字
在前面两篇文章中,我介绍了基于IdentityServer4的一个Identity Service的实现,并且实现了一个Weather API和基于Ocelot的API网关,然后实现了通过Ocelot API网关整合Identity Service做身份认证的API请求。今天,我们进入前端开发,设计
Ocelot是ASP.NET Core下的API网关的一种实现,在微服务架构领域发挥了非常重要的作用。本文不会从整个微服务架构的角度来介绍Ocelot,而是介绍一下最近在学习过程中遇到的一个问题,以及如何使用中间件(Middleware)来解决这样的问题。 问题描述 在上文中,我介绍了一种在Angu
在大数据处理和人工智能时代,数据工厂(Data Factory)无疑是一个非常重要的大数据处理平台。市面上也有成熟的相关产品,比如Azure Data Factory,不仅功能强大,而且依托微软的云计算平台Azure,为大数据处理提供了强大的计算能力,让大数据处理变得更为稳定高效。由于工作中我的项目
在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容。下面的类图描述了我们已经实现的组件及其之间的关系,貌似系统已经变得越来越复杂了。其中绿色的部分就是上文中新实现的部分,包括一个简单的Event Store,一个事件处理器执行上下文的接
在之前《在ASP.NET Core中使用Apworks快速开发数据服务》一文的评论部分,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语法解析提供支持。在此非常感激友哥给我的建议,也让我了解了一些Roslyn的知识。使用Roslyn的一个很大的好处
很长一段时间以来,我都在思考如何在ASP.NET Core的框架下,实现一套完整的事件驱动型架构。这个问题看上去有点大,其实主要目标是为了实现一个基于ASP.NET Core的微服务,它能够非常简单地订阅来自于某个渠道的事件消息,并对接收到的消息进行处理,于此同时,它还能够向该渠道发送事件消息,以便