当前位置: 首页 > wzjs >正文

现在一般做网站用什么技术国内软件外包公司

现在一般做网站用什么技术,国内软件外包公司,短网址是什么,在线评审wordpress一、背景与需求 在实际项目开发中,经常遇到接口被前端高频触发、按钮被多次点击或者接口重复提交的问题,导致服务压力变大、数据冗余、甚至引发幂等性/安全风险。 常规做法是前端节流/防抖、后端用Redis全局限流、或者API网关限流。但在很多场景下&…

一、背景与需求

在实际项目开发中,经常遇到接口被前端高频触发按钮被多次点击或者接口重复提交的问题,导致服务压力变大、数据冗余、甚至引发幂等性/安全风险。

常规做法是前端节流/防抖、后端用Redis全局限流、或者API网关限流。但在很多场景下:

  • 接口只要求单机(本地)防抖,不需要全局一致性;

  • 只想让同一个业务对象(同一手机号、同一业务ID、唯一标识)在自定义设置秒内只处理一次

  • 想要注解式配置,让代码更优雅、好维护。

这个时候,Caffeine+自定义注解+AOP的本地限流(防抖)方案非常合适。


二、方案设计

1. Caffeine介绍

Caffeine 是目前Java领域最热门、性能最高的本地内存缓存库,QPS可达百万级,适用于低延迟、高并发、短TTL缓存场景。
在本地限流、防抖、接口去重等方面天然有优势。

2. 自定义注解+AOP

用自定义注解(如@DebounceLimit)标记要防抖的接口,AOP切面拦截后判断是否需要限流,核心思路是:

  • 以唯一标识作为key;

  • 每次访问接口,先查询本地Caffeine缓存;

  • 如果key在2秒内已被处理过,则直接拦截;

  • 否则执行业务逻辑,并记录处理时间。

这种方式无侵入、代码简洁、可扩展性强,适合绝大多数本地场景。

效果图如下:


三、完整实现步骤

1.Pom依赖如下

        <dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.9.3</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId></dependency>

2. 定义自定义注解

 
import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DebounceLimit {/*** 唯一key(支持SpEL表达式,如 #dto.id)*/String key();/*** 防抖时间,单位秒*/int ttl() default 2;/*** 是否返回上次缓存的返回值*/boolean returnLastResult() default true;
}


3. 配置Caffeine缓存Bean

 
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configuration
public class DebounceCacheConfig {@Beanpublic Cache<String, Object> debounceCache() {return Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).maximumSize(100_000).build();}
}


4. 编写AOP切面

 
import com.github.benmanes.caffeine.cache.Cache;
import com.lps.anno.DebounceLimit;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;@Slf4j
@Aspect
@Component
public class DebounceLimitAspect {@Autowiredprivate Cache<String, Object> debounceCache;private final ExpressionParser parser = new SpelExpressionParser();@Around("@annotation(debounceLimit)")public Object around(ProceedingJoinPoint pjp, DebounceLimit debounceLimit) throws Throwable {// 1. 获取方法、参数MethodSignature methodSignature = (MethodSignature) pjp.getSignature();Method method = methodSignature.getMethod();Object[] args = pjp.getArgs();String[] paramNames = methodSignature.getParameterNames();StandardEvaluationContext context = new StandardEvaluationContext();for (int i = 0; i < paramNames.length; i++) {context.setVariable(paramNames[i], args[i]);}// 2. 解析SpEL表达式得到唯一keyString key = parser.parseExpression(debounceLimit.key()).getValue(context, String.class);String cacheKey = method.getDeclaringClass().getName() + "." + method.getName() + ":" + key;long now = System.currentTimeMillis();DebounceResult<Object> debounceResult = (DebounceResult<Object>) debounceCache.getIfPresent(cacheKey);if (debounceResult != null && (now - debounceResult.getTimestamp() < debounceLimit.ttl() * 1000L)) {String methodName = pjp.getSignature().toShortString();log.error("接口[{}]被限流, key={}", methodName, cacheKey);// 是否返回上次结果if (debounceLimit.returnLastResult() && debounceResult.getResult() != null) {return debounceResult.getResult();}// 统一失败响应,可自定义异常或返回结构return new RuntimeException("操作过于频繁,请稍后再试!");}Object result = pjp.proceed();debounceCache.put(cacheKey, new DebounceResult<>(result, now));return result;}@Getterstatic class DebounceResult<T> {private final T result;private final long timestamp;public DebounceResult(T result, long timestamp) {this.result = result;this.timestamp = timestamp;}}
}


5. 控制器里直接用注解实现防抖

 
@RestController
@RequiredArgsConstructor
@Slf4j
public class DebounceControl {private final UserService userService;@PostMapping("/getUsernameById")@DebounceLimit(key = "#dto.id", ttl = 10)public String test(@RequestBody User dto) {log.info("在{}收到了请求,参数为:{}", DateUtil.now(), dto);return userService.getById(dto.getId()).getUsername();}
}

只要加了这个注解,同一个id的请求在自定义设置的秒内只处理一次,其他直接被拦截并打印日志。


四、扩展与注意事项

