跳至主要內容

Spring Cloud 之微服务网关 Gateway

logycoconut关于技术SpringCloud大约 4 分钟

Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,比 Netflix 的 Zuul 组件更加适合 Spring Cloud体系

大家一定要多看官方文档啊!!文档比我详细多了,本文只是一些简单的应用

为什么要用网关

网关是介于客户端和服务器之间的一层,外部请求会先经过网关这一层再转发到其他功能模块中

所以,我们可以在网关上进行鉴权、监控等操作,让业务模块更加专注于业务

  • 只将网关对外暴露,隐藏微服务真实地址,保护微服务
  • 在网关中进行鉴权操作,无须在业务代码中鉴权
  • 避免了客户端和微服务直接接触 ( 在微服务变更时,重构难度会变大 )

快速上手

添加依赖

网关本质上也是一个微服务,也需要在注册中心注册

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
</dependencies>

相关代码

启动类代码

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

application.yml 配置

server:
  port: 10011
spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  # 是否要通过服务中心自动根据 serviceId 创建路由
          lower-case-service-id: true  #是否将服务id转换为小写
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka/
logging:
  level:
    org.springframework.cloud.gateway: debug

测试

是否正确代理

网关转发的语法为网关地址:端口/服务中心注册serviceId/具体的url

我们通过访问 http://localhost:10011/feign-provider/user/infoopen in new window 发现可以得到正确结果

feign-provider 是之前文章中创建的一个服务提供方

负载均衡

复制一份 provider 的启动配置并且对返回值进行适当的修改,我们可以看到不同的结果是交替出现的

路由规则匹配

我们现在知道了 gateway 自动根据 serviceId 创建路由的方式,但是怎么自定义路由规则呢

我们需要先清楚三个概念

  • Route(路由):它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
  • Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
  • Filter(过滤器):GatewayFilter的实例,我们可以使用它修改请求和响应。

上述概念原文地址open in new window,我是可耻的搬运工

简单实现

server:
  port: 10011
spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: provider-service  # 路由的唯一Id
          uri: https://github.com/  # 目标服务地址
          predicates:  # 路由条件,接受一个输入参数,返回一个布尔值结果
            - Path=/logycoconut

上述配置的意思是:配置了一个名为provider-service的规则,当访问地址http://localhost:10011/logycoconut时会自动转发到地址https://github.com/logycoconut

这是路由匹配规则的一种,还有其他的可以参照文档,包括通过时间、Cookie、请求方式、请求参数等匹配

路由规则拓展open in new window

Gateway 中的 Filter

简单实现

更改网关的配置文件

server:
  port: 10011
spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false  # 是否要通过服务中心自动根据 serviceId 创建路由
          lower-case-service-id: false  #是否将服务id转换为小写
      routes:
        - id: provider-service  # 路由的唯一Id
          uri: lb://feign-provider  # 目标服务地址
          predicates:  # 路由条件,接受一个输入参数,返回一个布尔值结果
            - Path=/user/info
          filters:
            - AddRequestParameter=name, zhangsan
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka/
logging:
  level:
    org.springframework.cloud.gateway: debug

上述配置的意思是:将符合路径/user/info的请求都添加了name=zhangsan的请求参数

lb://feign-provider是Gateway Global Filter的一种运用,如果 URL 中具有 lb,就使用负载均衡客户端将 URL 解析成实际的地址加端口

修改 provider 服务验证请求

@RestController
@RequestMapping("user")
public class ProviderController {

    @GetMapping("info")
    public String info(String name) {
        return "我叫张三,今年二十三" + name;
    }
}

相关源码地址

仅供参考

https://github.com/logycoconut/Spring-Cloud-Notes/tree/master/gatewayopen in new window

参考资料

Spring Cloud Gateway官方文档open in new window

spring cloud gateway 2 深入了解 - filteropen in new window 常用网关过滤器和全局过滤器介绍

Spring Cloud Gateway 过滤器open in new window 自定义过滤器