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

sketch网站花边怎么做西安专业网络推广平台

sketch网站花边怎么做,西安专业网络推广平台,辽宁网络推广,广告设计公司公司简介模板前言 Spring Cloud Gateway自带RequestRateLimiterGatewayFilterFactory限流方案,可基于Redis和RedisRateLimiter实现默认算法为令牌桶的请求限流。作为自带的该限流方案,其可与Spring生态的其它各项组件无缝集成,并且自身实现也相对完善/好用…

前言


    Spring Cloud Gateway自带RequestRateLimiterGatewayFilterFactory限流方案,可基于Redis和RedisRateLimiter实现默认算法为令牌桶的请求限流。作为自带的该限流方案,其可与Spring生态的其它各项组件无缝集成,并且自身实现也相对完善/好用,因此在没有特殊/复杂需求的情况下,该方案是实现基础限流的首选。
 
 

依赖


    在pom.xml文件中添加以下依赖。

<!--  Spring Boot Redis响应式起步依赖:用于实现请求限流  -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<!--  Spring Cloud网关起步依赖  -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

    继承&改造UsernamePasswordAuthenticationToken类以创建免密授权的鉴权类,该类会置null密码以逃脱密码校验。此外该类还可限定免密授权的处理器不会作用在其它授权模式上,因此其功能虽然完全可以使用UsernamePasswordAuthenticationToken代替,但其存在依然是不可省略的。

/*** @Author: 说淑人* @Date: 2025/5/8 21:45* @Description: 免密鉴权令牌类*/
public static class PasswordLessAuthenticationToken extends UsernamePasswordAuthenticationToken {private static final long serialVersionUID = -2798549339574220892L;public PasswordLessAuthenticationToken(Object principal) {// ---- credentials即为密码,为null表示不进行校验。super(principal, null);setAuthenticated(false);}public PasswordLessAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) {super(principal, null, authorities);}}

    实现AuthenticationProvider接口以创建免密授权的实际处理器。

/*** @Author: 说淑人* @Date: 2025/5/8 19:38* @Description: 免密鉴权供应者类*/
@Component
public class PasswordLessAuthenticationProvider implements AuthenticationProvider {private final UserDetailsService userDetailsService;public PasswordLessAuthenticationProvider(UserDetailsService userDetailsService) {this.userDetailsService = userDetailsService;}@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {// ---- 获取用户名,并调用我们实现的userDetailsService.loadUserByUsername(username)String username = (String) authentication.getPrincipal();UserDetails user = userDetailsService.loadUserByUsername(username);// ---- 如果用户不存在,按框架逻辑抛出原样异常以统一格式。if (user == null) {throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");}return new PasswordLessAuthenticationToken(user, user.getAuthorities());}@Overridepublic boolean supports(Class<?> authentication) {// ---- 该方法用于限定PasswordLessAuthenticationProvider只对// PasswordLessAuthenticationToken生效,这个可以避免// PasswordLessAuthenticationProvider作用于其它授权模式,而这会导致混乱。return PasswordLessAuthenticationToken.class.isAssignableFrom(authentication);}}

 
 

配置


    在application.yml文件中添加以下Redis与Gateway配置。

# ---- Spring Config
spring:# ---- Redis Configredis:host: 127.0.0.1port: 6379# ---- Gateway Configgateway:routes:# ---- 转发的服务。- id: world-biz-manageuri: lb://world-biz-managepredicates:- Path=/api/manage/**# ---- 添加RequestRateLimiter过滤器实现限流。因为过滤器是注册在具体服# 务下的,因此也只会对当前服务进行限流。filters:- name: RequestRateLimiterargs:# ---- 键解析器:定义限流数据键的生成规则,常用的生成规则有基于用# 户/IP/接口,而这里使用IP进行区分,即各IP限流数据是独立的。key-resolver: "#{@ipKeyResolver}"# ---- 每秒生成15个令牌,因此在令牌桶无令牌的情况下,一个IP每秒# 最多请求15次。redis-rate-limiter.replenishRate: 15# ---- 令牌桶中最多保存30个令牌,可支持单个IP最多30个请求/秒的流# 量高发。redis-rate-limiter.burstCapacity: 30# ---- 一次请求消耗一个令牌。redis-rate-limiter.requestedTokens: 1

    创建WebConfig(名称自定)类,用于内部创建/注册IP键解析器实例。

package com.ssr.world.frame.gateway.tool.config.web;import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;/*** @Author: 说淑人* @Date: 2025/4/22 22:39* @Description: 网络配置类*/
@Configuration
public class WebConfig {/*** IP键解析器** @return IP键解析器*/@Bean// ---- 你没看错,没有public。KeyResolver ipKeyResolver() {// ---- 以IP地址作为限流键的区分标志,即每个IP都有自己独立的令牌桶。return exchange -> Mono.just(// ---- 此处也可以获取其它参数作为限流键的区分表示,例如:// 头信息中携带的用户ID// 请求的接口// ---- 将上述参数混合使用也是不错的做法。exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());}}

 
 

启动&测试


# ---- 为了方便测试,我们暂时修改令牌的生成/存储上限为1/1。
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 1