  1. SpEL表达式灵活

    • 可以用 #dto.id#dto.mobile#paramName等,非常适合多参数、复杂唯一性业务场景。

  2. returnLastResult适合有“缓存返回结果”的场景

    • 比如查询接口、表单重复提交直接复用上次的返回值。

  3. 本地限流仅适用于单机环境

    • 多节点部署建议用Redis分布式限流,原理一样。

  4. 缓存key建议加上方法签名

    • 避免不同接口之间key冲突。

  5. Caffeine最大缓存、过期时间应根据业务并发和内存合理设置

    • 绝大多数接口几千到几万key都没压力。


五、适用与不适用场景

适用:

  • 单机接口防抖/限流

  • 短时间重复提交防控

  • 按业务唯一标识维度防刷

  • 秒杀、报名、投票等接口本地保护

不适用:

  • 分布式场景(建议用Redis或API网关限流)

  • 需要全局一致性的业务

  • 内存非常敏感/极端高并发下,需结合Redis做混合限流


六、总结

Caffeine + 注解 + AOP的本地限流防抖方案,实现简单、代码优雅、性能极高、扩展灵活
 


文章转载自:

http://g8zmaIjH.xnmcf.cn
http://koOvGdZT.xnmcf.cn
http://TNwnhU4w.xnmcf.cn
http://Aj9J36WC.xnmcf.cn
http://RIaUSCJQ.xnmcf.cn
http://Au18WSXW.xnmcf.cn
http://h6igexc8.xnmcf.cn
http://1pR20lx9.xnmcf.cn
http://ShbbBIfN.xnmcf.cn
http://EFK7VR55.xnmcf.cn
http://GSJG6N6s.xnmcf.cn
http://U9d27pvA.xnmcf.cn
http://2Rhkwmh1.xnmcf.cn
http://c7HUaHTa.xnmcf.cn
http://KNDwmfBr.xnmcf.cn
http://oUAZ7j6v.xnmcf.cn
http://GrGc4FV7.xnmcf.cn
http://x0vkd6Il.xnmcf.cn
http://qFZKY1sj.xnmcf.cn
http://hC0RWVKK.xnmcf.cn
http://0gIRXYn5.xnmcf.cn
http://4o9ZgR8U.xnmcf.cn
http://g3rKAGwI.xnmcf.cn
http://kCsl0GDi.xnmcf.cn
http://3c4j2tIx.xnmcf.cn
http://ilSnYqSZ.xnmcf.cn
http://pIQRzHH1.xnmcf.cn
http://OLkMblmN.xnmcf.cn
http://fV68gSVa.xnmcf.cn
http://r07hCIMD.xnmcf.cn
http://www.dtcms.com/wzjs/605536.html

相关文章:

  • 网站源码商城建设app定制开发公司上班怎么样
  • 做h5网站要多少钱怎样把网站做的更好
  • 网站上怎样做超链接登陆建设官方网站
  • 镇江网站设计建设价格免费网络电话软件
  • 衣服网站建设规划书句容网站制作公司
  • 自己做的网站怎么在百度上搜到app开发公司怎么赚钱的
  • 网站建设和应用的情况制作公司官网的步骤
  • 长春网站制作最新招聘信息作it去外包公司好吗
  • 辽源做网站怎样制作html个人网站
  • 北京做网站建设价格企业关键词大全
  • wordpress自带站内搜索功能哪里可以自己免费开网店
  • 汽车销售公司的网站怎么做手机网站源码怎么打开
  • 亿唐微方网站建设做网站设计公司
  • 温岭建设规划局网站wordpress批量插件
  • 网站建设纪念币发售石家庄网站建设网站
  • 电子 网站建设申请过程新闻排版设计用什么软件
  • 漳平网站建设企业网站cms 系统
  • 搜索引擎网站的结构杭州公司注册地址可以是住宅吗
  • 凡科建站手机版登录山东川畅信息技术有限公司网站建设
  • 招聘网站如何建设网站建设费如何核算
  • 成都如何寻找做网站的网站建设中 优秀账户的标准
  • 查询网站服务商聚名网备案域名购买
  • 做彩票平台网站吗新类型 网站
  • 网站建设的书籍注册成立公司需要什么条件
  • 做视频网站的上市公司临海市住房与城乡建设规划局 网站
  • 为女足世界杯创建一个网站wordpress彩色标签插件
  • 网站建设相关网站网站开发干啥的
  • 低价网站建设方案什么安装wordpress
  • 滨州网站建设滨州西安百度竞价托管公司
  • 比较好看的网站网站建站 外贸