赞
踩
在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计、开发、测试、部署和管理。这时,各个独立部署单元可以用不同的开发测试团队维护,可以使用不同的编程语言和技术平台进行设计,这就要求必须使用一种语言和平台无关的服务协议作为各个单元间的通讯方式。
换句话说就是网关为所有的请求提供了统一的入口,方便我们对服务请求和响应做统一管理。
API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。
Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
客户端向Spring Cloud网关发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序运行通过特定于请求的过滤器链发送请求。过滤器由虚线分隔的原因是,过滤器可以在发送代理请求之前或之后执行逻辑。执行所有“前置”过滤器逻辑,然后发出代理请求。发出代理请求后,将执行“后”过滤器逻辑。
路由和过滤器是gateway中非常重要的两个概念,gateway本身提供了非常丰富的路由规则和多种过滤器来适配我们的需求。gateway提供了11种路由规则,分别是:
其中,我们比较常用的就是路径路由谓词工厂,配合StripPrefix GatewayFilter工厂,实现我们的路由匹配转发。
路径路由谓词工厂配置如下:
- spring:
- cloud:
- gateway:
- discovery:
- locator:
- enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
- routes:
- # 路由id,建议配合服务名
- - id: demo_route
- #匹配路由名
- uri: lb://demo-provider
- predicates:
- # 断言,路径相匹配的进行路由
- - Path=/demo/**
配置的含义就是,如果请求路径中是/demo/**,则转发到demo-provider服务。
在spring cloud gateway 2.2.2.RELEASE版本中,已经默认实现了30种过滤器。
这里比较常用的如第25种,配置如下:
- spring:
- cloud:
- gateway:
- discovery:
- locator:
- enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
- routes:
- # 路由id,建议配合服务名
- - id: demo_route
- #匹配路由名
- uri: lb://demo-provider
- predicates:
- # 断言,路径相匹配的进行路由
- - Path=/demo/**
- filters:
- - StripPrefix=1
一般情况下我们配合path路由使用,这里的意思是假如,我们的demo-provider服务种有一个/test的接口,实际上我们的请求路径经过网关时应该时/demo/test,这样就能把这个路由分发到demo-provider服务中,但是分发过去的路由是/demo/test,和我们实际的/test接口不一样。这时候我们用StripPrefix=1,来截取掉一级路由,这样转发过去的路由就是/test了。
除了上面提供的30种过滤器外,我们还可以实现自定义的过滤器。
gatewayFilter接口是为了实现请求过滤,ordered接口是为了给过滤器设定优先级,值越大级别越低。
想要实现一个自定义的过滤器,无非就是两个步骤:1.实现过滤器,2.将过滤器添加到具体路由上。
- public class TokenGatewayFilter implements GatewayFilter, Ordered {
- @Override
- public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
-
- System.out.println("这里处理自身逻辑");
-
- return chain.filter(exchange);
- }
-
- @Override
- public int getOrder() {
- return 0;
- }
- }
-
- @Configuration
- class RouteConfiguration{
-
- @Bean
- public RouteLocator routeLocator(RouteLocatorBuilder builder){
-
- return builder.routes().route( r->
- r.path("/demo/**")
- .uri("lb://demo-provider ")
- .filter(new TokenGatewayFilter())
- .id("demo_route "))
- .build();
- }
- }
- @Component
- public class TokenCheckGatewayFilterFactory extends AbstractGatewayFilterFactory<TokenCheckGatewayFilterFactory.Config> {
- public TokenCheckGatewayFilterFactory() {
- super(Config.class);
- }
-
- @Override
- public List<String> shortcutFieldOrder() {
- return Arrays.asList("enabled");
- }
- @Override
- public GatewayFilter apply(Config config) {
- return (exchange, chain) -> {
- system.out.println("这里处理自身逻辑")
- return chain.filter(exchange);
- };
-
- }
-
- public static class Config {
- // 控制是否开启认证
- private boolean enabled = true;
-
- public Config() {}
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
- }
- }
这里我们可以直接在application.yml中为需要过滤的路由添加这个过滤器。
- spring:
- cloud:
- gateway:
- routes:
- - id: demo_route # 路由id,建议配合服务名
- uri: lb://demo-provider #匹配路由名
- predicates:
- - Path=/demo/** # 断言,路径相匹配的进行路由
- filters:
- - TokenCheck=true
需要注意的是,这个地方自定义的过滤器名称必须是XXGatewayFilterFactory,并且配置文件中配置过滤器时名字必须时这个XX。
当然,我们也可以为每个路由都添加这个过滤器,可以直接这样写配置,而不用在每个路由上都去写。
- spring:
- cloud:
- gateway:
- default-filters:
- - TokenCheck=true
这个GlobalFilter从名字中就可以看出,是一个全局过滤器,也就是说实现这个接口后,所有的请求都会被过滤,我们就不需要在去找往某个路由中加过滤器了。
- @Component
- public class TokenGlobalFilter implements GlobalFilter, Ordered {
- @Override
- public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
- System.out.println("这里处理自身逻辑");
- return chain.filter(exchange);
- }
-
- @Override
- public int getOrder() {
- return 0;
- }
- }
以上就是实现自定义网关过滤器的三种方式了。实际开发中根据需求来实现合适的过滤器就可以了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。