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

芜湖网站建设哪家好月亮花园wordpress

芜湖网站建设哪家好,月亮花园wordpress,网站查询网,seo外包资讯在上一节中,该接口已经接受过风控的处理,过滤掉了机器人脚本请求,剩下都是人为的下单请求。为了防止用户短时间内高频率点击抢课链接,海量请求造成服务器过载,这里使用接口限流算法。 先介绍下几种常用的接口限流策略…

在上一节中,该接口已经接受过风控的处理,过滤掉了机器人脚本请求,剩下都是人为的下单请求。为了防止用户短时间内高频率点击抢课链接,海量请求造成服务器过载,这里使用接口限流算法。

先介绍下几种常用的接口限流策略:
1.计数器算法(固定窗口)
计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。
此算法存在一个问题就是,在此周期快结束时,大量请求泳入请求,一直持续到下一周期开始一段时间后,这段时间的接口访问量大大超过服务器的负载,却小于每个周期的计数器最大值。
在这里插入图片描述

2.滑动窗口
滑动窗口算法是将时间周期分为N个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。尽可能地平滑过渡每一个小周期。
在这里插入图片描述
3、漏桶算法
漏桶算法是访问请求到达时直接放入漏桶,如当前容量已达到上限(限流值),则进行丢弃(触发限流策略)。漏桶以固定的速率进行释放访问请求(即请求通过),直到漏桶为空。
4.令牌桶算法
令牌桶算法是程序以r(r=时间周期/限流值)的速度向令牌桶中增加令牌,直到令牌桶满,请求到达时向令牌桶请求令牌,如获取到令牌则通过请求,否则触发限流策略

本文常用简单有效的固定窗口策略进行接口限流,具体流程如下:
1.自定义接口限流注解

package com.example.seckilldemo.config;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {int second();int maxCount();boolean needLogin() default true;
}

2.将接口限流做成拦截器,写入WebConfig中在回掉方法中扫描到有限流注解的接口进行接口限流

