在微服务架构中,我们通常有两种方式来传达2个微服务。假设服务A需要从服务B获取信息。第一个选项是远程调用,通常通过HTTPS同步,因此服务A查询由服务B托管的API。
第二种选择是采用事件驱动的体系结构,其中服务A可以以异步方式由服务A发布和使用。使用此模型,服务A可以使用来自服务B的事件的信息更新其自己的数据库,并且所有查询都在此数据库中本地进行。这种方法具有更好的微服务解耦的优点,因为开发直到操作。但它带来了与数据复制相关的一些缺点。
第一个是磁盘空间的高消耗,因为相同的数据可以驻留在需要它的微服务的数据库中。但在我看来,第二个是最糟糕的:如果服务B无法按照需要快速处理其订阅,则数据可能会变得陈旧,或者在服务B创建的同时它无法用于服务A,给定最终模型的一致性。
假设我们将Kafka用作事件中心,其主题配置为使用7天的数据保留。当服务B发布状态时,服务A保持同步。两周后,部署了一个新服务C,并且需要使用服务B拥有的所有信息来丰富其数据库。自从最古老的事件消失以来,我们只能从卡夫卡主题中获取部分信息。我的问题是我们可以用什么模式来实现这个微服务的数据库丰富(除了要求服务B将其所有当前状态重新发布到事件中心)。
有两种选择:
您的担忧是正确的,但同时微服务方法是给予和接受。您会以每个服务的单个数据库为代价获得松耦合。微服务架构没有正确的答案,实际上取决于你想要实现的目标。
根据CAP定理,您必须在一致性和可用性之间进行折衷,并且在大多数情况下,我们最终会保持一致性。如果您的服务A与B不一致,那么它最终将会以可用性为代价进行权衡。
关于微服务的另一个问题是你只保留来自其他服务的数据的参考,并且来自其他服务的实际数据可能非常有限,但绝对不多。而且,只有复制数据才能使您的服务独立并自动化,如果即使在复制数据后仍然无法实现任何数据,那么也没有意义。例如您的送货服务将具有订单转换的完整历史记录,但您的预订服务仅具有最新的订单状态(例如在运输途中,在船上等)。用户进入预订并显示订单的当前状态。但是,如果用户点击详细信息,您将从运输微服务获得所有订单转换历史记录。现在,在某些时候,您的送货服务会关闭,您的用户会检查您的状态 - 至少当前订单状态,即使您无法显示详细信息,因为订单状态在预订服务中被复制。
关于在后期加入系统的新服务,事件源是您用于这些场景的模式。它的复杂模式,但它会将您新添加的服务带到您希望它们所处的状态。您基本上将所有事件保存在事件存储中并重播它们以获得系统的当前状态并使用这些事件预先填充服务C数据库。