65.9K
CodeProject 正在变化。 阅读更多。
Home

水平扩展 .net C# / NodeJS, MongoDB 与微服务

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (3投票s)

2015 年 10 月 29 日

CPOL

9分钟阅读

viewsIcon

23948

downloadIcon

352

使用消息队列水平扩展应用程序

引言

关于物联网(Internet of Things)的讨论很多,如何处理其数据?微服务是方法吗?一旦设备上线,我们将有大量请求/数据涌入服务器,每个请求的响应时间都很重要。现在人们分享了许多关于水平扩展应用程序的想法。在本文中,我们将讨论重构一个以典型单体设计开发的 .Net 应用程序。编写本文只是分享一个思路,并尝试获得反馈。

在本文中,我假设您对 .net / Nodejs (Javascript)、消息队列和数据库(Mongodb / SQL Server)有基本了解。本文附带的代码库是使用 Nodejs 开发的,但这并不意味着此设计特定于 .net 或 nodejs。我们可以使用任何我们熟悉的语言。多种语言也可以共存。

我希望得到对本文的反馈。请随时分享您的评论,您也可以发送电子邮件至 shettyashwin@outlook.com。如果您喜欢这篇文章,请不要忘记评价它。

背景

让我们举个例子,以便更好地理解,然后与下面提供的架构设计进行比较。例如:我们有一个设备,它持续跟踪医院患者的心率和血压。心率每 50 秒发送一次,血压每 15 分钟发送一次。患者与医院的某个位置相关联。定期通过我们服务器上公开的 API 将患者数据发送到服务器。应用程序用户可以从我们的网站在线查看此详细信息,还可以监控实时仪表板。用户还可以搜索患者或查询任何特定详细信息。

在典型的客户端-服务器应用程序中(至少在大多数情况下),我们开发相互紧密关联的层。UI 层与外观层或业务层通信,业务层与数据访问层通信。在负载过重的情况下,我们设置一台新服务器,它包含应用程序的完整堆栈(数据库除外),并配有负载均衡器,根据传入的负载和请求进行分发。但是,我们所有的组件都需要相同数量的额外资源吗?

单体设计

在上图中,我遗漏了一些 API 扩展,但这能传达我想分享的想法。

我想要强调的另一件事是,单一技术是否拥有我们所需的所有优势?Java 可能在库方面有其优缺点,.net 或我们可能正在使用的任何其他技术也是如此。此外,未来可能出现一种技术来取代两者。

其他方法

现在,让我们提高一些性能要求,将心率的发送间隔从 50 秒改为 30 秒,血压间隔从 15 分钟改为 5 分钟。现在,我们接收/处理的数据量已经翻倍。但用户交互仍然相同。您真的认为增加更多节点是经济高效的吗?还要考虑如何在持续接收心率和血压的情况下部署新更新。丢失如此关键的数据可能会造成生死攸关的局面。

现在,让我们看看一种完全不同但更可靠、更具成本效益的设计和处理此类问题的方式。

微服务设计

如果您查看上图,关键的区别在于每个模块都是一个独立的负责处理特定需求的服务。它们与其他模块没有紧密耦合。让我们开始详细了解每个部分,以理解它的好处。

服务器代码

如果您查看第二张图,我们已经独立创建了每个服务。每个服务都可以独立运行在其进程线程中。它可以独立托管、部署和维护。这使我们能够将服务维护为更小的代码块。您可以根据您的产品需求和使用情况来决定微服务的粒度。您将从 这里 获得更好的理解。

微服务图中的第二点也是最重要的一点是使用消息队列连接您的服务。引入消息队列将有助于在需要时即插即用新节点。在典型的单体设计中,当请求进来时,数据将自上而下和自下而上流动。但通过引入队列,我们将改变这种典型流程。

在队列方法中,最顶层将接收来自 UI 的数据,并对其进行验证。如果接收到的数据有效,则将其转换为序列化消息并推送到消息队列。让我们在这里举两个例子。

心率数据

医院的物联网设备开始向我们的 API 发送信息。该请求首先经过身份验证,并验证数据参数。现在,在成功验证后,数据将被发布到消息队列。订阅此消息的接收者将接收此信息并开始进一步处理。在我们假设的场景中,我们从物联网接收到的数据量翻倍了。为了处理这种情况,我们将增加处理此信息的订阅者数量。我们完全可以决定是否需要一台新服务器来处理这些数据,或者这是否可以由托管应用程序的服务器处理。

如果您正在使用 RabbitMQ,消息发布逻辑可以在 这里 找到。

