SpringCloud 服务网关

博客参考学习视频: https://www.bilibili.com/video/BV18E411x7eT?from=search&seid=4388336378730572330

上一篇:SpringCloud 服务降级: https://blog.csdn.net/qq_45738810/article/details/109134845

GateWay 新网关

① 概述简介

1.官网
2.是什么

概述:

image-20201017231511015

image-20201017231529685

一句话:

  1. SpringCloud Getaway 使用的 Webflux 中的 reactor-netty 响应式编程组件,底层使用的 Netty 通讯框架
  2. 源码框架

image-20201017231835609

3.能干嘛
  1. 反向代理
  2. 鉴权
  3. 浏览控制
  4. 熔断
  5. 日志监控

4.微服务架构中网关在哪里

image-20201017232035683

5.有了 Zuul 了怎么又出来了 gateway

我们为什么选择 Gatway?

  1. neflix 不太靠谱, zuul2.0 一直跳票,迟迟不发布

image-20201017232138919

  1. SpringCloud Gateway 具有如下特性

image-20201017232221246

  1. SpringCloud Gateway 与 Zuul 的区别

image-20201017232613951

Zuul1.x 模型

image-20201017232643447

image-20201017232655244

GateWay 模型

  1. WebFlux 是什么

image-20201017232828772

②三大核心概念

1.Route(路由)

​ 路由的构建网关的基本模块,它由ID ,目标 URI , 一系列的断言和过滤器组成,如果断言为true则匹配该路由

2. Predicate(断言)

​ 参考的是 java8的 java.util.function.Predicate 开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求域断言相匹配则进行路由。

3. Filter(过滤)

​ 指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

4. 总体

image-20201017233554041

③ Gateway 工作流程

1.官网总结

image-20201017233730406

image-20201017233740334

2.核心逻辑

​ 路由转发+执行过滤器链

④ 入门配置

新建 Module: cloud-gateway-gateway9527

POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>clould</artifactId>
        <groupId>com.oy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-gateway-gateway9527</artifactId>

    <dependencies>
        <!--新增 gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.oy</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

YML

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
eureka:
  instance:
    hostname: cloud-gateway-service
  client:   #服务提供者provider注册进eureka服务列表中
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone:  http://eureka7001.com:7001/eureka

业务类 (无)

主启动类

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

**9527 网关如何做路由映射那? ? ? **

  • cloud-provider-payment8001 看看 controller 的访问地址
    • get
    • lb
  • 我们目前不想暴露 8001 端口,希望在 8001 外面套一层 9527

YML 新增网关配置

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
      routes:
        - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          uri: http://localhost:8001
          predicates:
            - Path=/payment/get/** # 断言,路径相匹配的进行路由
        - id: payment_route2
          uri: http://localhost:8001
          predicates:
            Path=/payment/lb/** #断言,路径相匹配的进行路由
eureka:
  instance:
    hostname: cloud-gateway-service
  client:   #服务提供者provider注册进eureka服务列表中
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone:  http://eureka7001.com:7001/eureka

测试

  • 启动 7001
  • 启动 8001: cloud-provider-payment8001
  • 启动 8001: cloud-provider-payment8001

访问说明

image-20201017235433754

  • 添加网关前: http://localhost:8001/payment/get/1

image-20201017235712871

  • 添加网关后: http://localhost:9527/payment/get/1

image-20201017235746463

YML 配置说明

Gateway 网关路由有两种配置方式

  1. 在配置文件 yml 中配置 (见前面步骤)
  2. 代码中注入 RouteLocator 的 Bean

官网案例

image-20201017235947408

自己写一个
业 务 需 求 : 通 过 9527 网 关 访 问 到 外 网 的 百 度 新 闻 网 址 http://news.baidu.com/guoji

image-20201018001052144

/**
 * 配置网关
 * @Author OY
 * @Date 2020/10/18
 */
@Configuration
public class GateWayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_rote_oy", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();

        return routes.build();
    }

    @Bean
    public RouteLocator customRouteLocator2(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_rote_oy2", r -> r.path("/guoji").uri("http://news.baidu.com/guoji")).build();

        return routes.build();
    }
}

测试

image-20201018001206863

⑤ 通过服务名实现动态

​ 默认情况下 Gateway 会根据注册中心的服务列表,以注册中心上微服务名为路径路径创建动态路由创建动态路由进行转发,从而实现动态路由的功能

启动: 一个 eureka7001 + 两个服务提供者 8001/8002

POM

image-20201018101507557

