4000字教你如何创建一个基于Redis构建微服务的反应式架构

如何使用 Redis 的特性来生成反应式数据流?
Redis 是我遇到的最强大、最通用的技术之一。可悲的是,大多数人只知道它是因为它是一个很好的缓存解决方案。我们需要解决这个问题。
特别是,我想向您展示您可以创建一个以 Redis 作为主要组件的反应式架构。这是一个巨大的优势,特别是如果您由于其他要求(即好的 ol'cache)已经将它作为基础架构的一部分。
您使用 Redis 与我将在此处描述的功能进行交互的方式取决于您,老实说,此时任何选项都与下一个选项一样有效。我倾向于使用 Node.js,但这就是我,你可以自由使用最适合你的东西。

构建反应式架构
这里首先要了解什么是反应式架构,为什么我们要构建一个而不是采用更传统的方法?
简而言之,反应式架构是在满足所有前提条件的那一刻开始执行每一位逻辑的架构——我想我应该在“简单”这个词周围加上引号。
让我换一种说法:当您需要在特定事件发生后触发逻辑时,您有两种选择:


第二部分是面向对象编程中观察者模式的关键。观察到的对象让对其内部状态感兴趣的每个人都知道,它实际上已更新。
我们在这里尝试做的是将相同的 OOP 模式外推到架构级设计中。因此,与其在我们的程序中加入一些逻辑,我说的是一旦正确的事件发生,就会触发服务的功能。
这是分发和扩展平台的最有效方式,因为:


反应式平台本质上是异步的,因此任何尝试使用它们的客户端应用程序也需要适应相同的范例。外部 API 可能是通过 HTTP 实现的 REST,但这并不意味着您将获得作为响应的答案,相反,您将获得一个200 OK响应,这意味着您的请求已被接收。为了让您的应用程序获得实际结果,它必须订阅将包含此类响应的特定事件。
请记住这一点,否则,您将花费很长时间来调试为什么没有得到您想要的响应。

那我们需要什么?
撇开这一点,我们需要什么才能使我们的平台/架构成为反应式平台/架构?它不是 ReactJS,这是肯定的。我们需要一个消息代理,它可以集中多个服务之间的消息分发。
有了可以充当代理的东西,我们需要确保我们的代码的编写方式可以通过让代理知道它在哪里以及它需要的事件类型来订阅某些事件。
之后,将向我们的服务发送通知,并触发我们的逻辑。
听起来很简单吧?那是因为它就是!

那么 Redis 是如何考虑的呢?
Redis 不仅仅是一个键值内存存储,事实上,它有 3 个我喜欢它的特性,允许我根据不同的预期行为创建反应式架构。
这3个特点是:


所有这些功能都允许您以一种或另一种方式与您的流程进行通信,并且根据您所追求的行为类型,您可能想要解决其中一个或全部。
让我们快速浏览一些示例,让您了解使用什么以及何时使用。
经典的基于事件的消息传递
最简单的例子是每个微服务都在等待某事发生。要触发的事件,该事件可能来自外部,即系统的用户或客户端。


看上图,把中央的红管看成是Redis的Pub/Sub或者Blocking list,这是一个更可靠的Pub/Sub的自定义实现。
流程从 #1 开始,由“客户端应用程序”提交请求,并在 9 点结束,“客户端应用程序”收到有关响应的通知。其余的部分?我不在乎,客户端应用程序也不应该在乎。
这是这种范式的优点之一,该架构成为客户端的黑匣子。单个请求可以触发数百个事件或仅触发一个,行为将是相同的:一旦响应准备就绪,它将被传递给客户端。而不是客户端知道需要多长时间或多久需要检查它是否准备好。这些都不重要。
请记住以下注意事项:


现在让我们看看如果您的事件触发取决于某些时间会发生什么。

基于时间的触发
反应式架构的另一个常见行为是能够在预定义的时间过去后触发某些事件。例如:在发现数据问题 10 分钟后触发警报。或者等待 30 分钟,然后触发 IoT 设备已停止发送数据的警报。
这些通常是与现实世界的限制相关的行为,需要一些时间来解决,或者甚至可以通过“稍等片刻”并重新开始倒计时来解决自己的问题(例如连接不可靠的物联网设备) )。
对于这种情况,架构保持不变,唯一的区别是中央通信集线器肯定使用来自 Redis的键空间通知。
您会看到,您需要了解有关 Redis 的两个主要功能才能实现这一目标:

  1. 设置键值对时,您可以选择以秒为单位定义 TTL(生存时间)。这就变成了倒计时,一旦达到 0,密钥将自动销毁。
  2. 当您订阅一个键空间时(这也适用于 pub/sub,但我们在这里没有使用它),您可以使用模式进行订阅。换句话说,您可以订阅“last_connection_time_of_device*”,而不是订阅键“last_connection_time_of_device100002”的事件。然后,一旦发生某些事情,创建的每个与该模式匹配的密钥都会通知您。

考虑到这两点,您可以创建订阅这些特定键的服务,并在它们被删除后(即事件被触发时)做出反应。同时,您让生产者不断更新密钥,这也会重置 TTL 计时器。

因此,如果您正在跟踪设备上次发送其心跳的时间,则可以像我上面显示的那样为每个设备设置一个密钥,并在每次获得新的心跳时更新该密钥。一旦 TTL 结束,这意味着您在配置的时间内没有收到新的心跳。您订阅的进程将只接收密钥名称,因此如果您只需要设备的 ID,您可以像我展示的那样构造您的密钥,并解析名称以捕获所需的信息。


影键技术
另一方面,如果您在该键中保存了一个复杂的结构并且需要它,则必须稍微更改此方法。这是因为当 TTL 到期时,密钥将被删除,从而删除其中的数据,因此您无法真正检索它。这时,您可以使用一种称为“阴影键”的技术。
影子键本质上是用于触发事件的键,但这实际上是在隐藏包含您需要的数据的实际键。回到我们的例子,假设生产者每次收到心跳都会更新 2 个键:

因此,当您收到过期通知时,您将从过期密钥 (last_connection_time_of_device100002) 中获取 ID 并使用它来读取第二个密钥的内容。

然后,如果需要,您也可以继续删除其他密钥,或者将其保留在那里,无论对您的用例是否有效。
这里需要考虑的唯一警告是,如果您在集群模式下配置了 Redis,则密钥空间通知不会在整个集群中传播。

这意味着您必须确保您的消费者连接到每个节点。其中一些通知会丢失,否则没有人会收到它们。这是这种技术的唯一缺点,但在您花几天时间调试异步逻辑之前了解它很重要(去过那里,做过)。
如您所见,两种情况下的复杂性都降低到只需确保您订阅正确的事件或分发渠道。

例如,如果您要尝试使用普通 SQL 数据库执行此操作,则必须围绕代码创建大量逻辑,以有效确定何时输入新数据或何时删除一条信息。
相反,这里的所有复杂性都由 Redis 抽象出来,您需要担心的只是编写业务逻辑。那对我来说就是黄金。


原文:https://www.jdon.com/57489

展开阅读全文

页面更新:2024-04-20

标签:反应式   架构   密钥   客户端   逻辑   消息   发生   事件   通知   时间

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top