package com.example.seckilldemo.config;import com.example.seckilldemo.pojo.User;
import com.example.seckilldemo.service.UserService;
import com.example.seckilldemo.utils.CookieUtil;
import com.example.seckilldemo.vo.RespBean;
import com.example.seckilldemo.vo.RespBeanEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.thymeleaf.util.StringUtils;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;@Component
public class AccessLimitInterceptor implements HandlerInterceptor {@Autowiredprivate UserService itUserService;@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (handler instanceof HandlerMethod) {User tUser = getUser(request, response);UserContext.setUser(tUser);HandlerMethod hm = (HandlerMethod) handler;//判断有没有接口限流的注解AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);if (accessLimit == null) {return true;}int second = accessLimit.second();int maxCount = accessLimit.maxCount();boolean needLogin = accessLimit.needLogin();String key = request.getRequestURI();if (needLogin) {if (tUser == null) {render(response, RespBeanEnum.SESSION_ERROR);}key += ":" + tUser.getId();}//接口限流使用计数器算法ValueOperations valueOperations = redisTemplate.opsForValue();Integer count = (Integer) valueOperations.get(key);if (count == null) {valueOperations.set(key, 1, second, TimeUnit.SECONDS);} else if (count < maxCount) {valueOperations.increment(key);} else {render(response, RespBeanEnum.ACCESS_LIMIT_REACHED);return false;}}return true;}private void render(HttpServletResponse response, RespBeanEnum respBeanEnum) throws IOException {response.setCharacterEncoding("UTF-8");response.setContentType("application/json");PrintWriter printWriter = response.getWriter();RespBean bean = RespBean.error(respBeanEnum);printWriter.write(new ObjectMapper().writeValueAsString(bean));printWriter.flush();printWriter.close();}private User getUser(HttpServletRequest request, HttpServletResponse response) {String userTicket = CookieUtil.getCookieValue(request, "userTicket");if (StringUtils.isEmpty(userTicket)) {return null;}return itUserService.getUserByCookie(userTicket, request, response);}
}

这里还有个问题是虽然自增是原子操作,但是获取计数器并不是,改进使用lua脚本配合计数器实现接口限流原子性操作

@Component
public class AccessLimitInterceptor implements HandlerInterceptor {@Autowiredprivate UserService itUserService;@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (handler instanceof HandlerMethod) {User tUser = getUser(request, response);UserContext.setUser(tUser);HandlerMethod hm = (HandlerMethod) handler;//判断有没有接口限流的注解AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);if (accessLimit != null) {int second = accessLimit.second();int maxCount = accessLimit.maxCount();boolean needLogin = accessLimit.needLogin();String key = request.getRequestURI();if (needLogin) {if (tUser == null) {render(response, RespBeanEnum.SESSION_ERROR);return false;}key += ":" + tUser.getId();}// 使用Lua脚本确保操作的原子性String luaScript = "local currentCount = redis.call('get', KEYS[1]) " +"if currentCount and tonumber(currentCount) < tonumber(ARGV[1]) then " +"  redis.call('incr', KEYS[1]) " +"  if tonumber(currentCount) == 0 then " +"    redis.call('expire', KEYS[1], ARGV[2]) " +"  end " +"  return 0 " +"end " +"return 1";DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(luaScript, Boolean.class);Boolean isLimited = (Boolean) redisTemplate.execute(redisScript, Collections.singletonList(key), maxCount, second);if (isLimited) {render(response, RespBeanEnum.ACCESS_LIMIT_REACHED);return false;}}}return true;}private void render(HttpServletResponse response, RespBeanEnum respBeanEnum) throws IOException {response.setCharacterEncoding("UTF-8");response.setContentType("application/json");PrintWriter printWriter = response.getWriter();RespBean bean = RespBean.error(respBeanEnum);printWriter.write(new ObjectMapper().writeValueAsString(bean));printWriter.flush();printWriter.close();}private User getUser(HttpServletRequest request, HttpServletResponse response){String userTicket = CookieUtil.getCookieValue(request, "userTicket");if (StringUtils.isEmpty(userTicket)) {return null;}return itUserService.getUserByCookie(userTicket, request, response);}
}
http://www.yayakq.cn/news/959770/

相关文章:

  • 网站支付平台是怎么做的昆明云南微网站
  • 网站备案拍照背景图wordpress 短网址插件
  • 为什么企业建设银行网站打不开做守望先锋h的网站
  • 大连手机自适应网站制作公司网站优化案例
  • 门户网站建设工作流程天水市住房和城乡建设局网站
  • 免费推广网站大全下载宁波网站建设详细内容
  • 网站架构建设方案网站建设的计划
  • 网站开发接单群网页代理 最干净
  • 一个ip地址做多个网站广西建设网官网住房和城乡厅官网官方网
  • 广州做网站公司电话网站备案是域名备案还是空间备案
  • 做货代还有什么网站可以加人网站管理员怎样管理员权限
  • 昌吉州建设局网站建网站公司耳机套
  • 长沙品质企业建站服务电话提高百度快速排名
  • 太原有哪些做网站的公司建筑焊工证查询网站官方网
  • 网站ip地址大全网页制作素材库属不属于信息管理
  • 没有网站怎样做外贸wordpress js 页脚
  • 抢注域名网站东莞公司注册地址可以是住宅吗
  • 网站建设与维护ppt模板下载网站集约化建设规范
  • 山西大川建设有限公司网站留学网站建设
  • 温州设计集团网站建设ps做好切片后怎么做网站
  • 网站权重传递时代网站管理系统怎么做网站
  • 做网站_没内容以就业为导向的高职计算机专业网站设计
  • wordpress网站移植陕西外贸英文网站建设
  • 公司网站开发完成后怎么办百度做公司网站
  • 广告网站制作报价wordpress themes.php
  • 哪些企业网站使用水墨风格零售商城
  • 网站建设经济可行性公众号怎么做链接
  • 网站开发相关书籍资料淄博网站推广那家好
  • 网站做浮动边框asp代码上海企业登记在线平台
  • 佳木斯建设网站网站 版式