如何在 Cosmos DB 中实现发件箱模式
How to implement outbox pattern in Cosmos DB
我希望在 Cosmos DB 中实现对发件箱模式的支持。
但是,Cosmos DB 似乎不支持跨集合的事务。
那我该怎么做呢?
我一直在考虑几种实现方法:
使用服务总线事务
在 Service bus transaction scope 内,发送消息(尚未提交),执行 Cosmos DB 更新,如果成功,我们将提交服务总线事务以使消息可供订阅者使用。
使用触发器在发件箱集合中插入行
当 inserts/updates 发生时,我们使用 Cosmos DB 触发器将相应的消息插入发件箱 table,从那时起,一切照常进行。
使用触发器执行 azure 函数
创建Azure functions as Cosmos DB triggers。我几乎喜欢这个,但直接向服务总线发送消息会好得多。
使用数据泵
添加两个字段 UpdateTimestamp
和 OutboxMessageTimestamp
。当记录更新时 UpdateTimestamp
.
某些进程会查找这两个不匹配的记录,并为每个创建通知消息并将其转发到相应的队列或主题。
当然,然后它会更新第二个时间戳以使它们匹配。
关于如何做到这一点的其他想法?
通常,您将东西存储在您的 cosmos db 集合中。然后你有更改提要将这些更改发送给一些观察者(假设是 azure 函数)。然后你的 azure 函数可以做任何事情:将它放入其他消费者的队列中,保存到另一个不同投影的集合中,等等......在你的 azure 函数中你应该为与函数运行时无关的故障实现你的死信队列(例如, 由于 id 冲突,写入另一个集合失败)
[更新]
让我再补充一点作为对您评论的回应。
根据我的经验,在分布式系统中以原子方式做事归结为:
- 始终按照相同的顺序做事
- 使第二步有效(确保您可以重复多次以获得相同的结果)
- 一旦第一步成功 - 重复第二步直到成功
因此,如果您想发送有关保存到 cosmos db 中的内容的电子邮件,您可以:
- 在 cosmos db 中保存记录
- 让 azure 函数监听变化提要
- 收到插入的文档后 > 发送电子邮件(更强大的解决方案实际上会将其放入队列中,一些专门的消费者从中发送电子邮件)
另一种方法是将初始命令(保存记录)放入队列,然后有 2 个消费者(一个用于保存,一个用于发送电子邮件)但是你有一个订购问题(如果这对你很重要) .
我希望在 Cosmos DB 中实现对发件箱模式的支持。
但是,Cosmos DB 似乎不支持跨集合的事务。
那我该怎么做呢?
我一直在考虑几种实现方法:
使用服务总线事务
在 Service bus transaction scope 内,发送消息(尚未提交),执行 Cosmos DB 更新,如果成功,我们将提交服务总线事务以使消息可供订阅者使用。
使用触发器在发件箱集合中插入行
当 inserts/updates 发生时,我们使用 Cosmos DB 触发器将相应的消息插入发件箱 table,从那时起,一切照常进行。
使用触发器执行 azure 函数
创建Azure functions as Cosmos DB triggers。我几乎喜欢这个,但直接向服务总线发送消息会好得多。
使用数据泵
添加两个字段 UpdateTimestamp
和 OutboxMessageTimestamp
。当记录更新时 UpdateTimestamp
.
某些进程会查找这两个不匹配的记录,并为每个创建通知消息并将其转发到相应的队列或主题。
当然,然后它会更新第二个时间戳以使它们匹配。
关于如何做到这一点的其他想法?
通常,您将东西存储在您的 cosmos db 集合中。然后你有更改提要将这些更改发送给一些观察者(假设是 azure 函数)。然后你的 azure 函数可以做任何事情:将它放入其他消费者的队列中,保存到另一个不同投影的集合中,等等......在你的 azure 函数中你应该为与函数运行时无关的故障实现你的死信队列(例如, 由于 id 冲突,写入另一个集合失败)
[更新]
让我再补充一点作为对您评论的回应。 根据我的经验,在分布式系统中以原子方式做事归结为:
- 始终按照相同的顺序做事
- 使第二步有效(确保您可以重复多次以获得相同的结果)
- 一旦第一步成功 - 重复第二步直到成功
因此,如果您想发送有关保存到 cosmos db 中的内容的电子邮件,您可以:
- 在 cosmos db 中保存记录
- 让 azure 函数监听变化提要
- 收到插入的文档后 > 发送电子邮件(更强大的解决方案实际上会将其放入队列中,一些专门的消费者从中发送电子邮件)
另一种方法是将初始命令(保存记录)放入队列,然后有 2 个消费者(一个用于保存,一个用于发送电子邮件)但是你有一个订购问题(如果这对你很重要) .