zoukankan      html  css  js  c++  java
  • Gateway 网关

    一、是什么

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

    SpringCloud Gateway是SpringCloud的一个全新项目,基于Spring5.0+SpringBoot2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。

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

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

    二、微服务架构中网关在哪里

    三、三大核心概念

    • Route(路由)
      • 路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
    • Predicate(断言)
      • 参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
    • Filter(过滤)
      • 指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

    四、Gateway工作流程

    核心逻辑:路由转发+执行过滤器链

    五、入门配置

    1)新建cloud-gateway-gateway9527

    2)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>cloud2020</artifactId>
            <groupId>com.atguigu.springcloud</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.atguigu.springcloud</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>
    pom文件

    3)YML

    server:
      port: 9527
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
              uri: http://localhost:8001   #匹配后提供服务的路由地址
              predicates:
                - Path=/payment/get/**   #断言,路径相匹配的进行路由
    
            - id: payment_routh2
              uri: http://localhost:8001
              predicates:
                - Path=/payment/lb/**   #断言,路径相匹配的进行路由
    
    
    eureka:
      instance:
        hostname: cloud-gateway-service
      client:
        service-url:
          register-with-eureka: true
          fetch-registry: true
          defaultZone: http://eureka7001.com:7001/eureka

    4)主启动类

    package com.atguigu.springcloud;
    
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class GateWayMain9527 {
        public static void main(String[] args) {
                SpringApplication.run( GateWayMain9527.class,args);
            }
    }

    5)YML新增网关配置

    9527网关如何做路由映射哪——见上面的红色加粗配置

    6)测试

    • 启动7001
    • 启动8001:cloud-provider-payment8001
    • 启动9527网关
    • 添加网关前:http://localhost:8001/payment/get/31
    • 添加网关后:http://localhost:9527/payment/get/31

    访问说明

    六、Gateway网关路由两种配置方式

    除了上面的一种方式,还有一种方式:代码中注入RouteLocator的Bean

    GateWayConfig类

    package com.atguigu.springcloud.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_rote_atguigu", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
            return routes.build();
        }
    }

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

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

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

    修改YML文件

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

    测试:http://localhost:9527/payment/lb

    八、Predicate的使用

    1、Route Predicate Factories这个是什么?

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

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

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

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

    2、常用的Route Predicate

    • After Route Predicate

    • Before Route Predicate

    • Between Route Predicate

    • Cookie Route Predicate

    • Header Route Predicate

    • Host Route Predicate

    • Method Route Predicate

    • Path Route Predicate

    • Query Route Predicate

     All配置

    server:
      port: 9527
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true  #开启从注册中心动态创建路由的功能,利用微服务名进行路由
          routes:
            - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
              #uri: http://localhost:8001   #匹配后提供服务的路由地址
              uri: lb://cloud-payment-service
              predicates:
                - Path=/payment/get/**   #断言,路径相匹配的进行路由
     
            - id: payment_routh2
              #uri: http://localhost:8001   #匹配后提供服务的路由地址
              uri: lb://cloud-payment-service
              predicates:
                - Path=/payment/lb/**   #断言,路径相匹配的进行路由
                #- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
                #- Cookie=username,zhangshuai #并且Cookie是username=zhangshuai才能访问
                #- Header=X-Request-Id, d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式
                #- Host=**.atguigu.com
                #- Method=GET
                #- Query=username, d+ #要有参数名称并且是正整数才能路由
     
    eureka:
      instance:
        hostname: cloud-gateway-service
      client:
        service-url:
          register-with-eureka: true
          fetch-registry: true
          defaultZone: http://eureka7001.com:7001/eureka

    九、Filter的使用

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

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

    1、Spring Cloud Gateway的Filter 

    2、自定义过滤器

    用于全局日志记录、统一网关鉴权

    package com.atguigu.springcloud.filter;
    
    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.util.StringUtils;
    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("username");
            if (StringUtils.isEmpty(uname)) {
                log.info("*****用户名为Null 非法用户,(┬_┬)");
                exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//给人家一个回应
                return exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    }

    没有添加username就会报错

  • 相关阅读:
    nodeName,nodeValue未知 xml 入库方案 The ElementTree iterparse Function
    如何:执行大型 XML 文档的流式转换 大XML文件解析入库的一个方法
    python curl_get-pip.py Installing with get-pip.py
    iptables List the rules in a chain or all chains
    goroutine 分析 协程的调度和执行顺序 并发写 run in the same address space 内存地址 闭包 存在两种并发 确定性 非确定性的 Go 的协程和通道理所当然的支持确定性的并发方式(
    数据库业界
    The MEAN stack is a modern replacement for the LAMP (Linux, Apache, MySQL, PHP/Python) stack
    Using Groovy To Import XML Into MongoDB
    虚拟机网络模式 桥接 网桥 交换机
    防止有内存泄漏并尽可能快地释放所有内存是内存管理的重要组成部分 长时间运行进程的内存泄漏
  • 原文地址:https://www.cnblogs.com/jwen1994/p/14326183.html
Copyright © 2011-2022 走看看