我正面临一个用例,我需要跟踪重复请求,这些请求是通过后端的REST API调用触发的。每个请求都写入数据库,因此不需要再次处理重复请求。
重复请求可能位于同一个VM下的不同线程中,也可能完全位于不同的VM下。问题是如何识别这些重复请求?
我能想到的方法:
如果请求的结果已经是完成的,即使我们处理请求,每次在处理传入请求之前签入数据库。如果是,则忽略请求处理它。
对于已处理的每个传入请求,将其以序列化格式存储在映射到值的数据库中(类似于哈希索引)。然后,对于每个传入请求,检查数据库是否已经有该请求。如果是,则忽略其他处理它。
但两者都需要db read操作。我能做得更好吗?
答案 0 :(得分:0)
在这种情况下,我认为你不能避免数据库操作。
您的第一种方法是特定于项目的方法。 第二种方法也不能应用于任何代码,因为可能存在用户发送多个相等请求并且它们都必须被处理的情况。
更通用的方法是服务器发出令牌,然后在客户端向服务器发出的每个请求中传递令牌。处理每个请求的服务器检查请求中传递的令牌是否已被某人使用。如果没有,请在DB中标记已使用此令牌并处理请求。否则忽略请求或发送错误。 客户端可以通过查询服务器方法获取此类令牌(在这种情况下,不需要检查此特定请求的任何令牌),或者可选地,服务器可以在每次响应查询时发送新令牌。
如果随机生成令牌,还应确保偶尔清理过时的令牌,以避免在生成新数据库时发生数据库和冲突。 (见Birthday paradox)。
答案 1 :(得分:0)
“双提交”是Web开发的常见问题。使用标准形式,常见的习语是submit-redirect-get
,这可以避免很多问题。
我假设你使用javascript来发送请求到REST后端?防止一个用户复制请求的一种简单方法是使用javascript在点击后的一小段时间内禁用该按钮。
但是,如果您必须为多个用户阻止此操作,则高度依赖于您的模型和其他项目详细信息。