springCloud-gateway-1-路由功能集成

在开篇springcloud微服务架构-CSDN博客中,对网关进行了功能的说明,下面将按照其核心功能进行逐一的实现。

本篇将讲解建立一个gateway项目,微服务注册到nacos中。实现用gateway动态实现路由功能。

Client ----> gateway ----> Ribbion负载均衡 取一个服务A ---->转发到服务A

一、回顾gateway的核心功能。

springCloud-gateway-1-路由功能集成_第1张图片

划重点:服务注册-nacos,gateway也是微服务。

功能实现包括:路由服务、鉴权与加密、日志服务、负载均衡、限流熔断。 

二、服务注册到nacos

这里为了演示效果,我们分别建立服务a,服务b,网关注册到nacos。

1、springboot项目注册到nacos。

网上关于maven项目有多,这里我以grdle构建的项目为例进行讲解。

1)新建一个空的springboot项目

idea新版用spring初始时不支持jdk8,所以我用start.aliyun.com来初始化。

springCloud-gateway-1-路由功能集成_第2张图片

springCloud-gateway-1-路由功能集成_第3张图片

初始化完成后,build.gradle文件修改repositories,增加阿里镜像url,以解决下载插件慢的问题。

repositories {
    mavenLocal()
    maven { url 'https://maven.aliyun.com/repository/central' }
    maven { url 'https://maven.aliyun.com/repository/public' }
    maven { url 'https://maven.aliyun.com/repository/spring' }
    maven { url 'https://maven.aliyun.com/repository/spring-plugin' }
    maven { url 'https://repo.spring.io/release' }
    mavenCentral()
}

如果下载gradle-7.5.1的包慢的话,可以改为最新的8.1.1版。 

springCloud-gateway-1-路由功能集成_第4张图片

等待gradle下载完所有依赖插件后,启动项目成功就完了一个初始项目的建立。

 2)build.gradlealibaba-nacos-discovery依赖

添加完后的完整的dependencies配置如下:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    //  alibaba-nacos-discovery 服务注册依赖
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.0.1.0'
    //  starter-alibaba-nacos-config 读取nacos配置的依赖。如果不需要配置中心可以不添加
//    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.0.1.0'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

完整文件如下:

springCloud-gateway-1-路由功能集成_第5张图片

3)application.yaml中添加nacos配置

resource目录下默认是application.properties,请自行创建(application.yml或application.yaml)

不同的后缀都可以的,需注意不同的后缀采用不同的格式

(加载优先级properties>yml>yaml,后加载的覆盖同名的先加载的配置)

spring:
  application:
    name: servies-a
  cloud:
   nacos:
     discovery:
       server-addr: 192.168.189.3:8849
       username: nacos
       password: nacos
       namespace: 4ddd4368-c3ed-45fd-8d7b-e28f9661498d

 配置完成后,重启项目,会看到控制台进行了nacos的注册

nacos registry, DEFAULT_GROUP servies-a 192.168.2.6:8080 register finished

springCloud-gateway-1-路由功能集成_第6张图片

4)nacos后台查看服务列表

springCloud-gateway-1-路由功能集成_第7张图片

5)编写一个用于查看应用名称的接口。

 通过enviroment返回配置属性,获得spring.application.name.springCloud-gateway-1-路由功能集成_第8张图片

 2、新建gateway项目注册到nacos。

新建gateway项目和上面的普通微服务差不多。区别在于不要勾选spring-web。

初始化项目以后,参照上面的项目修改repositories和修改grdle版本。

然后,我们添加gateway依赖:

核心是:implementation 'org.springframework.cloud:spring-cloud-starter-gateway',

需要指定spring-cloud-dependencies版本在2021.0.0及上版本。

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'    
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

