SpringCloud服务网关:GateWay


zuul停更了,要使用GateWay

1. GateWay

1.1 概述

Gateway官方文档:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/

在Spring Cloud 1.x中,网关使用的是Zuul 1,在Spring Cloud 2.x中,网关使用的是Gateway,因为Zuul 2版本进展缓慢,所以Spring Cloud自己研发了网关,Gateway是原Zuul 1的替代版。Gateway采用异步非阻塞模型开发,性能上不需要担心,虽然Netflix发布了Zuul 2版本,但是Spring Cloud并没有整合的计划,所以才自己推出了Gateway的方案。

Spring Cloud Gateway是Spring Cloud的一个全新项目,基于Spring 5+Spring Boot 2.x+Project Reactor等技术开发的网关,旨在为微服务架构提供一种简单有效的统一API路由管理方式。

Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul 1,在Spring Cloud 2.x版本中,没有对新版本Zuul 2最新高性能版本进行集成,仍然使用的Zuul 1非Reactor模式的老版本,为了提升网关性能,Spring Cloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway目标是提供统一的路由方式,并且基于Filter链方式提供网关基本功能:安全、监控、指标、限流。

gateway之所以性能好,因为底层使用WebFlux,而webFlux底层使用netty通信(NIO)

网关的作用:反向代理、鉴权、流量控制、熔断、日志监控等。

在微服务架构中,网关的位置,位于各个微服务的上一层,通过网关后,就访问到了具体的微服务了。

1.2 Spring Cloud Gateway特性

  • 基于Spring Framework 5+Project Reactor+Spring Boot 2.x进行构建
  • 动态路由:能够匹配任何请求属性
  • 支持路由指定Predicate(断言)和Filter(过滤器),而且编写容易
  • 集成了Hystrix断路器功能
  • 集成Spring Cloud服务发现功能
  • 支持请求限流功能
  • 支持路径重写功能
    在这里插入图片描述

1.3 GateWay与zuul的区别

  • Zuul 1采用的是阻塞I/O的API网关
  • Zuul 1使用Servlet2.5的阻塞架构实现,不支持任何长连接(如WebSocket),Zuul的设计模式和Nginx比较像,每次I/O都从工作线程中选择一个执行,请求线程在工作线程完成之前一直是阻塞的,Nginx是C++实现,Zuul是Java实现,JVM在第一次的加载时候,会比较慢,所以Zuul的性能比较差
  • Zuul 2设计理念跟先进,基于Netty非阻塞和支持长连接,但是目前Spring Cloud没有整合它,Zuul 2的性能比Zuul 1性能有较大提升,Spring Cloud Gateway的性能也不错,官方测试数据表示,Spring Cloud Gateway的RPS(每秒请求数)是Zuul 1的1.6倍
  • Spring Cloud Gateway建立在Spring Framework 5+Project Reactor+Spring Boot 2.x之上,使用异步非阻塞API,Spring Cloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层使用了高性能的Reactor模式通信框架Netty
  • Spring Cloud Gateway还支持WebSocket,与Spring紧密集成拥有更好的开发体验

1.4 zuul1.x的模型

在这里插入图片描述
在这里插入图片描述

1.5 什么是webflux

是一个非阻塞的web框架,类似springmvc这样的,其底层使用了高性能的Reactor模式通信框架Netty
在这里插入图片描述

1.6 GateWay的三大核心概念

1. 路由:

在这里插入图片描述
就是根据某些规则,将请求发送到指定服务上

2. 断言:

在这里插入图片描述
就是判断,如果符合条件就是xxxx,反之yyyy

3. 过滤:

在这里插入图片描述
路由前后,过滤请求

4. 3个概念总结:

路由的功能是由断言和过滤组合来实现的,一个Web请求发送后,先经过网关,网关里的断言和过滤用来判断这个请求是否需要路由转发,当断言为true,过滤器放行时候,这个请求进行路由转发,此时,请求才到达具体的微服务模块。

1.7 GateWay的工作原理

在这里插入图片描述
在这里插入图片描述

2. 使用GateWay

2.1 GateWay —路由

2.11 创建GateWay网关9527服务模块

(1)pom.xml

