package com.bolt.gateway.config; import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * 路由限流配置 * * @author arch_group */ @Configuration public class RateLimiterConfiguration implements KeyResolver{ /** * 自定义限流标志的key,多个维度可以从这里入手 * exchange对象中获取服务ID、请求信息,用户信息等 */ @Bean(value = "remoteAddrKeyResolver") public KeyResolver remoteAddrKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()); } @Override public Mono<String> resolve(ServerWebExchange exchange) { return null; } }
时间: 2024-04-14 18:31:11 浏览: 167
这是一个用于配置路由限流的类。在这个类中,定义了一个名为`remoteAddrKeyResolver`的Bean,用于自定义限流的标志key。在这个示例中,使用`exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()`来获取请求的远程地址,作为限流的标志key。
同时,这个类实现了`KeyResolver`接口,并重写了`resolve`方法。`resolve`方法用于根据请求获取限流的标志,这里返回了一个空值,你可以根据实际需求进行处理。
这个类的作用是配合Spring Cloud Gateway进行路由限流配置。通过自定义的限流标志key,可以实现按不同维度进行限流,例如按服务ID、请求信息、用户信息等。如果你还有其他问题,请继续提问。
相关问题
package com.bolt.gateway.config; import com.bolt.gateway.handler.HystrixFallbackHandler; import com.bolt.gateway.props.AuthProperties; import com.bolt.gateway.props.RouteProperties; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.cors.reactive.CorsUtils; import org.springframework.web.filter.reactive.HiddenHttpMethodFilter; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono; /** * 路由配置信息 * * @author arch_group */ @Slf4j @Configuration @AllArgsConstructor @EnableConfigurationProperties({RouteProperties.class, AuthProperties.class}) public class RouterFunctionConfiguration { /** * 这里为支持的请求头,如果有自定义的header字段请自己添加 */ private static final String ALLOWED_HEADERS = "x-requested-with, zkpt-ks-auth, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, username, client"; private static final String ALLOWED_METHODS = "*"; private static final String ALLOWED_ORIGIN = "*"; private static final String ALLOWED_EXPOSE = "*"; private static final String MAX_AGE = "18000L"; private final HystrixFallbackHandler hystrixFallbackHandler; @Bean public WebFilter corsFilter() { return (ServerWebExchange ctx, WebFilterChain chain) -> { ServerHttpRequest request = ctx.getRequest(); if (CorsUtils.isCorsRequest(request)) { ServerHttpResponse response = ctx.getResponse(); HttpHeaders headers = response.getHeaders(); headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS); headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS); headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN); headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE); headers.add("Access-Control-Max-Age", MAX_AGE); headers.add("Access-Control-Allow-Credentials", "true"); if (request.getMethod() == HttpMethod.OPTIONS) { response.setStatusCode(HttpStatus.OK); return Mono.empty(); } } return chain.filter(ctx); }; } @Bean public RouterFunction routerFunction() { return RouterFunctions.route( RequestPredicates.path("/fallback") .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), hystrixFallbackHandler); } /** * 解决springboot2.0.5版本出现的 Only one connection receive subscriber allowed. * 参考:https://github.com/spring-cloud/spring-cloud-gateway/issues/541 */ @Bean public HiddenHttpMethodFilter hiddenHttpMethodFilter() { return new HiddenHttpMethodFilter() { @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { return chain.filter(exchange); } }; } }
这是一个Spring Cloud Gateway的路由配置类。它使用了函数式编程风格来定义路由规则。
在这个类中,主要做了以下几件事情:
1. 配置跨域请求的过滤器(corsFilter):当请求的Origin与服务端的地址不一致时,浏览器会发送跨域请求。跨域请求需要服务端设置特殊的响应头来允许跨域访问。在这个过滤器中,我们判断当前请求是否为跨域请求,如果是,就设置相关的响应头。
2. 配置fallback路由:当其他路由都无法匹配时,将请求转发给hystrixFallbackHandler来处理。这个处理器是一个自定义的降级处理器,用于处理服务熔断、降级等情况。
3. 解决Spring Boot 2.0.5版本出现的"Only one connection receive subscriber allowed"问题:这个问题是由于WebFlux框架在处理请求时,只允许一个订阅者消费数据。为了解决这个问题,我们需要配置一个HiddenHttpMethodFilter过滤器。
以上就是这个类的主要功能和作用。如果你还有其他问题,请继续提问。
package com.bolt.gateway.handler; import com.bolt.gateway.provider.ResponseProvider; import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.ResourceProperties; import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; import org.springframework.boot.web.reactive.error.ErrorAttributes; import org.springframework.cloud.gateway.support.NotFoundException; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.server.*; import org.springframework.web.server.ResponseStatusException; import java.util.Map; /** * 异常处理 * * @author arch_group */ public class ErrorExceptionHandler extends DefaultErrorWebExceptionHandler { public ErrorExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, ErrorProperties errorProperties, ApplicationContext applicationContext) { super(errorAttributes, resourceProperties, errorProperties, applicationContext); } /** * 获取异常属性 */ @Override protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) { int code = 500; Throwable error = super.getError(request); if (error instanceof NotFoundException) { code = 404; } if (error instanceof ResponseStatusException) { code = ((ResponseStatusException) error).getStatus().value(); } return ResponseProvider.response(code, this.buildMessage(request, error)); } /** * 指定响应处理方法为JSON处理的方法 * * @param errorAttributes */ @Override protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) { return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); } /** * 根据code获取对应的HttpStatus * * @param errorAttributes */ @Override protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) { int statusCode = (int) errorAttributes.get("code"); return HttpStatus.valueOf(statusCode); } /** * 构建异常信息 * * @param request * @param ex * @return */ private String buildMessage(ServerRequest request, Throwable ex) { StringBuilder message = new StringBuilder("Failed to handle request ["); message.append(request.methodName()); message.append(" "); message.append(request.uri()); message.append("]"); if (ex != null) { message.append(": "); message.append(ex.getMessage()); } return message.toString(); } }
这是一个自定义的异常处理类,用于处理Spring Cloud Gateway中的异常情况。这个类继承自`DefaultErrorWebExceptionHandler`,并重写了一些方法来自定义异常处理的逻辑。
在这个类中,主要做了以下几件事情:
1. 重写`getErrorAttributes`方法:根据不同的异常类型,设置不同的响应状态码和错误信息。如果是`NotFoundException`异常,设置状态码为404;如果是`ResponseStatusException`异常,获取其对应的HTTP状态码。
2. 重写`getRoutingFunction`方法:指定响应处理方法为JSON处理的方法。
3. 重写`getHttpStatus`方法:根据错误属性中的`code`获取对应的HTTP状态码。
4. 定义了一个私有方法`buildMessage`:用于构建异常信息,包括请求方法、URI和异常消息。
通过重写这些方法,我们可以自定义异常处理的逻辑,包括设置响应状态码和错误信息。如果你还有其他问题,请继续提问。
阅读全文