360建筑网是什么网站数字媒体技术移动互联网开发

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

360建筑网是什么网站,数字媒体技术移动互联网开发,国际新闻最新消息今天新闻大事件 中方,云南城乡建设厅网站前言 为啥需要限制接口请求频率#xff1f;这个是因为防止接口一直被刷#xff0c;比如发送手机验证码的接口#xff0c;一直被刷的话#xff0c;费钱费资源的#xff0c;至少做点基本的防护工作。以下分别使用Redis和Nginx实现限制接口请求频率方案。 一、基于Redis实现…前言 为啥需要限制接口请求频率这个是因为防止接口一直被刷比如发送手机验证码的接口一直被刷的话费钱费资源的至少做点基本的防护工作。以下分别使用Redis和Nginx实现限制接口请求频率方案。 一、基于Redis实现接口限流 1.ZADD 命令 1用法ZADD key score_1 value_1 score_2 value_2 … 2作用将一个或多个成员元素及其分数值加入到有序集当中。某个成员已经是有序集的成员那么更新这个成员的分数值并通过重新插入这个成员元素来保证该成员在正确的位置上。分数值可以是整数值或双精度浮点数。 3返回值被成功添加的新成员的数量不包括那些被更新的、已经存在的成员。 4示例 redis ZADD runoobkey 1 redis (integer) 1 redis ZADD runoobkey 2 mongodb (integer) 1 redis ZADD runoobkey 3 mysql (integer) 1 redis ZADD runoobkey 3 mysql (integer) 0 redis ZADD runoobkey 4 mysql (integer) 0 redis ZRANGE runoobkey 0 10 WITHSCORES1) redis

  1. 1
  2. mongodb
  3. 2
  4. mysql
  5. 4 2.ZREM 命令 1用法ZREM key value_1 value_2 … 2作用移除有序集中的一个或多个成员不存在的成员将被忽略。 3返回值被成功添加的新成员的数量不包括那些被更新的、已经存在的成员。 4示例 redis ZRANGE runoobkey 0 10 WITHSCORES1) redis
  6. 1
  7. mongodb
  8. 2
  9. mysql
  10. 4redis ZREM mongodb (integer) 1redis ZRANGE runoobkey 0 10 WITHSCORES
  11. redis
  12. 1
  13. mysql
  14. 4 3.ZCARD 命令 1用法ZCARD key 2作用获取有序集合中成员的数量。 3返回值当key存在且是有序集类型时返回有序集的基数。 当key不存在时返回0 。 4示例 redis ZADD myzset 1 one (integer) 1 redis ZADD myzset 2 two (integer) 1 redis ZCARD myzset (integer) 2 4.ZREMRANGEBYSCORE 命令 1用法ZREMRANGEBYSCORE key min max 2作用移除有序集中指定分数区间内的所有成员。 3返回值被移除成员的数量。 4示例 redis ZRANGE salary 0 -1 WITHSCORES
  15. tom
  16. 2000
  17. peter
  18. 3500
  19. jack
  20. 5000redis ZREMRANGEBYSCORE salary 1500 3500 (integer) 2redis ZRANGE salary 0 -1 WITHSCORES
  21. jack
  22. 50005.具体实现 1新建一个过滤器如【/src/main/java/org/example/interceptor/RateLimiterInterceptor.java】 package org.example.interceptor;import cn.hutool.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.concurrent.TimeUnit;/*** 限流拦截器*/ Component public class RateLimiterInterceptor implements HandlerInterceptor {private static final String RATE_LIMITER_PREFIX Rate-Limiter:;private static final int LIMIT 10; // 限流阈值private static final int TIME_WINDOW 60; // 时间窗口单位为秒Autowiredprivate StringRedisTemplate stringRedisTemplate;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {response.setCharacterEncoding(utf-8);response.setContentType(application/json);String key RATE_LIMITER_PREFIX request.getRequestURI() : request.getRemoteAddr(); // Rate-Limiter:/api/sendCode:127.0.0.1long currentTime System.currentTimeMillis(); // 1703036748554long beforeTime currentTime - TIME_WINDOW * 1000; // 1703036748554 - 60000 1703036688554// Long removeNum stringRedisTemplate.opsForZSet().removeRangeByScore(K key, double min, double max); // 删除有序集合中分数在指定范围内的元素返回删除元素的数量stringRedisTemplate.opsForZSet().removeRangeByScore(key, 0, beforeTime); // 删除有序集合中60秒之前存进去的所有数据如// Long memberNum stringRedisTemplate.opsForZSet().size(K key); // 获取有序集合中元素的数量long count stringRedisTemplate.opsForZSet().size(key); // 3if (count LIMIT) {HashMapString, Object responseObj new HashMap();responseObj.put(code, HttpStatus.TOO_MANY_REQUESTS.value());responseObj.put(success, false);responseObj.put(msg, HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());JSONObject json new JSONObject(responseObj);response.getWriter().println(json);return false;} else {// Boolean addFlag stringRedisTemplate.opsForZSet().add(K var1, V var2, double var3); // 向有序集合中添加一个或多个元素并指定其分数stringRedisTemplate.opsForZSet().add(key, String.valueOf(currentTime), currentTime);// Boolean expireFlag stringRedisTemplate.expire(K key, long timeout, TimeUnit unit); // 对指定key的数据设置过期时间stringRedisTemplate.expire(key, TIME_WINDOW, TimeUnit.SECONDS);return true;}} }2在SpringMVC配置类中注入此过滤器如【/src/main/java/org/example/config/ResourceConfig.java】 package org.example.config;import org.example.interceptor.RateLimiterInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;Configuration public class ResourceConfig extends WebMvcConfigurationSupport {Autowiredprivate RateLimiterInterceptor rateLimiterInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(rateLimiterInterceptor).addPathPatterns(/abcd/api/sendCode);} }6.运行效果 // ~ 二、基于Nginx实现接口限流 1.在nginx.conf文件中新增限流配置 user nginx; worker_processes 1;error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;events {worker_connections 1024; }http {include /etc/nginx/mime.types;default_type application/octet-stream;log_format main \(remote_addr - \)remote_user [\(time_local] \)request \(status \)body_bytes_sent \(http_referer \)http_user_agent \(http_x_forwarded_for;access_log /var/log/nginx/access.log main;sendfile on;#tcp_nopush on;keepalive_timeout 65;#gzip on;include /etc/nginx/conf.d/*.conf;# 负载均衡upstream springboot {server xxx.xxx.xxx.xxx:8080;}# limit_req_zone \)binary_remote_addr zonelimit_zone:10m rate10r/s; # 定义了一个名为limit_zone的限流区域使用IP地址进行限流该区域的大小为10MB限流速率为10个请求每秒。limit_req_zone \(binary_remote_addr zonelimit_zone:10m rate10r/m; # 定义了一个名为limit_zone的限流区域使用IP地址进行限流该区域的大小为10MB限流速率为10个请求每分钟。# 80端口的服务server { listen 80;server_name xxx.xxx.xxx.xxx;location / {alias html;index index.html index.htm;try_files \)uri $uri/ /love/index.html;proxy_pass http://localhost;}location ^~ /love/ {root html/love;index index.html index.htm;proxy_pass http://localhost;}location ^~ /abcd/api/sendCode {# 在/xxx/api/sendCode接口的location中使用limit_req指令进行限流限流区域为limit_zone同时设置了一个瞬时突发流量为20个请求的阈值。# 这样当同一个IP地址在一秒钟内发送超过10个请求到此接口时Nginx会返回503错误码表示请求被限流了。# limit_req zonelimit_zone burst20;# 在/xxx/api/sendCode接口的location中使用limit_req指令进行限流限流区域为limit_zone同时设置了一个瞬时突发流量为5个请求的阈值。# 这样当同一个IP地址在一秒钟内发送超过10个请求到此接口时如果在一分钟内有超过10个请求则允许其中的5个请求通过nodelay表示不延迟响应即立即返回503错误码。limit_req zonelimit_zone burst5 nodelay;proxy_pass http://springboot;}} }2.运行效果 // ~