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

台州网站优化方案wordpress社交媒体优化

台州网站优化方案,wordpress社交媒体优化,专业的网站建设,深圳网站设计优刻在上一节中,该接口已经接受过风控的处理,过滤掉了机器人脚本请求,剩下都是人为的下单请求。为了防止用户短时间内高频率点击抢课链接,海量请求造成服务器过载,这里使用接口限流算法。 先介绍下几种常用的接口限流策略…

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

先介绍下几种常用的接口限流策略:
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/359207/

相关文章:

  • wordpress修改手机端幻灯片seo平台优化服务
  • 网站没有设置关键词wordpress ldap登陆
  • 主要的电子商务网站有哪些门户网站制作方法
  • 无人机网站建设上海自适应网站
  • 建网站需要什么网站开发人员上级主管
  • 北京网站模板可以自己做课程的网站
  • 用php做网站需要什么软件哈尔滨建设投资集团
  • aspcms网站源码网站建设策划 优帮云
  • 网站定制公司哪家最权威淘宝做个网站多少钱
  • 北京 企业建网站网站做等保二级收费多少
  • php建站程序网站开发里的输入
  • 局网站建设方案项目经理岗位职责
  • 网站如何注销网站建设属于无形资产
  • 集团网站策划方案免费php源码网
  • 濮阳公司网站建设企业青海seo技术培训
  • 做设计灵感的网站门户网站 建设 如何写
  • 高校网站建设的重要性wordpress 热门文章调用
  • 中国建设银行金华分行网站猫咪多用户wordpress
  • 网站设计建设方案建设官方网站需要那些人员
  • 梦幻建站网大学生网络营销策划方案书
  • python怎么搭建网站登封网站开发
  • 各大网站的软文怎么做注册城乡规划师值钱吗
  • 电子商务网站建设与管理答案网络推广公司哪家做得好
  • 如何做地方网站在建项目查询在哪里查
  • adsl 网站服务器创可贴在线设计网站
  • 网站 如何做用户统计合肥建网站要多少钱
  • 东莞的网站建设公司哪家好电商网站开发人员配置
  • 企业网站建设电话简约的网站设计界面
  • 建设项目网站免费网页游戏平台
  • 升级的网站显示什么北京网站设计合理刻