    使用Postman进行连续快速地多次调用后返回以下内容,表示请求被限流:

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c1b593acd672465bb9cb74f1dd24bda1.png
    Redis数据结构如下所示。注意!由于限流数据键每秒都会更新/删除,所以想看到的话需要频繁请求接口以保持限流状态。
在这里插入图片描述
 
 

自定义回应


    Spring Cloud Gateway通过返回429的异常状态来表示限流异常/情况,但显然这种行为并无法兼容进异常的统一返回格式,因此此处会展示自定义限流异常回应信息的完整流程…这通过自定义限流过滤器的方式实现:
    创建WebRequestRateLimiterGatewayFilterFactory类并重写apply(Config config)方法以自定义限流回应的内容/格式。

import com.alibaba.fastjson2.JSONObject;
import com.ssr.world.tool.toft.model.bo.result.ResultBox;
import com.ssr.world.tool.toft.model.eo.web.WebResultEnum;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;@Component
public class WebRequestRateLimiterGatewayFilterFactory extends RequestRateLimiterGatewayFilterFactory {// ---- defaultKeyResolver会因为多实例而出现无法注入的情况,可通过// 在ipKeyResolver()方法上添加@Primary注解的方式处理。public WebRequestRateLimiterGatewayFilterFactory(RateLimiter defaultRateLimiter, KeyResolver defaultKeyResolver) {super(defaultRateLimiter, defaultKeyResolver);}@Overridepublic GatewayFilter apply(Config config) {// ---- 获取健解析器/速率限制器。KeyResolver resolver = config.getKeyResolver() != null ? config.getKeyResolver() : getDefaultKeyResolver();RateLimiter<Object> limiter = config.getRateLimiter() != null ? config.getRateLimiter() : getDefaultRateLimiter();return (exchange, chain) -> resolver.resolve(exchange).flatMap(key -> {String routeId = config.getRouteId();if (routeId == null) {Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);assert route != null;routeId = route.getId();}return limiter.isAllowed(routeId, key).flatMap(response -> {// ---- 继承所有的头信息。for (Map.Entry<String, String> header : response.getHeaders().entrySet()) {exchange.getResponse().getHeaders().add(header.getKey(), header.getValue());}// ---- 如果未被限流,直接返回。if (response.isAllowed()) {return chain.filter(exchange);}// ---- 如果被限流了,重置回应体。ServerHttpResponse httpResponse = exchange.getResponse();// ---- 重设状态/内容类型/内容长度(皆可选)。httpResponse.setStatusCode(HttpStatus.OK);httpResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);httpResponse.getHeaders().setContentLength(REQUEST_TOO_QUICKLY_BYTES.length);// ---- 重设回应体。Map<String, Object> map = new HashMap<>();map.put("code", "自定义错误码");map.put("message", "请求频率过高,请稍后重试...");map.put("data", "自定义数据");map.put("success", false);// ---- 回应内容是固定的,因此可以bytes直接在static中预加载,这能一定程度提升性能。byte[] bytes = JSONObject.toJSONString(map).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = httpResponse.bufferFactory().wrap(bytes);return httpResponse.writeWith(Mono.just(buffer));});});}}

    修改application.yml文件中指定的限流过滤器为自定义的限流过滤器。

filters:# ---- 将原本的RequestRateLimiter改为自定义的WebRequestRateLimiter,即略去名称尾部的GatewayFilterFactory部分。- name: WebRequestRateLimiterargs:key-resolver: "#{@ipKeyResolver}"redis-rate-limiter.replenishRate: 1redis-rate-limiter.burstCapacity: 1redis-rate-limiter.requestedTokens: 1

    启动测试。
在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/wzjs/240208.html

相关文章:

  • 做公司网站的步骤百度一下 你就知道官网
  • 手机网站建设推广方案接单平台
  • 单页网站如何制作每日新闻简报
  • 福州婚庆网站建设哪个公司比较专业营销技巧培训ppt
  • 网站开发意义更厉害的病毒2024
  • 淘宝网站建设需要哪些技术如何做免费网络推广
  • 织梦网站修改教程视频教程seo搜索引擎优化哪家好
  • 做虚拟币网站需要什么手续企业如何进行品牌推广
  • 简易的网站制作最好用的搜索引擎排名
  • 石家庄网站建设seo优化营销百度指数批量
  • 页眉做的好的网站重庆seo公司怎么样
  • 打字建站宝网站检测中心
  • 淘客做的领券网站网络营销总结及体会
  • 学做网站从零开始百度网页
  • 公司网站制作导航惊艳的网站设计
  • 宝安设计网站建设百度排行
  • 十个app制作网站搜索引擎优化网页
  • 哪些网站是做批发的怎么给公司做网站推广
  • 温州做微网站设计市场调研模板
  • 制作网站怎么做导航栏seo网站排名优化案例
  • 女人能做网站开发吗广告营销包括哪些方面
  • 做设计必知网站阳东网站seo
  • 医院网站怎么做优化排名百度惠生活商家入驻
  • 沧州建设局网站什么是seo是什么意思
  • 上海宝山区做网站的个人网站该怎么打广告
  • 顺德移动端网站建设青岛网站建设微动力
  • 中韩双语网站制作价格怎样精准搜索关键词
  • 可信网站认证必须做引流软件有哪些
  • 关于加强网站建设与管理的通知百度爱采购推广一个月多少钱
  • 地和网站建设seo引擎优化专员