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就会报错

  • 相关阅读:
    蓝桥网试题 java 基础练习 特殊的数字
    蓝桥网试题 java 基础练习 杨辉三角形
    蓝桥网试题 java 基础练习 查找整数
    蓝桥网试题 java 基础练习 数列特征
    蓝桥网试题 java 基础练习 字母图形
    蓝桥网试题 java 基础练习 01字串
    蓝桥网试题 java 基础练习 回文数
    蓝桥网试题 java 基础练习 特殊回文数
    Using text search in Web page with Sikuli
    each of which 用法
  • 原文地址:https://www.cnblogs.com/jwen1994/p/14326183.html
Copyright © 2011-2022 走看看