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

0716网站建设如何提高自己在百度的排名

0716网站建设,如何提高自己在百度的排名,试用型网站怎么做,网站功能建设描述书一,概述 日常开发中会有一个常见的需求,需要限制接口在单位时间内的访问次数,比如说某个免费的接口限制单个IP一分钟内只能访问5次。该怎么实现呢,通常大家都会想到用redis,确实通过redis可以实现这个功能&#xff0c…

一,概述

日常开发中会有一个常见的需求,需要限制接口在单位时间内的访问次数,比如说某个免费的接口限制单个IP一分钟内只能访问5次。该怎么实现呢,通常大家都会想到用redis,确实通过redis可以实现这个功能,下面实现一下。

二,常见错误

固定时间窗口

有人设计了一个在每分钟内只允许访问1000次的限流方案,如下图01:00s-02:00s之间只允许访问1000次。这种设计的问题在于,请求可能在01:59s-02:00s之间被请求1000次,02:00s-02:01s之间被请求了1000次,这种情况下01:59s-02:01s间隔0.02s之间被请求2000次,很显然这种设计是错误的。

三, 实现

1,基于滑动时间窗口

在指定的时间窗口内次数是累积的,超过阈值,都会限制。

2,流程如下

3,代码实现

前提:pom文件引入redis,Spring AOP等

(1)添加注解RequestLimit
package com.xxx.demo.aspect;import java.lang.annotation.*;/*** 接口访问频率注解,默认一分钟只能访问10次*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLimit {// 限制时间 单位:秒(默认值:一分钟)long period() default 60;// 允许请求的次数(默认值:10次)long count() default 10;
}
(2)添加切面实现注解的限制访问逻辑
package com.xxx.demo.aspect;import com.xgd.demo.commons.ErrorCode;
import com.xgd.demo.handler.BusinessException;
import com.xgd.demo.util.IpUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.concurrent.TimeUnit;/*** @date 2024/11/8 上午8:43*/
@Aspect
@Component
@Log4j2
public class RequestLimitAspect {@AutowiredRedisTemplate redisTemplate;@Pointcut("@annotation(requestLimit)")public void controllerAspect(RequestLimit requestLimit) {}@Around("controllerAspect(requestLimit)")public Object doAround(ProceedingJoinPoint joinPoint, RequestLimit requestLimit) throws Throwable {// 从注解中获取限制次数和窗口时间long period = requestLimit.period();long limitCount = requestLimit.count();// 请求ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();assert attributes != null;HttpServletRequest request = attributes.getRequest();String ip = IpUtil.getIpFromRequest(request);String uri = request.getRequestURI();//设置客户端访问的keyString key = "req_limit_".concat(uri).concat(ip);ZSetOperations zSetOperations = redisTemplate.opsForZSet();// 添加当前时间戳,分数为当前时间戳long currentMs = System.currentTimeMillis();zSetOperations.add(key, currentMs, currentMs);// 设置窗口时间作为过期时间redisTemplate.expire(key, period, TimeUnit.SECONDS);// 移除掉不在窗口里的数据zSetOperations.removeRangeByScore(key, 0, currentMs - period * 1000);// 查询窗口内已经访问过的次数Long count = zSetOperations.zCard(key);if (count > limitCount) {log.error("接口拦截:{} 请求超过限制频率【{}次/{}s】,IP为{}", uri, limitCount, period, ip);throw new BusinessException(ErrorCode.REQUEST_LIMITED.getCode(), ErrorCode.REQUEST_LIMITED.getMessage());}// 继续执行请求return  joinPoint.proceed();}
}

上面里面请求被拦截,是抛出了一个自定义的业务异常,大家可以根据自己的情况自己定义。

(3)同时附上上面中引用到自定义工具类
package com.xxx.demo.util;import jakarta.servlet.http.HttpServletRequest;
import java.util.Objects;/*** @date 2024/11/8 上午9:06*/
public class IpUtil {private static final String X_FORWARDED_FOR_HEADER = "X-Forwarded-For";private static final String X_REAL_IP_HEADER = "X-Real-IP";/*** 从请求中获取IP** @return IP;当获取不到时,返回null*/public static String getIpFromRequest(HttpServletRequest request ) {return getRealIp(request);}/*** 获取请求的真实IP,优先级从高到低为:<br/>* 1.从请求头X-Forwarded-For中获取ip,并且只获取第一个ip(从左到右) <br/>* 2.从请求头X-Real-IP中获取ip <br/>* 3.使用{@link HttpServletRequest#getRemoteAddr()}方法获取ip** @param request 请求对象,必须不能为null* @return ip*/private static String getRealIp(HttpServletRequest request) {Objects.requireNonNull(request, "request must be not null");String ip = request.getHeader(X_FORWARDED_FOR_HEADER);if (ip != null && !ip.isBlank()) {int delimiterIndex = ip.indexOf(',');if (delimiterIndex != -1) {// 如果存在多个ip,则取第一个ipip = ip.substring(0, delimiterIndex);}return ip;}ip = request.getHeader(X_REAL_IP_HEADER);if (ip != null && !ip.isBlank()) {return ip;} else {return request.getRemoteAddr();}}
}
(4)使用注解

这里限制为10秒内只允许访问3次,超过就抛出异常

(5)访问测试

前3次访问,接口正常访问

后面的访问,返回自定义异常的结果

如果对你有帮助,记得点赞关注哟!

http://www.dinnco.com/news/83941.html

相关文章:

  • 比较好的能组数学卷的网站做教案的360建站官网
  • 淄博网站建设团队搜索引擎优化百度百科
  • 武汉设计网站公司百度注册网站
  • 蒙阴做网站百度网站优化公司
  • 施工企业管理费厦门网站seo哪家好
  • 自己做网站给自己淘宝引流快刷网站
  • 网站建设 山东关键词排名优化网站
  • 网站建设费用高如何在百度发视频推广
  • 网站开发一般用哪种语言网络营销首先要
  • 怎样搭建属于自己的网站uc浏览网页版进入
  • 深圳网站建设app开发国际最新新闻热点事件
  • 做网站的技术要求高吗谷歌广告代理商
  • 如何做适合手机访问的网站百度推广客户端下载安装
  • 网站的域名怎么起如何编写一个网站
  • 北京网站建设兴田德润电话多少请输入搜索关键词
  • 深圳h5网站建设南宁推广公司
  • 网站建设案例实录软文素材
  • 用dw做网站毕业设计小程序开发公司排行榜
  • 新闻发稿计划怎么写windows优化大师破解版
  • 有什么可以下载软件的网站网站怎么优化排名的方法
  • 软件开发公司排行灰色seo关键词排名
  • wordpress 星 评分免费的seo
  • 用织梦软件如何做网站谷歌三件套一键安装
  • 公司网站开发步骤排名优化课程
  • 珠海响应式网站建设太原seo排名收费
  • wordpress怎么上传pdf最新seo网站优化教程
  • 天津网站制作公司电话百度开放云平台
  • 2017国外优秀网站设计长沙网络公司排名
  • 做网站用什么浏览器建站软件
  • 网站权重是什么意思网络推广员一个月多少钱