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

mvc5 网站开发之美 pdf汽车之家官网首页

mvc5 网站开发之美 pdf,汽车之家官网首页,网页站点的用途,服装设计师怎么学1、Redis实现限流方案的核心原理&#xff1a; redis实现限流的核心原理在于redis 的key 过期时间&#xff0c;当我们设置一个key到redis中时&#xff0c;会将key设置上过期时间&#xff0c;这里的实现是采用lua脚本来实现原子性的。2、准备 引入相关依赖 <dependency>…

1、Redis实现限流方案的核心原理:

redis实现限流的核心原理在于redis 的key 过期时间,当我们设置一个key到redis中时,会将key设置上过期时间,这里的实现是采用lua脚本来实现原子性的。

2、准备

  • 引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.23</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>3.1.5</version>
</dependency>
<dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>2.2</version>
</dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>
<dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.25.1</version>
</dependency>
  • 添加redis配置信息
server:port: 6650nosql:redis:host: XXX.XXX.XXX.XXXport: 6379password:database: 0spring:cache:type: redisredis:host: ${nosql.redis.host}port: ${nosql.redis.port}password: ${nosql.redis.password}lettuce:pool:enabled: truemax-active: 8max-idle: 8min-idle: 0max-wait: 1000
  • 配置redis Conf
@Configuration
public class RedisConfig {/*** 序列化* jackson2JsonRedisSerializer** @param redisConnectionFactory 复述,连接工厂* @return {@link RedisTemplate}<{@link Object}, {@link Object}>*/@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setKeySerializer(jackson2JsonRedisSerializer);template.setHashKeySerializer(jackson2JsonRedisSerializer);template.setValueSerializer(jackson2JsonRedisSerializer);template.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}/*** 加载lua脚本* @return {@link DefaultRedisScript}<{@link Long}>*/@Beanpublic DefaultRedisScript<Long> limitScript() {DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("luaFile/rateLimit.lua")));redisScript.setResultType(Long.class);return redisScript;}}

3、限流实现

  1. 编写核心lua脚本
local key = KEYS[1]
-- 取出key对应的统计,判断统计是否比限制大,如果比限制大,直接返回当前值
local count = tonumber(ARGV[1])
local time = tonumber(ARGV[2])
local current = redis.call('get', key)
if current and tonumber(current) > count thenreturn tonumber(current)
end
--如果不比限制大,进行++,重新设置时间
current = redis.call('incr', key)
if tonumber(current) == 1 thenredis.call('expire', key, time)
end
return tonumber(current)
  1. 编写注解 limiter
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimiter {/*** 限流key*/String key() default "rate_limit:";/*** 限流时间,单位秒*/int time() default 60;/*** 限流次数*/int count() default 100;/*** 限流类型*/LimitType limitType() default LimitType.DEFAULT;
}
  1. 增加注解类型
public enum LimitType {/*** 默认策略全局限流*/DEFAULT,/*** 根据请求者IP进行限流*/IP
}
  1. 添加IPUtils
@Slf4j
public class IpUtils {/**ip的长度值*/private static final int IP_LEN = 15;/** 使用代理时,多IP分隔符*/private static final String SPLIT_STR = ",";/*** 获取IP地址* <p>* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址*/public static String getIpAddr(HttpServletRequest request) {String ip = null;try {ip = request.getHeader("x-forwarded-for");if (StrUtil.isBlank(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (StrUtil.isBlank(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (StrUtil.isBlank(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");}if (StrUtil.isBlank(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (StrUtil.isBlank(ip)) {ip = request.getRemoteAddr();}} catch (Exception e) {log.error("IPUtils ERROR ", e);}//使用代理,则获取第一个IP地址if (!StrUtil.isBlank(ip) && ip.length() > IP_LEN) {if (ip.indexOf(SPLIT_STR) > 0) {ip = ip.substring(0, ip.indexOf(SPLIT_STR));}}return ip;}
}
  1. 核心处理类
@Aspect
@Component
@Slf4j
public class RateLimiterAspect {@Resourceprivate RedisTemplate<Object, Object> redisTemplate;@Resourceprivate RedisScript<Long> limitScript;@Before("@annotation(rateLimiter)")public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable {String key = rateLimiter.key();int time = rateLimiter.time();int count = rateLimiter.count();String combineKey = getCombineKey(rateLimiter, point);List<Object> keys = Collections.singletonList(combineKey);try {Long number = redisTemplate.execute(limitScript, keys, count, time);if (number == null || number.intValue() > count) {throw new ServiceException("访问过于频繁,请稍候再试");}log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), key);} catch (ServiceException e) {throw e;} catch (Exception e) {throw new RuntimeException("服务器限流异常,请稍候再试");}}public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {StringBuilder stringBuilder = new StringBuilder(rateLimiter.key());if (rateLimiter.limitType() == LimitType.IP) {stringBuilder.append(IpUtils.getIpAddr(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest())).append("-");}MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();Class<?> targetClass = method.getDeclaringClass();stringBuilder.append(targetClass.getName()).append("-").append(method.getName());return stringBuilder.toString();}
}

到此,我们就可以利用注解,对请求方法进行限流了

http://www.yayakq.cn/news/701071/

相关文章:

  • 什么网站可以做装修效果图的手机端设计
  • 视频网站怎么建设no.7 wordpress 破解
  • 南山老品牌网站建设wordpress getfooter
  • 横沥镇网站建设公司成为网站有哪些网址?
  • 坪山网站的建设什么行业适合做网站推广
  • 快彩网站开发怎样做废旧网站
  • jquery个人网站开发网站搭建心得体会
  • 网站建设三网合一指的是什么意思如何做网络推广公司
  • 手机访问网站跳wap制作网站的最新软件
  • 国外做游戏的视频网站哪个公司的app开发公司
  • 网站建设税收编码做网站基础
  • 做现货黄金的金融网站dw怎样建设网站
  • 成品网站源码在线观看网络营销发展的新趋势
  • 杭州市做网站网站开发工程师获奖
  • 南京500元做网站多终端响应式网站
  • 五泉山网页设计宣传网站制作影视自助建站官网
  • 包头做网站公司哪家好男女做暧视频网站免费
  • 用ps做个人网站界面wordpress站点维护
  • 网站的关键词排名郑州艾特软件 网站建设
  • 徐州的网站设计wordpress上传的gif图不会动
  • 做网站是用什么软件电商网站运维怎么做
  • 介绍网站ppt该怎么做网站流量一直下降
  • 品牌网站策划书免费app制作网站
  • 江苏建设行政主管部门网站wordpress 群晖设置
  • ps网站设计与制作什么样算网站需要备案
  • 做校招的网站有哪些佛山做网站优化公司
  • 怎么查看一个网站的建设地区服务类网站开发
  • 大疆网站建设网上购物商城首页
  • 网站建设和推广的完整话术家如何网站
  • 清远市住房和城乡建设局网站网站前置审批项 教育