Design patterns Microservice CQRS单独构建(写入)查询模型和读取模型
以下场景 每分钟从队列接收60000条消息。RESTAPI每分钟为来自这些消息的数据提供10次服务 我有一个带有事件源和CQR的微服务体系结构。因此,我的命令已经与查询部分分离。问题在于同步查询并查询它,而不是命令部分 每隔几分钟,使用Design patterns Microservice CQRS单独构建(写入)查询模型和读取模型,design-patterns,microservices,scaling,cqrs,event-sourcing,Design Patterns,Microservices,Scaling,Cqrs,Event Sourcing,以下场景 每分钟从队列接收60000条消息。RESTAPI每分钟为来自这些消息的数据提供10次服务 我有一个带有事件源和CQR的微服务体系结构。因此,我的命令已经与查询部分分离。问题在于同步查询并查询它,而不是命令部分 每隔几分钟,使用事件源模式将大约60000条命令作为事件发送和存储。通过CQRS,实际数据(不是事件)被同步到另一个服务,该服务将数据存储在数据库中。同时,数据每隔几分钟只读取十几次 换句话说。这一个服务接收60000个写操作,但只有十几个读操作 我真的很想遵循微服务的设计模式,
事件源
模式将大约60000条命令作为事件发送和存储。通过CQRS,实际数据(不是事件)被同步到另一个服务,该服务将数据存储在数据库中。同时,数据每隔几分钟只读取十几次
换句话说。这一个服务接收60000个写操作,但只有十几个读操作
我真的很想遵循微服务的设计模式,也就是每个服务一个数据库,但是由于扩展的原因,我认为在我的场景中这是不可行的。写入数据库比读取数据库需要更大的扩展
我看到了一个解决方案,但答案建议使用CQR,我已经实现了。以前有人告诉我要删除事件源,但这仍然让我有60000次写入和10次读取
我的体系结构应该是什么来独立扩展读写?我正在考虑创建两个独立的服务,但这将违反每个服务一个数据库的模式。要找到您问题的答案,您可能需要将微服务和CQR的思维过程结合起来 有两种观点可以帮助您思考这个问题:
因此,IMHO,如果您希望能够单独扩展,并且不希望写入和读取之间存在任何争用,那么两个独立的服务是最好的选择。假设 据我所知,问题在于您的写模型需要尽快反映读模型状态,因为您已经 每分钟仅读取10次,它们需要实时或接近实时地反映真实状态 问题 基于此假设,将此域拆分为2个微服务并使用CQR无法解决此问题。 为什么? 因为如果你有一个写微服务和读微服务,并且你更新了读微服务 对于从Write micro service发布的事件,您将遇到延迟问题。 这意味着您将有大约50-100毫秒(大部分时间)的最小延迟 延迟会更大) 直到读微服务数据库与写微服务数据库同步。 这是正常的,在使用分布式系统时需要考虑到这一点 使用队列的系统 基于此,将这部分域拆分为2个微服务并不是最好的方法(同样,这也是 基于我的假设,您需要几乎实时地读取微服务数据) 可能的解决方案 你能做什么? 在这里,您可以做几件事:
- 数据库部分 同样,如果您需要最新的数据,您可以使用诸如写数据库的只读复制之类的方法。 SQLServer提供了类似于这种开箱即用的功能。我在我的一个项目中使用它。这意味着 您将拥有另一个数据库,SQL server将在其中将您的数据复制到数据库级别上的另一个数据库 (这将比整个过程快得多,发布到队列并使用来自另一个微服务的消息)。 此数据库将与您的写数据库完全相同,并且是只读的。这样,您的10次读取操作将 几乎总是最新的,延迟非常低。您可以在此处从SQL Server了解此功能
- 后端的CQRS部分 当涉及到CQR时,您仍将继续使用它,并拥有2个微服务(写入和读取)。Write-micro服务将使用 主SQL Server实例和Read micro服务将使用主数据库的只读副本。牢记 此只读复制副本是一个单独的数据库,在单独的计算机上运行。因此,基于此,您将满足规则:“每个微服务一个数据库”。 当然,如果您使用的是Microsoft Sql Server,则此选项是可能的
- 数据库部分 在这种方法中,您将使用物化视图,它将作为主或写微服务数据库在同一数据库上进行读取。例如,如果使用PostgreSQL,则可以使用Marten()进行事件来源和存储。它适用于.NET,但我想其他语言也有其他解决方案。Marten的优点是 您可以生成物化视图(称为投影视图),这些视图在聚合/模型更改时立即生成。 这意味着,例如,如果您使用事件源更改了某个客户对象,您将发布一个偶数