1 changed files with 56 additions and 0 deletions
@ -0,0 +1,56 @@ |
|||||
|
package com.zdxt.gateway.webserver.filter; |
||||
|
|
||||
|
import com.zdxt.gateway.webserver.config.PreferredFirstLoadBalancer; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain; |
||||
|
import org.springframework.cloud.gateway.filter.GlobalFilter; |
||||
|
import org.springframework.cloud.gateway.route.Route; |
||||
|
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; |
||||
|
import org.springframework.core.Ordered; |
||||
|
import org.springframework.http.server.reactive.ServerHttpRequest; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.web.server.ServerWebExchange; |
||||
|
import reactor.core.publisher.Mono; |
||||
|
|
||||
|
/** |
||||
|
* 优先角色注入过滤器 |
||||
|
* <p> |
||||
|
* 从命中的路由 metadata 中读取 role-order(逗号分隔的角色优先级列表), |
||||
|
* 复制为请求头 {@link PreferredFirstLoadBalancer#HEADER_ROLE_ORDER}, |
||||
|
* 供 {@link PreferredFirstLoadBalancer} 在负载均衡阶段读取。 |
||||
|
* <p> |
||||
|
* Order 必须早于 Spring Cloud Gateway 的 ReactiveLoadBalancerClientFilter(默认 10150), |
||||
|
* 否则 LoadBalancer choose 时拿不到 header。 |
||||
|
* |
||||
|
* @author zdxt |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
public class PreferredRoleFilter implements GlobalFilter, Ordered { |
||||
|
|
||||
|
/** 路由 metadata 中约定的 key */ |
||||
|
public static final String ROUTE_METADATA_ROLE_ORDER = "role-order"; |
||||
|
|
||||
|
@Override |
||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
||||
|
Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); |
||||
|
if (route != null) { |
||||
|
Object roleOrder = route.getMetadata().get(ROUTE_METADATA_ROLE_ORDER); |
||||
|
if (roleOrder != null && !roleOrder.toString().isBlank()) { |
||||
|
log.debug("[{}] 路由 {} 注入角色优先级: {}", |
||||
|
route.getId(), route.getUri(), roleOrder); |
||||
|
ServerHttpRequest mutated = exchange.getRequest().mutate() |
||||
|
.header(PreferredFirstLoadBalancer.HEADER_ROLE_ORDER, roleOrder.toString()) |
||||
|
.build(); |
||||
|
return chain.filter(exchange.mutate().request(mutated).build()); |
||||
|
} |
||||
|
} |
||||
|
return chain.filter(exchange); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
// 早于 ReactiveLoadBalancerClientFilter(10150),晚于 AccessLogFilter(HIGHEST_PRECEDENCE)
|
||||
|
return 10000; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue