我正在使用 Azure 中的无服务器架构来试验事件溯源/cqrs 模式。
我为 Event Store 和 Azure Event Grid 选择了 Cosmos DB 文档数据库,用于将事件分派给非规范化程序。
当事件存储在 Cosmos DB 中时,如何实现事件仅可靠地传递到事件网格一次?我的意思是,如果传递到事件网格失败,它不应该存储在事件存储中,不是吗?
我正在使用 Azure 中的无服务器架构来试验事件溯源/cqrs 模式。
我为 Event Store 和 Azure Event Grid 选择了 Cosmos DB 文档数据库,用于将事件分派给非规范化程序。
当事件存储在 Cosmos DB 中时,如何实现事件仅可靠地传递到事件网格一次?我的意思是,如果传递到事件网格失败,它不应该存储在事件存储中,不是吗?
查看 Cosmos Db 更改源。为 db 中的每个更改内置事件引发器/队列。您可以注册一个或多个侦听器/处理程序。即 Azure 函数。
这可能正是您所要求的。
有人建议您可以直接进入 cosmos db 并在 changefeed 的背面附加 eventgrid。
你不能,但无论如何你都不应该这样做。也许有一些非常复杂的方法使用分布式事务,但它们不可扩展。您不能以原子方式存储和发布事件,因为您正在写入具有不同事务边界的两个不同持久性。您可以拥有一个同步的 CQRS 单体,但前提是您对事件持久性和 readmodels 持久性使用相同的技术。
在 CQRS 中,应用程序分为写入/命令和读取/查询方面(这个长视频可能会有所帮助)。您正在尝试将这两个部分统一为一个部分,如果您愿意,可以降级。相反,您应该使用不同的模型将它们分开处理(请参阅领域驱动设计)。
写入端不应依赖于读取端的结果。这意味着,在事件存储持久化事件之后,写入端就完成了。此外,写入端应包含完成其工作所需的所有数据,即根据业务规则发出事件。
如果您在写入和读取部分有不同的技术,那么您的读取端应该与写入端分离,也就是说,它应该在单独的线程/进程中运行。
一种方法是让一个线程/进程侦听附加到事件存储,获取新事件然后将它们发布到事件网格。如果此过程失败或重新启动,它应该从停止的地方恢复。我不知道 CosmosDB 是否支持这一点,但 MongoDB(也是一个文档数据库)rslog
可以tail
在几毫秒内获取新事件。