SpringCloud:Spring Cloud Gateway中如何定制filter实现自定义路由

Spring Cloud Gateway中提供的默认filter有时不能满足实际的业务需求,因此很多时候需要使用定制的filter。

在Spring Cloud Gateway中,predicate用于定义请求需要满足什么条件才能对它继续进行处理,filter用于定义对请求进行怎样的处理,uri用于定义处理后的请求要转发到什么地址。

filter执行的顺序是有优先级的,优先级越高则在pre阶段执行顺序越靠前,而在post阶段执行顺序越靠后。在Spring Cloud Gateway中会为每个filter设置一个order值,order值越大则优先级越低,order值起小优先级越高。

Spring Cloud Gateway中有两个非常重要的GlobalFilter:

filter名称作用优先级
RouteToRequestUrlFilter生成最终转发到的uri10000
NettyRoutingFilter转发报文Integer.MAX_VALUE

 

 

例如要实现根据特定标识将请求转发到指定uri的功能,则定制的filter的优先级要在RouteToRequestUrlFilter和NettyRoutingFilter之间,下面提供一个例子:

pom.xml

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<maven.compiler.source>1.8</maven.compiler.source>
	<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-webflux</artifactId>
		<version>2.4.4</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-gateway</artifactId>
		<version>3.0.2</version>
	</dependency>
</dependencies>

 application.properties

server.port=8070
spring.application.name=gateway_server

# unit: ms
spring.cloud.gateway.httpclient.connect-timeout=10000
spring.cloud.gateway.httpclient.response-timeout=5s

 java代码

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SpringBootApplication
@EnableAutoConfiguration(exclude = { ErrorMvcAutoConfiguration.class })
public class SpringCloudGatewayApplication {
	@Autowired
	private CustomerFilter filter;

	public static void main(String[] args) {
		SpringApplication.run(SpringCloudGatewayApplication.class, args);
	}

	@Bean
	public RouteLocator myRoutes(RouteLocatorBuilder builder) {
		return builder.routes().route(p -> p.path("/**").filters(f -> f.filter(filter)).uri("no://op")).build();
	}

}
import reactor.core.publisher.Mono;

@Component
public class CustomerFilter implements GatewayFilter, Ordered {

	@Override
	public int getOrder() {
		return RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER + 1;
	}

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		String newUrl = null;
		String serviceName = "";

		List<String> serviceHeaderList = exchange.getRequest().getHeaders().getValuesAsList("serviceName");

		if (serviceHeaderList.contains("s1")) {
			newUrl = "http://127.0.0.1:9090/TestWebApp/testServlet";
			serviceName = "s1";
		} else if (serviceHeaderList.contains("s2")) {
			newUrl = "http://127.0.0.1:9090/TestWebApp/regionServlet?flag=list";
			serviceName = "s2";
		}

		try {
			exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, new URI(newUrl));
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}

		Mono<Void> ret = chain.filter(exchange);

		exchange.getResponse().getHeaders().add("doWork", serviceName + " ok");

		return ret;
	}
}

以上代码中可以看到,会根据请求头中serviceName对应的值转到不同的uri,同时把order的值设置成比RouteToRequestUrlFilter的order的值大1,这样CustomerFilter在pre阶段就会在RouteToRequestUrlFilter之后执行。

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway 3.1.7版本自定义负载均衡策略可以通过实现`org.springframework.cloud.gateway.loadbalancer.LoadBalancer`接口来实现,该接口定义了选择服务实例的方法。 以下是一个示例,展示了如何定义一个基于特定请求头的自定义负载均衡策略: ```java public class CustomLoadBalancer implements LoadBalancer<ServiceInstance> { private final String headerName; public CustomLoadBalancer(String headerName) { this.headerName = headerName; } @Override public ServiceInstance choose(Object key) { if (key instanceof ServerWebExchange) { ServerWebExchange exchange = (ServerWebExchange) key; Object headerValue = exchange.getRequest().getHeaders().getFirst(headerName); String serviceName = "my-service"; // 根据请求头的值选择服务实例 ServiceInstance serviceInstance = ...; return serviceInstance; } return null; } } ``` 在上面的示例,`CustomLoadBalancer`实现了`LoadBalancer`接口,并基于特定的请求头选择服务实例。 然后,你需要创建一个`org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction`实例,用于将服务的URI重写为负载均衡的服务实例地址。最后,你需要将这个自定义的负载均衡策略应用到Spring Cloud Gateway路由规则。 以下是一个完整的示例,展示了如何定义和应用自定义的负载均衡策略: ```java @Bean public LoadBalancer<ServiceInstance> customLoadBalancer() { return new CustomLoadBalancer("my-header"); } @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder, LoadBalancer<ServiceInstance> customLoadBalancer) { return builder.routes() .route(r -> r.path("/my-service/**") .uri("http://my-service") .id("my-route") .filter(new CustomLoadBalancerGatewayFilterFactory(customLoadBalancer))) .build(); } public class CustomLoadBalancerGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomLoadBalancerGatewayFilterFactory.Config> { private final LoadBalancer<ServiceInstance> loadBalancer; public CustomLoadBalancerGatewayFilterFactory(LoadBalancer<ServiceInstance> loadBalancer) { super(Config.class); this.loadBalancer = loadBalancer; } @Override public GatewayFilter apply(Config config) { RewriteFunction<String, String> rewriteFunction = uri -> { // 将URI重写为负载均衡的服务实例地址 ServiceInstance serviceInstance = loadBalancer.choose(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR).block(); return "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + uri; }; return new RewritePathGatewayFilterFactory().apply(new RewritePathGatewayFilterFactory.Config().setRewriteFunction(rewriteFunction)); } public static class Config { // 配置属性 } } ``` 在上面的示例,`customLoadBalancer`方法定义了自定义的负载均衡策略`CustomLoadBalancer`。`customRouteLocator`方法创建了一个路由规则,将请求路径`/my-service/**`映射到`http://my-service`服务上,并使用自定义负载均衡策略。`CustomLoadBalancerGatewayFilterFactory`则将自定义负载均衡策略应用到路由规则,并将服务的URI重写为负载均衡的服务实例地址。最后,你可以在路由规则使用`CustomLoadBalancerGatewayFilterFactory`来定义自定义的负载均衡策略。 ```yaml spring: cloud: gateway: discovery: locator: enabled: false routes: - id: my-route uri: http://my-service predicates: - Path=/my-service/** filters: - CustomLoadBalancer=my-header ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值