ext {
    set('springCloudVersion', "2021.0.6")
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

启动项目,运行如下: springCloud-gateway-1-路由功能集成_第9张图片

将gateway项目注册到nacos。 

添加依赖:

implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.0.1.0'

application中设置nacos地址和服务名称:

spring:
  application:
    name: gateway
  cloud:
   nacos:
     discovery:
       server-addr: 192.168.189.3:8849
       username: nacos
       password: nacos
       namespace: 4ddd4368-c3ed-45fd-8d7b-e28f9661498d

我们在nacos后台查看服务:

 springCloud-gateway-1-路由功能集成_第10张图片

到这,我们gateway项目的新项目注册到nacos就算成功了。

 3、配置gateway,实现简单路由转发.

在application文件中配置(网关的端口为22060):

spring:
  application:
    name: gateway
  cloud:
   nacos:
     discovery:
       server-addr: 192.168.189.3:8849
       username: nacos
       password: nacos
       namespace: 4ddd4368-c3ed-45fd-8d7b-e28f9661498d
   gateway:
     routes:
       # 下面的路由是配合nacos的注册,实现自动地址
       - id: service-a  # 全局唯一,不能重复
         uri: http://192.168.189.3:8080 # 表示将服务名ip路由指向这个url地址
         predicates:
           - Path=/se-a/**  # 表示将匹配路径为se-a开头的请求
         filters: #这个必须写
           - StripPrefix=1  #  请求/se-a/home/get,会把/se-a这一级去掉,最后转发到目标服务的路径为/home/get
server:
  port: 22060

springCloud-gateway-1-路由功能集成_第11张图片

 4、通过lb实现负载均衡,动态路由实现

由于各微服务都是单独开发,部署,所以网关并不知道各微服务的实际地址。即然我们用了nacos,这个就交由微服务中心来管理了。

Gateway有两种客户端负载均衡器,LoadBalancerClientFilterReactiveLoadBalancerClientFilter。

所以,我们可以loadbalancer来解决这个问题,先引用依赖:

implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-loadbalancer', version: '4.1.0'

然后,application.yaml中配置服务:

gateway:
  routes:
    # 下面的路由是配合nacos的注册,实现自动地址
    - id: service-a  # 全局唯一,不能重复
      uri: http://192.168.189.3:8080 # 表示将服务名ip路由指向这个url地址
      predicates:
        - Path=/se-a/**  # 表示将匹配路径为se-a开头的请求
      filters: #这个必须写
        - StripPrefix=1  #  请求/se-a/home/get,会把/se-a这一级去掉,最后转发到目标服务的路径为/home/get
    - id: service-b
      uri: lb://service-b # lb:服务名称。表示调用nacos注册的服务名称为service-b的服务
      predicates:
        - Path=/se-b/**
      filters: #这个必须写
        - StripPrefix=1  #  请求/openapi/home/get,会把/open这一级去掉,最后转发到目标服务的路径为/home/get
      # - JwtAuthFilter

这样,我们就可以访问这个se-b服务了:

springCloud-gateway-1-路由功能集成_第12张图片

 三、Spring Gateway工作流程及组成

 官网介绍流程如下:

springCloud-gateway-1-路由功能集成_第13张图片

核心点:
Route(路由):路由是构建网关的基础模块儿,它由ID,目标URI,包括一系列的断言和过滤器组成,如果断言为True则匹配该路由。
Predicate(断言):开发人员可以匹配http请求中的所有内容(如:请求头或请求参数),请求与断言匹配则进行路由。
Filter(过滤):指Spring框架中GatewayFilter的实例,使用过滤器可以在请求被路由前或者之后对请求进行修改。
除此之外,还有用springboot本身的过滤器、拦截器,全局过滤器等进行更加个性化的设置。

总结:路由断言 + 过滤器链

学习文档地址:

官网(英文):Spring Cloud Gateway

中文:Spring Cloud Gateway 中文文档 (springdoc.cn) 

1、路由组成

     id:  路由的ID
     uri: 匹配路由的转发地址
     predicates:  配置该路由的断言,通过PredicateDefinition类进行接收配置。
     order:  路由的优先级,数字越小,优先级越高。
     Filter: 过滤器 过滤掉一些请求, 满足则转发
 

2、 predicates

Predicate 来源于Java8,接受输入参数,返回一个布尔值结果
   Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则
   转发的判断条件.
   SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等
   支持多个Predicate请求的转发是必须满足所有的Predicate后才可以进行路由转发
 

 官方自带了很多实用的断言,参见:Spring Cloud Gatewayicon-default.png?t=N7T8https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

 springCloud-gateway-1-路由功能集成_第14张图片

举例:

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: lb://service-a
        predicates:
        - Cookie=mycookie,mycookievalue
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: lb://service-a
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue
spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: lb://service-a
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: lb://service-a
        predicates:
        - Weight=group1, 2

 3、filter

Spring Cloud Gateway 包括许多内置的 GatewayFilter 工厂。

springCloud-gateway-1-路由功能集成_第15张图片

具体的使用请见上述学习文档的,说得比较详细,有用例和说明,比如:

springCloud-gateway-1-路由功能集成_第16张图片

4、全局过滤器\Forwarded Headers Filter 

Forwarded Headers Filter 创建一个 Forwarded header来发送给下游服务。它将当前请求的 Host header、scheme和port添加到任何现有的 Forwarded 头中。

GlobalFilter 接口的签名与 GatewayFilter 相同。这些是特殊的过滤器,有条件地应用于所有路由

springCloud-gateway-1-路由功能集成_第17张图片

 四、设置跨域

springCloud-gateway-1-路由功能集成_第18张图片

springCloud-gateway-1-路由功能集成_第19张图片

五、通过RouteLocatorBuilder实现路由

 springCloud-gateway-1-路由功能集成_第20张图片

六、总结

由于gateway的内容过多,不得不分篇来介绍。这篇仅讲到路由的动态转发。下篇将继续介绍gateway中的鉴权实现。

你可能感兴趣的:(SpringCloud微服务,spring,cloud,gateway,java)