防止跨多个服务器重复 POST API 调用

Posted

技术标签:

【中文标题】防止跨多个服务器重复 POST API 调用【英文标题】:Prevent duplicate POST API calls across multiple servers 【发布时间】:2019-03-05 22:50:10 【问题描述】:

假设我有一个 SPA 应用程序来管理具有以下结构的用户详细信息(姓名、年龄等):

SPA my-api-servcie.com VIP [my-api-server-1.com, my-api-server-2.com]

API 使用 SpringBoot、Java、Spring JDBC、oracle 12c 构建

我想强制名称是唯一的。但是,我无法控制数据库架构,也无法向名称列添加唯一约束。无论如何,我确实实施了以下预防措施:

前端级别 验证以防止重名 停留全屏微调器以防止意外点击 API 级别 验证以防止重名

了解上述所有情况后,其中一位应用程序用户成功发送了 2 个 POST 请求,这两个请求均成功通过了上述所有验证。

调用看起来像这样,每个请求需要几毫秒才能完成:

POST my-api-server-1.com/user name:"Sam" at 15-JUN-18 02.11.20.000000000 PM
POST my-api-server-2.com/user name:"Sam" at 15-JUN-18 02.11.23.000000000 PM 

首先这两个请求都成功了,即使它们相隔近 2 秒,这似乎很奇怪。所以从技术上讲,第二次调用不应该通过 API 级别的验证。这种行为的原因是什么?是否有一些短期兑现 JDBC 或 Oracle 层?

第二,除了添加数据库约束之外,我还可以采取哪些其他预防措施?

我可以使用同步方法,但这会导致一些性能后果。

【问题讨论】:

根据用户名同步访问 如果您在服务器上使用,这将起作用。但是,在此我使用多个服务器 但是您可以使用另一个集中式数据库来同步仅访问。或者使用单独的集中服务仅进行用户注册。您还可以使用 Hazelcast 等跨集群同步 java 结构。作为最后的手段,使用表锁定。 【参考方案1】:

在您的情况下同步是不可行的,因为您明确声明您正在使用两个应用程序服务器。在两个不同 VM 中运行的同步方法显然在这两个 VM 之间不同步。

此外,我不知道您实现的确切细节(也许您可以分享您的 application.properties 的匿名版本),但很可能您启用了 Hibernate 缓存。

这些缓存完全透明,这意味着当您的应用程序查询一个实体时,该实体很可能是从缓存而不是数据库提供的。在您的情况下,您正在使用两个应用程序服务器,每个应用程序服务器都使用自己的数据库缓存。

【讨论】:

是的,你是对的,在这种情况下,同步并不能解决我的问题。我正在使用 Spring JDBC 。在我的情况下没有休眠。 好的,我错过了那一点。

以上是关于防止跨多个服务器重复 POST API 调用的主要内容,如果未能解决你的问题,请参考以下文章

如何防止在 PHP 中重复提交表单(跨多个窗口进行保护)?

如何设计API接口,请求接口时需要进行身份验证,防止第三方随意调用接口?

如何设计API接口,请求接口时需要进行身份验证,防止第三方随意调用接口?

如何防止方法跨多个线程运行?

从 C# 向 URL 发送 POST 请求 [重复]

POST 请求 Fetch API 防止重定向