不要忘记使用消息队列中的确认机制。如果任何进程被杀死或出错,这将非常有用。同样,由于消息已发布到消息队列,如果我们正在重新启动订阅者或更新订阅者中的逻辑,消息将被存入队列并在订阅者恢复运行后进行处理。

显示患者列表的请求

 

在典型的(无队列)数据请求中,我们获取参数并调用底层层在单个线程中获取所需数据。但在这种特定方法中,我们不会调用底层层,而是在数据验证后,将消息推送到消息队列中。当我们这样做时,首先浮现在我们脑海中的问题是,由于这是一个 GET 请求,我们需要在响应请求的用户时返回。为了实现这一点,我们将使用现有的 RPC 机制。

为了实现请求-响应,我们需要确保遵循 4 个步骤。

步骤 1

我们设置消息的 `reply_to` 属性。此处提到的名称将由订阅者用于返回生成的数据作为响应。

第二步

设置唯一的 `correlation id`。此消息的订阅者将使用 `correlation id` 将数据发送回。一旦收到数据,就需要验证此 ID,以确保收到的数据是请求的数据。

步骤 3

消息的订阅者应确保在处理完数据后,消息会发送回 `reply_to` 中指定的队列,并附带 `correlation id`。

步骤 4

消息发布后(根据步骤 1),发布者需要订阅 `reply_to` 队列以获取响应。收到消息时,需要将收到的消息中的 `correlation id` 与发布消息时生成的 ID 进行验证。

如果您看到更多请求进来,可以增加订阅者数量。

相应的代码/逻辑可以在 这里 找到。

注意:我共享了 RabbitMQ 网站上的代码链接,因为这些示例非常有帮助,而且有多种语言可供选择。

数据库

在此方法中,我考虑了 MongoDB 数据库。根据您所处的情况,您可以选择所需的实例数量以及适合您产品的数据库(关系型/非关系型)。在上图中,关键区别在于它们属于同一个集群,可以处理重负载。每当执行 CRUD 操作时,它们都会跨所有实例同步。

在服务器上配置 MongoDB (Windows)

这里 下载最新版的 MongoDB 安装程序。为了方便访问,我建议您将 MongoDB 安装的 bin 文件夹路径配置到 Path 变量(Windows 环境变量)中。这将使您能够快速访问 MongoDB 命令/可执行文件。在环境变量中配置 MongoDB 路径后,在一个父文件夹中创建三个文件夹:data, log, config

Data Folder:将存储 MongoDB 实例的数据文件。

Log Folder:将存储 MongoDB 实例的日志文件。

Config Folder:将存储运行 MongoDB 实例的配置文件。

Mongod.conf 文件详情

dbpath = [Data 文件夹路径,当前实例的数据文件将在此创建]

port = [MongoDB 将监听的端口]

logpath = [Log 文件路径,当前实例的日志文件将在此创建]

如果您尝试在同一服务器上创建 MongoDB 集群(用于研发),则创建父文件夹的多个副本。请确保在所有配置文件中更新 Log 和 Data 文件夹路径。此外,所有配置文件都应具有不同的端口号。

要在批处理模式下运行 MongoDB 实例,您需要执行以下命令。

mongod --config [Physical path of Mongod.config file created in Config folder]

在集群中配置 MongoDB 既快速又简单。

第一步

首先,您需要在数据库配置文件中定义下副本集名称。集群中的所有数据库配置都需要设置此项。

replSet=[NameOfReplication]

第二步:

配置 MongoDB 服务器列表

如果您已将 mongodb bin 配置到 Path 环境变量,请打开命令提示符并键入 *mongo*,然后按 Enter。这将自动连接到运行在 27017 端口上的默认 MongoDB 实例。要获取集群信息,请键入 *rs.config()* 或 *rs.status()*,然后按 Enter。MongoDB shell 将列出集群详细信息(如果已配置)。现在,要添加第一个集群信息,您可以使用 *rs.initiate()*。

rs.initiate({
   "_id" : "[NameOfReplication]",
   "version" : 1,
   "members" : [
      {
         "_id" : 1,
         "host" : "[MongoDBServerName:Port]"
      }
   ]
})

对于第二个或附加服务器,您可以使用 *rs.add("")*。

rs.add("[MongoDBServerName:port]")

现在您拥有了一个完整的集群 MongoDB 实例。

对于 Elasticsearch 集成,您可以使用消息队列来获取数据更改更新,然后相应地更新 Elasticsearch。

关注点

微服务:- https://martinfowler.com.cn/articles/microservices.html

Rabbit MQ 教程:https://rabbitmq.cn/getstarted.html

MongoDB:https://mongodb.ac.cn/ & 培训 https://university.mongodb.com/

 

 

© . All rights reserved.