YML: uri: lb//cloud-payment-service

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
      routes:
        - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          #uri: http://localhost:8001
          uri: lb//cloud-payment-service
          predicates:
            - Path=/payment/get/** # 断言,路径相匹配的进行路由
        - id: payment_route2
          #uri: http://localhost:8001
          uri: lb//cloud-payment-service
          predicates:
            Path=/payment/lb/** #断言,路径相匹配的进行路由
eureka:
  instance:
    hostname: cloud-gateway-service
  client:   #服务提供者provider注册进eureka服务列表中
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone:  http://eureka7001.com:7001/eureka

需要注意的是uri 的协议为 lb ,表示启用 Gateway 负载均衡功能。

lb ://serviceName 是 spring cloud gateway 在微服务中自动为我们创建负载均衡 uri。

测试:

​ http://localhost:9527/payment/lb: 8001/8002 两个端口切换

image-20201018102215917

⑥ Predicate 的使用

1.是什么

启动我们的 gateway9527

image-20201018102438957

2.Route Predicate Factories 是什么?

image-20201018102818983

image-20201018102833101

3.常用的 Route Predicate

image-20201018102917173

  1. After Route Predicate

问题一:上述这个 After 好懂,这个时间时间串串,有点不能理解。使用以下方式即可解开谜团。

@Test
public void test1(){
    ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区
    System.out.println(zbj); // 2020-10-18T10:35:52.127+08:00[Asia/Shanghai]

    ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/Denver"));// 用指定时区获取当前时间
    System.out.println(zny); // 2020-10-17T20:38:37.693-06:00[America/Denver]
}

image-20201018103914482

YML

- After=2020-10-18T10:38:37.692+08:00[Asia/Shanghai]

image-20201018104343943

  1. Before Route Predicate

YML

- After=2020-10-18T10:38:37.692+08:00[Asia/Shanghai]
- Before=2020-10-18T10:38:37.692+08:00[Asia/Shanghai]
  1. Between Route Predicate

YML

- Between=2020-10-18T10:38:37.692+08:00[Asia/Shanghai],2020-10-19T10:38:37.692+08:00[Asia/Shanghai]
  1. Cookie Route Predicate

image-20201018104650868

1) 不带 cookies 访问

image-20201018105547760

2) 带上 cookies 访问

image-20201018105958123

加 入 curl 返 回 中 文 乱 码 :https://blog.csdn.net/leedee/article/details/82685636

curl http://localhost:9527/payment/lb --cookie "username=oy"

3)YML

- Cookie=username,oy #并且Cookie是username=oy才能访问

image-20201018110149006

  1. Header Route Predicate

image-20201018110242173

YML

- Header=X-Request-Id, \d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式

image-20201018110827869

image-20201018110353776

  1. Host Route Predicate

image-20201018110918455

YML

- Host=**.somehost.org,**.anotherhost.org
  1. Method Route Predicate

image-20201018111406971

YML

- Method=GET,POST
  1. Path Route Predicate

YML

- Path=/red/{segment},/blue/{segment}
  1. Query Route Predicate

image-20201018111513538

YML

- Query=username, \d+ #要有参数名称并且是正整数才能路由

image-20201018111707585

测试: http://localhost:9527/payment/lb?username=1

image-20201018111747994

  1. 小总结

All

image-20201018111959191

说白了,Predicate就是为了实现一组匹配规则, 让请求过来找到对应的Route进行处理

⑦ Filter 的使用

1.是什么

image-20201018112246481

2.Spring Cloud Gateway 的 Filter
  • 生命周期, Only Two
    • Pre : 在业务逻辑之前
    • Post: 在业务逻辑之后
  • 种类: Only Two
    • GatewayFilter: 单一
    • GlobalFilter: 全局
3.常用的 GatewayFilter

AddRequestParameter

YML

image-20201018112722005

4.自定义过滤器

自定义全局 GlobalFilter

  1. 两个主要接口介绍
impiemerts GlobalFilter , Ordered
  1. 能干嘛
  • 全局日志记录
  • 统一网关鉴权
  1. 案例代码
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("*********come in MyLogGateWayFilter: "+new Date());
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if(username == null){
            log.info("*****用户名为 NUll 非法用户.(┬_┬)");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);// 给人家一个回应
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

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

测试

启动

image-20201018114817482

  • 正确: http://localhost:9527/payment/lb?username=1

    image-20201018114840709

  • 错误 : http://localhost:9527/payment/lb?usernameaa=1
    image-20201018114922381

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值