作者:微信小助手
发布时间:2024-07-02T07:54:27
前言
作为一名老码农,在开发后端Java业务系统,包括各种管理后台和小程序等。在这些项目中,我设计过单/多租户体系系统,对接过许多开放平台,也搞过消息中心这类较为复杂的应用,但幸运的是,我至今还没有遇到过线上系统由于代码崩溃导致资损的情况。这其中的原因有三点:一是业务系统本身并不复杂;二是我一直遵循某大厂代码规约,在开发过程中尽可能按规约编写代码;三是经过多年的开发经验积累,我成为了一名熟练工,掌握了一些实用的技巧。 啥是防抖 ❝ 所谓防抖,一是防用户手抖,二是防网络抖动。在Web系统中,表单提交是一个非常常见的功能,如果不加控制,容易因为用户的误操作或网络延迟导致同一请求被发送多次,进而生成重复的数据记录。要针对用户的误操作,前端通常会实现按钮的loading状态,阻止用户进行多次点击。而对于网络波动造成的请求重发问题,仅靠前端是不行的。为此,后端也应实施相应的防抖逻辑,确保在网络波动的情况下不会接收并处理同一请求多次。 一个理想的防抖组件或机制,我觉得应该具备以下特点: 思路解析 前面讲了那么多,我们已经知道接口的防抖是很有必要的了,但是在开发之前,我们需要捋清楚几个问题。 接口防抖也不是每个接口都需要加,一般需要加防抖的接口有这几类: 防抖也即防重复提交,那么如何确定两次接口就是重复的呢?首先,我们需要给这两次接口的调用加一个时间间隔,大于这个时间间隔的一定不是重复提交;其次,两次请求提交的参数比对,不一定要全部参数,选择标识性强的参数即可;最后,如果想做的更好一点,还可以加一个请求地址的对比。 分布式部署下如何做接口防抖? 有两个方案: 流程图如下: 流程图如下: ❝ 常见的分布式组件有Redis、Zookeeper等,但结合实际业务来看,一般都会选择Redis,因为Redis一般都是Web系统必备的组件,不需要额外搭建。 具体实现 现在有一个保存用户的接口 AddReq.java ❝ 目前数据库表中没有对userPhone字段做UK索引,这就会导致每调用一次add就会创建一个用户,即使userPhone相同。
哪一类接口需要防抖?
如何确定接口是重复的?
使用共享缓存
使用分布式锁
@PostMapping("/add")
@RequiresPermissions(value = "add")
@Log(methodDesc = "添加用户")
public ResponseEntity<String> add(@RequestBody AddReq addReq) {
return userService.add(addReq);
}package com.summo.demo.model.request;
import java.util.List;
import lombok.Data;
@Datapublic class AddReq {
/** * 用户名称 */ private String userName;
/** * 用户手机号 */ private String userPhone;
/** * 角色ID列表 */ private List<Long> roleIdList;}