创建cloud-gateway-gateway9527模块,修改pom.xml,加入spring-cloud-starter-gateway和spring-cloud-starter-netflix-eureka-client的坐标。

记住这里需要删除一直配置的两个依赖,否则后面会报错

spring-boot-starter-webspring-boot-starter-actuator

<parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloud-gateway-gateway9527</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</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>

(2)yaml配置文件

将9527网关服务注册进服务注册中心eureka
在这里插入图片描述
(3)主启动类

package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
 * @program: cloud2020
 * @ClassName GateWayMain9527
 * @create: 2020-11-13 19:52
 **/
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
    public static void main(String[] args) {
        SpringApplication.run(GateWayMain9527.class,args);
    }
}

(4)针对pay8001模块,通过yml给Gateway网关服务9527添加路由规则

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        # - 是yml语法,代表数组的意思
        - id: payment_route1 # 路由ID,没有固定规则,需要保证唯一
          uri: http://localhost:8001 # 路由到哪个地址,实际提供微服务的地址
          predicates:
            - Path=/payment/get/** # 路径匹配断言
        - id: payment_route2 # 路由ID,没有固定规则,需要保证唯一
          uri: http://localhost:8001 # 路由到哪个地址,实际提供微服务的地址
          predicates:
            - Path=/payment/loadbalance # 路径匹配断言
      ###访问外网百度新闻的国际新闻
        - id: payment_route3
          uri: https://news.baidu.com/guoji # 路由到哪个地址,实际提供微服务的地址
          predicates:
            - Path=/guoji # 路径匹配断言
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    register-with-eureka: true # true:将自己注册进Eureka
    fetch-registry: true # true:需要去注册中心获取其他服务地址
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

相比之前的yml,这里的yml多了Gateway结点,配置这个的目的在于隐藏localhost:8001的地址,如果想访问payment8001服务的/payment/get/**地址,之前需要访问http://localhost:8001/payment/get/1,配置了路由之后,访问http://localhost:9527/payment/get/1也可以实现,于是,原来的8001端口就隐藏了。
在这里插入图片描述
在这里插入图片描述
修改GateWay模块(9527)的配置文件:
在这里插入图片描述
这里表示,

​ 当访问localhost:9527/payment/get/1时,

​ 路由到localhost:8001/payment/get/1

(5)开始测试

启动7001,8001,9527

如果启动GateWay报错
  	可能是GateWay模块引入了web和监控的starter依赖,需要移除

访问:

​ localhost:9527/payment/get/1

predicates断言匹配后(访问指定path路径,才进行路由),就会通过路由转发到8001端口下的路径访问
在这里插入图片描述
在这里插入图片描述

2.12 GateWay配置路由的两种方式

GateWay的网关配置,除了支持配置文件yaml(上述2.11配置路由方式),还支持硬编码方式

方式一yaml:

cloud:
    gateway:
      routes:
        # - 是yml语法,代表数组的意思
        - id: payment_route1 # 路由ID,没有固定规则,需要保证唯一
          uri: http://localhost:8001 # 路由到哪个地址,实际提供微服务的地址
          predicates:
            - Path=/payment/get/** # 路径匹配断言
        - id: payment_route2 # 路由ID,没有固定规则,需要保证唯一
          uri: http://localhost:8001 # 路由到哪个地址,实际提供微服务的地址
          predicates:
            - Path=/payment/loadbalance # 路径匹配断言
      ###访问外网百度新闻的国际新闻
        - id: payment_route3
          uri: https://news.baidu.com/guoji # 路由到哪个地址,实际提供微服务的地址
          predicates:
            - Path=/guoji # 路径匹配断言

第二种配置路由方式:硬编码方式配置

uri中记得带http,否则访问不到,这里的uri可以写任意地址,代表一个路由规则,访问path路径的时候,被路由到uri地址。

(1)创建配置类

既然不用yaml,那么肯定就是config配置类
在这里插入图片描述
输入如下路径:/guoji访问到外网
在这里插入图片描述

2.13 动态路由的实现(负载均衡给8001和8002)

现在存在的问题:真实服务地址写死了(如8001写死了,访问8002还得重新写),我们应该通过服务名来找服务,而不是通过服务地址找服务。

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

为了演示网关的负载均衡,修改Provider8001和Provider8002的yml配置文件,将它们的注册地址改成eureka7001的地址。启动Eureka7001和Provider8001和Provider8002服务。修改Gateway9527模块的application.yml配置文件,修改为如下内容。因为要修改application.yml,所以先把GatewayConfig类进行屏蔽,避免产生影响。

(1)修改GateWay模块9527的配置文件yaml

主要将uri更改,uri: lb://cloud-payment-service # 使用微服务名称查找路由地址,lb是用于识别负载均衡的前缀,不能修改

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
            #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式

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

(2)测试

通过浏览器访问http://localhost:9527/payment/lb,在页面端可以看到端口号的不断变化,如果要实现负载均衡,注意uri中的lb是固定的(uri: lb://cloud-payment-service),它是识别开启负载均衡的标志。

通过网关实现负载均衡效果,不用经80消费者负载均衡
在这里插入图片描述
在这里插入图片描述

2.2 GateWay-- 断言(Pridicate)

在Gateway9527启动的时候,在Console可以看到如下内容,代表执行加载Predicate,我们目前使用的Predicate是Path。
在这里插入图片描述
在这里插入图片描述
我们之前在配置文件中配置了Path断言:
在这里插入图片描述
这个断言表示,如果外部访问路径是指定路径,就路由到指定微服务上

2.21 多种断言演示

(1)After断言

After:
		可以指定,只有在指定时间后,才可以路由到指定微服务

在这里插入图片描述
​ 这里表示,只有在2020年的2月21的15点51分37秒之后,访问才可以路由

​ 在此之前的访问,都会报404

如何获取当前时区?**
在这里插入图片描述
(2)Before和Between断言

Before:
		与after类似,他说在指定时间之前的才可以访问
Between:
		需要指定两个时间,在他们之间的时间才可以访问

在这里插入图片描述
(3)Cookie断言

Cookie:
		只有包含某些指定cookie(key,value),的请求才可以路由

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(4)Header断言

Header:
		只有包含指定请求头的请求,才可以路由
            \d+表示正数,-123就路由转发失败

在这里插入图片描述
在这里插入图片描述
测试:在这里插入图片描述
(5)Host断言

Host:
		只有指定主机的才可以访问,
		比如我们当前的网站的域名是www.aa.com
    那么这里就可以设置,只有用户是www.aa.com的请求,才进行路由

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到,如果带了域名访问,就可以,但是直接访问ip地址.就报错了

(6)Method断言

Method:
		只有指定请求才可以路由,比如get请求...

在这里插入图片描述
(7)Path断言

Path:
		只有访问指定路径,才进行路由
     比如访问,/abc才路由

在这里插入图片描述

(8)Query断言

Query:
		必须带有请求参数才可以访问  //  \d+表示正数,-123就路由转发失败

在这里插入图片描述

2.3 GateWay --过滤器(Filter)

  • 路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用,
  • Spring Cloud Gateway内置了多种路由过滤器,它们是通过Gateway Filter Factory工厂类产生的。
2.31 生命周期

从生命周期来分类,可以分为Pre和Post,类似于Spring AOP的前置通知和后置通知。

从种类上来分类,可以分为Gateway Filter单一过滤器和Global Filter全局过滤器。具体可以参考官网,这个的配置也是在application.yml里加配置即可。

Gateway Filter:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/#gatewayfilter-factories

Global Filter:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/#global-filters

在请求进入路由之前,和处理请求完成,再次到达路由之前

2.32 单一和全局过滤器

在这里插入图片描述
(1)GateWayFilter,单一的过滤器

与断言类似,比如闲置,请求头,只有特定的请求头才放行,反之就过滤
在这里插入图片描述
(2)GlobalFilter,全局过滤器

一般我们都使用自定义过滤器

实现两个接口
在这里插入图片描述
然后启动服务,即可,因为过滤器通过@COmponet已经加入到容器了

如果请求时uname!=null,则不会过滤,路由就会转发到指定路径访问,路径必须加上uname=123/jh/…
在这里插入图片描述
进入filter过滤
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值