Gateway新一代网关

Gateway新一代网关

在这里插入图片描述

zuul路由网关

zuul核心人员走了两个,zuul2的研发过久,spring公司等不及,自己研发的Gateway网关。


简介

Cloud全家桶有个狠重要的组件就是网关,在1.x版本中都是采用Zuul网关;但是在2.x版本中,zuul的升级一致跳票,SpringCloud最后自己研发了一个网关替代Zuul, 那就是SpringCloud Gateway

sada
  • Gateway是在Spring生态之上构建的API网关服务,基于Spring 5,Spring Boot 2和Project Reactor 等技术。

  • Gateway旨在提供一种简单而有效 等方式来对API 进行路由,以及提供一些强大对过滤器,例如:熔断、限流、重试等

  • Gateway 作为SpringCloud 等目标提供统一等路由方式且基于Filter 链的方式提供了网关基本的功能,例如:安全,监控。限流

  • SpringCloud Gateway 使用的Webflux中的 reactor-netty 响应式的编程,底层使用了Netty通讯框架

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

[图片上传失败...(image-7403d-1598765825600)]

因为Zuul1.0 进入了维护阶段,而且Gateway 是SpringCloud 团队开发,比Zuul更加的便捷

Gateway 是基于异步非阻塞模型上进行开发的,性能方面不需要担心

在这里插入图片描述

SpringCloud Gateway 与 Zuul 的区别

在这里插入图片描述

三大核心概念

Route (路由)
  • 路由是构建网关的基本模块,它由ID,目标URL,一系列的断言和过滤器组成,如果断言为true则匹配该路由
Predicate (断言)
  • 参考的是Java8的java.util.function.predicate
  • 开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Filter (过滤)
  • 指的是Spring框架中的GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后请求进行修改。
总体
在这里插入图片描述
  • web请求,通过一些匹配条件,定位到真正的服务节点。并在这个妆发过程的前后,进行一些精细化控制。
  • predicate就是我们匹配条件;而filter ,就可以理解为一个无所不能的拦截器,有了这两个元素,在加上目标uri,就可以实现一个具体的路由了

Gateway工作流程

(官网总结)

在这里插入图片描述

[图片上传失败...(image-47ba69-1598765825600)]


在这里插入图片描述

Demo

  1. 新建模块cloud-gateway-gateway9527
  2. 引入pom
<dependencies>
    <!--gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
    <dependency>
        <groupId>com.angenin.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <!--eureka client(通过微服务名实现动态路由)-->
    <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>
  1. yml文件
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      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:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

  1. 主启动类
@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
    public static void main(String[] args) {
        SpringApplication.run(GatewayMain9527.class, args);
    }
}

  1. 启动微服务 Eureka server 7001 client 8001 + Gateway 9527
在这里插入图片描述

[图片上传失败...(image-936c9d-1598765825600)]
通过我们 9527 网关访问 8001的接口

在这里插入图片描述

这里起到了作用

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

  1. 在配置文件中配置
    在配置文件yml中配置

  2. 在配置类中配置
    代码中注入RouteLocator的Bean

image
案例(访问百度)

新建config.GatewayConfig

package com.yxl.cloud.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

        routes.route("path_route_angenin",  //id
                r -> r.path("/guonei")  //访问 http://localhost:9527/guonei
                        .uri("http://news.baidu.com/guonei"));  //就会转发到 http://news.baidu.com/guonei
        routes.route("path_route_angenin2",  //id
                r -> r.path("/guoji")  //访问 http://localhost:9527/guoji
                        .uri("http://news.baidu.com/guoji"));  //就会转发到 http://news.baidu.com/guonji

        return routes.build();

    }
}

访问:http://localhost:9527/guonei

在这里插入图片描述

通过微服务名实现动态路由

server:
  port: 9527

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

        - id: payment_route2
          #          uri: http://localhost:8001
          uri: lb://cloud-provider-hystrix-payment
          predicates:
            - Path=/payment/lb/** #断言,路径相匹配的进行路由


eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

在这里插入图片描述

[图片上传失败...(image-7cdd7d-1598765825600)]

Predicate的使用

在这里插入图片描述

官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

在这里插入图片描述

SpringCloud Gateway 将路由匹配作为Spring WebFlux HandlerMapping 基础架构的一部分。

SpringCloud Gateway 包括许多内置的Route Predicate工厂。所有这些Predicate 都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以进行组合

SpringCloud Gateway 创建Route 对象时,使用RoutePredicateFactory 创建 Predicate,Predicate 对象可以赋值给Route。Springcloud Gateway 包含许多内置的 Route Predicate Factories.

所有这些动词 都匹配HTTP请求的不同属性,多种谓词工厂可以组合,通过逻辑and

在这里插入图片描述
简单使用
public class T2 {

    public static void main(String[] args) {
        //获取当前时间串
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now);
        //2020-06-17T11:53:40.325+08:00[Asia/Shanghai]
    }

}

[图片上传失败...(image-4201f4-1598765825600)]


在这里插入图片描述
    #指定时间前才能访问(Before)
   - Before=2020-06-17T11:53:40.325+08:00[Asia/Shanghai]
    #指定时间内才能访问(Between)
   - Between=2020-06-17T11:53:40.325+08:00[Asia/Shanghai],2020-06-17T12:53:40.325+08:00[Asia/Shanghai]

Cookie
在这里插入图片描述

yml 设置 cookie

         - Cookie=username,angenin   #带Cookie,并且username的值为angenin

不带cookie 直接访问失败


在这里插入图片描述
Header
在这里插入图片描述
#            - After=2020-06-17T12:53:40.325+08:00[Asia/Shanghai]
#            - Cookie=username,angenin   #带Cookie,username的值为angenin
            - Header=X-Request-Id, \d+   #请求头要有 X-Request-Id属性并且值为整数的正则表达式

Method

在这里插入图片描述
- Method=GET    #只允许get请求访问
总结

[图片上传失败...(image-da0657-1598765825600)]

Filter的使用

在这里插入图片描述

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。

SpringCloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生

在这里插入图片描述

GatewayFilter(31种)
Global Filter(10种)

arameter为代表。
package com.yxl.cloud.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

@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 uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(uname ==null){
            log.info("*******用户名为null,非法用户!!");
            //设置响应,不被接受
            exchange.getResponse().setStatusCode(HttpStatus.NO_CONTENT);
            return exchange.getResponse().setComplete();

    }
        //返回chain.filter(exchange),放行
        return chain.filter(exchange);
    }

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

http://localhost:9527/payment/lb?xxx=111

在这里插入图片描述


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355