SpringCloud之gateway组件(网关)


一、gateway是什么?

gateway组件是继zuul之后的又一大网关组件,不过zuul其本身还是基于servlet实现的,换言之还是同步阻塞方式的实现。就其本身来讲它的最根本弊端也是再此。而非阻塞带来的好处不言而喻,高效利用线程资源进而提高吞吐量,基于此Spring率先拿出针对于web的杀手锏,对,就是webflux。而Gateway本身就是基于webflux基础之上实现的。

Spring Cloud Gateway功能:

1.建立在Spring Framework 5,Project Reactor和Spring Boot 2.0之上

2.能够匹配任何请求属性上的路由。

3.谓词和过滤器特定于路由。

4.断路器集成。

5.Spring Cloud DiscoveryClient集成

6.易于编写的谓词和过滤器

7.请求速率限制

8.路径改写

在gateway当中有三个重要的元素他们分别是:

Route :是最核心的路由元素,它定义了ID,目标URI ,predicates的集合与filter的集合,如果Predicate聚合返回真,则匹配该路由
Predicate :基于java8的函数接口Predicate,其输入参数类型ServerWebExchange,其作用就是允许开发人员根据当前的http请求进行规则的匹配,比如说http请求头,请求时间等,匹配的结果将决定执行哪种路由
Filter:GatewayFilter,它是由特殊的工厂构建,通过Filter可以在下层请求路由前后改变http请求与响应

二、工作原理

在这里插入图片描述
客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链运行请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有“前置”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。

简而言之:客户端发起请求->由Predicate里面所定义的规则选去合适的路由->网关处理程序执行Filter(前置)->转发请求并执行过滤器(后置)

三、入门使用

1.pom引入

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

2.配置文件

application.yml

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: route1
          uri: http://localhost:8001
          predicates:
            - Path=/payment/**
        - id: route2
          uri: http://localhost:80
          predicates:
            - Path=/order/**
eureka:
  client:
    service-url:
      defaultZone: http://eurekaserver7001.com:7001/eureka/

上述路由配置中,访问路径是/payment开头那么路由到8001端口,访问路径是/order开头那么路由到80端口。

3.启动类

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayMain9527 {

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

4.测试

为了测试gateway功能,还需要启动注册中兴Eureka,启动两个微服务(payment,consumer)这个两个微服务中只写一个方法就是返回当前服务的端口。

eureka截图
在这里插入图片描述
访问路径 http://localhost:9527/payment/getPort
在这里插入图片描述
访问路径 http://localhost:9527/order/getPort
在这里插入图片描述
测试通过。

四、Route(路由)

在上述入门操作步骤中,路由配置为指定的微服务的地址,但是在实际使用场景中,我们搭建的是微服务的集群,所以此时只是配置一个指定的路由地址就显得有些相形见绌了。

所以能不能有一种配置方式适用于集群环境下?

答案是可以的,在学习Ribbon+restTemplate和Fegin中我们是使用微服务注册到注册中心的Application.name来作为请求转发的地址,如今gateway也同样注册在Eureka中,那么也可以如此使用。

在这里插入图片描述
(官网解释)

1.修改application.yml

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: route1
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/**
        - id: route2
          uri: lb://CLOUD-CONSUMER-SERVICE
          predicates:
            - Path=/order/**
eureka:
  client:
    service-url:
      defaultZone: http://eurekaserver7001.com:7001/eureka/

2.测试

重新启动gateway测试
访问路径 http://localhost:9527/payment/getPort
在这里插入图片描述
访问路径 http://localhost:9527/order/getPort
在这里插入图片描述
测试通过。

五、Predicate(断言)

从工作原理可以知道,Predicate的作用就是确定路由的规则。

官网提供了十一种类型Predicate
在这里插入图片描述
The Path Route Predicate Factory:根据访问路径匹配路由(这个是比较常用的Predicate,上一个目录里面的配置就是这个)
官网实例:

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

这些Predicate官网都有非常详细的实例,并且可以组合使用,所以此处就不再过多解释,把官网地址贴在此处,如有需要自己查看一下即可,链接: Spring-gateway.

六、Filter(过滤器)

gateway给我们提供的Filter可以分为单一过滤器(GatewayFilter )和全局过滤器( Global Filters)

1、单一过滤器

官网提供的单一过滤器一共有30种之多,这里就不一一展示了,官网的实例非常详细,同样是把链接贴到此处如有需要,自行查看,链接: Spring-gateway.

下面测试一种单一过滤器(The SetPath GatewayFilter Factory)

The SetPath GatewayFilter Factory:修改请求访问路径

修改application.yml

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: route1
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/**
        - id: route2
          uri: lb://cloud-consumer-service
          predicates:
            - Path=/test/order/**
          filters:
            - SetPath=/order/getPort
eureka:
  client:
    service-url:
      defaultZone: http://eurekaserver7001.com:7001/eureka/

orderController

@RestController
@Slf4j
@RequestMapping("/order")
public class OrderController {

 

    @Value("${server.port}")
    public String port;

    @GetMapping("/getPort")
    public String getPort(){
        return port;
    }
}

我们将访问/test/order,测试是否可以将顺利路由到后台的/order所指向的controller中。

测试通过。

2、全局过滤器

在springgateway中配置全局过滤器需要实现两个接口GlobalFilter, Ordered。
下面写一个全局过滤器判断请求头里test字段值是否为123,如果test字段值为123则不做任何处理,不是则返回错误信息

新增GlobalFilterConfig配置类

@Configuration
@Slf4j
public class GlobalFilterConfig {

    @Bean
    public MyGlobalFilter getMyGlobalFilter(){
        return new MyGlobalFilter();
    }

    public class MyGlobalFilter implements GlobalFilter, Ordered {

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            String value = exchange.getRequest().getHeaders().getFirst("test");

            if(!value.equals("123")){
                log.info("value值为空");
                 exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY);
                 return  exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        }

        @Override
        public int getOrder() {
            return 0;
        }
    }
}

测试:
test值为456时,如下图
在这里插入图片描述
test值为123时,如下图
在这里插入图片描述
测试通过。

七、总结

Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。
Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。

以上是个人见解,如有错误,欢迎指正。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值