JQueue:实现发件箱模式的库

每日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。

JQueue 是一个有助于确保服务以一致和原子方式更新和发布的库。了解如何在您的 EBA 中使用它。

在微服务或任何其他基于事件的架构中,在某些用例中,服务可能需要我们对其自己的本地数据库进行更改并发布事件。然后该事件被其他服务使用。为了拥有一个一致的软件系统,这两个动作必须原子地执行。两个动作都需要成功完成,或者都不需要完成。不应该有其他方法。

解决此问题的一种优雅方法是使用发件箱模式。这通过使用通常称为发件箱表的数据库表(如果您的服务使用关系数据库)来存储事件来工作。在这种情况下,您可以将事件的插入 SQL 语句包含到用例本地事务中。另一个运行器可以定期检查发件箱表是否不为空,并通过将事件发布到消息代理来处理事件。

我已经实现了一个名为 JQueue 的 Java 库,它使这种模式的实现更加容易。JQueue 使用关系数据库表实现 FIFO 数据结构,因此,如果您的服务的数据库是关系数据库,它就可以工作。

JQueue 有两个模块,push 模块和 runner 模块。要将事件(或任务)推送到队列中,您可以执行以下操作:

JQueueRunner.runner(/* a JDBC DataSource */)

请注意,作为参数,您必须传递本地事务中当前正在使用的数据源或连接。在这种情况下,如果您的事务已提交,则推送也将被提交。如果有任何失败,一切都将被回滚。您推入队列的事件或任务可以是任何文本。

然后,要使用队列中的事件或任务,您必须编写如下内容:

JTxQueue.queue(/*a JDBC Data Source or a JDBC Connection */)
.push(
“{“type””: “”job_type1″”

上面的代码将循环处理队列中的所有条目,直到它为空。它将读取队列数据并调用您必须提供的 Job 接口的实例,以便对数据执行任何您需要的操作。这可能是将消息推送到消息代理或只是调用任何其他外部服务 API。您可以使用任何调度程序库(例如 Quartz)以所需的频率调度 JQueue 运行器,以保持队列为空。

runner 使用“select for update skip locked ” SQL 语句,这是一些关系数据库已经实现的一种新功能,用于(除其他外)在关系表中实现队列。这是目前使 JQueue 在 PostgreSQL v9.5+ 和 MySQL 8.0+ 中工作的原因之一(JQueue 中对 Oracle 和 MS SQL 的支持即将推出,因为它们都支持跳过锁定功能)。

现在让我们展示一些如何在本地事务中推送事件的示例。假设您的服务创建了用户,当发生这种情况时,您需要发布NewUserEvent。如果您的服务使用普通 JDBC,您可以执行以下操作:
Connection conn = connection();
try {
conn.setAutoCommit(false);
//your business logic first
final PreparedStatement st = conn.prepareStatement(
“”insert into user(id

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年9月19日
下一篇 2022年9月19日

相关推荐