Spring Cloud Gateway网关

Spring Cloud Gateway(以下简称为Gateway),是Spring Cloud开源项目系列下一个子项目,它主要为接口API调取提供统一入出口的控制角色服务,比如:路由调度、结合Sentinel限流、结合Hystrix实现熔断回退、鉴权、日志收集等,所以它的存在很有价值。Gateway不同于zuul,它的核心是基于webflux实现非阻塞式web请求响应,性能高于zuul很多,是市面上应用较多的API网关选型,具体详细内容请浏览本篇及后续关于gateway的文章。

| 服务搭建

| 负载路由验证

| 一些注意事项

一、服务搭建

  1. 准备事项

本篇内容用到了《献给Nacos小白的一篇好文:注册中心》文中的项目示例:client-service和provider-service,请读者查阅该篇文章自行搭建这两个服务。

另外,在介绍gateway路由负载时,需要到nacos中寻找服务的多个实例,以便于gateway根据负载策略调度合适的服务实例,所以,我们需要准备好nacos服务环境,并知道如何将服务注册到nacos中,这些内容在文章《献给Nacos小白的一篇好文:注册中心》中都有介绍,请读者自行查阅实现。

2、依赖包pom.xml

2.1 springboot版本

<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.2.5.RELEASE</version>
 </parent>

2.2 alibaba cloud & spring cloud依赖管理

<dependencyManagement>

    <dependencies>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-dependencies</artifactId>

            <version> Hoxton.SR8</version>

            <type>pom</type>

            <scope>import</scope>

        </dependency>

        <dependency>

            <groupId>com.alibaba.cloud</groupId>

            <artifactId>spring-cloud-alibaba-dependencies</artifactId>

            <version> 2.2.1.RELEASE</version>

            <type>pom</type>

            <scope>import</scope>

        </dependency>

    </dependencies>

</dependencyManagement>

因为用到了alibaba cloud nacos和spring cloud gateway依赖,所以需要上面两个依赖管理。

2.3 gateway & nacos 依赖

<dependencies>

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-webflux</artifactId>

    </dependency>

    <dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-starter-gateway</artifactId>

        <version> 2.2.1.RELEASE</version>

    </dependency>

    <!-- service registry -->

    <dependency>

        <groupId>com.alibaba.cloud</groupId>

        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>

    </dependency>

</dependencies>

3、application.yml配置

spring:

  application:

    name: gateway-service

  cloud: 

     gateway:
routes:

       ### client service ###

        - id: client-service

          # 非负载均衡路由

#          uri: http://127.0.0.1:10002

        # 负载均衡的路由

         uri: lb://client-service/

         predicates:

          - Path=/api/test/**

         filters:

          - StripPrefix=1



如上配置,其中routes是配置路由规则的位置,其下的几个参数说明如下:

-id: 路由规则的唯一标识,保证唯一即可,一般设置为服务名;

uri: 调取服务的接口地址,可以是http或lb负载形式,如果指定为http形式,则gateway不负载调度服务接口,如果以lb://服务名/ 形式则以负载策略调度,所以这里选择负载方式。

predicates: -Path指定路由服务接口前置地址,也就是说接口地址为/api/test/xxx时就会触发路由规则,其中**代表任何层级接口地址,如:/api/test/1212、/api/test/client/1212等。

filters: -StripPrefix=1代表路由中转时会剔除第一个地址参数,如:/api/test/hello-world,实际调度地址/test/hello-world

4、将gateway注册中nacos,其它两个服务同样要注册

nacos:
  discovery:
   
### 服务注册地址及端口
    server-addr: 127.0.0.1:8848
    ### 指定服务注册的空间
    namespace: 4d973c7e-0a7e-4488-8e45-83ee5441f9d9
    ### 指定服务注册的分组
    group: provider_group

 
    ### 实例上报心跳间隔时间(毫秒)
    heart-beat-interval: 1000
    ### 实例上报心跳超时时间(毫秒)
    heart-beat-timeout: 3000
    ### 实例超时心跳被剔除时间(毫秒)
    ip-delete-timeout: 3000

将上面配置放在spring.cloud下,保证与gateway配置同级别即可,需要注意其中的namespace和group配置,必须保证三个服务gateway、client-service和provider-service都在同样的namespace和 group下,否则找不到服务。

二、负载路由验证

1、允许gateway到nacos中寻找实例

### 开启从注册中心获取地址
discovery:
   locator:
     enabled: true

将上面配置添加在spring.cloud.gateway下面,与routes同级别即可,若不配置,则路由找不到调度服务接口。

2、修改client-service服务接口/test/{hello}

为了验证gateway路由负载调度client-service接口,我们简单修改下client-service服务接口:

2.1 获取当前实例端口

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

2.2 接口/test/{hello}修改

为了区分负载调度哪个实例的接口,我们可通过端口区分,所以在返回做如下调整即可:

return ret + " ,I'am coming form the current service of port:" + serverPort;

3、验证下gateway负载路由调度

首先,分别启动provider-service和gateway服务,并将他们注册到nacos中,查看它们是否注册成功。

其次,我们启动2个client-service服务实例(端口为10002、10003),来验证下gateway负载路由的效果,启动命令如下:

java -jar -Dserver.port=10002 client-service.jar

java -jar -Dserver.port=10003 client-service.jar

然后,我们看下nacos注册的服务client-service已经存在2个实例了,端口号分别为10002和10003,进入服务详情页后,可看到实例的详细信息,如下:

spring gateway 白名单格式 spring cloud gateway 白名单_spring boot

spring gateway 白名单格式 spring cloud gateway 白名单_java_02

如何验证?我们可以使用postman或浏览器访问gateway接口地址,由其进一步路由中转,具体访问地址(10000为gateway服务的端口号):

http://127.0.0.1:10000/api/test/hello-world

多次访问上面接口后,若结果中端口号在10002和10003之间交替显示的话,则代表gateway路由和负载调度已成功:

hello-world ,I'am coming form the current service of port:10002
hello-world ,I'am coming form the current service of port:10003

三、一些注意事项

1、保证namespace和group一致

如果gateway想要到nacos中找到服务client-service的多个实例,那么它必须先注册到nacos中,然后保证gateway、client-service和provider-service三个服务的均属于同一个namespace和 group中,否则找不到服务。

2、记得开启从nacos获取实例权限

### 开启从注册中心获取地址
discovery:
   locator:
     enabled: true

3、负载调度必须使用lb://形式

# 负载均衡的路由
uri: lb://client-service/

4、启动多个服务实例

java -jar -Dserver.port=10002 client-service.jar

如上启动实例命名可以指定服务程序的端口号,如果读者使用—server-port=10002选项,则指定端口无效。