尚硅谷—Cloud—GetWay 新一代网关(66~73)

一:概念简介(技术选型-重要)
二:三大核心概念
三:Gateway 工作流程
四:入门配置
五:通过 微服务名 实现动态路由
六:Predicate 的使用
七:Filter 的使用

一:概念简介(技术选型-重要)

             1)官网:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter

             2)是什么:
                           a:Spring Cloud 全家桶中,有个很重要的组件,就是网关(Getway):在 1.x 版本中都是采用的 Zuul 网关。
                           b:2.x 中,使用 SpringCloud Getway 代替了 Zuul。
                                       (netty视频:https://www.bilibili.com/video/BV1DJ411m7NR)(韩顺平)
                           c:一句话:SpringCloud Getway 使用的 WebFlux 框架实现的,而 WebFlux 框架底层使用了 高性能的 Reactor 模式通信框架 Netty;(异步非阻塞,性能高)





             3)能干嘛:
                           a:反向代理:
                           b:鉴权:
                           c:流量控制:
 
                          d:熔断:重试、安全、
                           e:日志监控/指标:
                           f:。。。。。


             4)微服务架构中,网关在哪里:(网关是 所有 为服务的 入口)



             5)有 Zuul 了,怎么又来了 Getway:
                           a:为什么我们选择 Getway:
                                - SpringCloud Getway 特性:(Getway:异步非阻塞模型)


                                - SpringCloud Getway 与 Zuul 区别:



                           b:Zuul 1.x 模型:




                           c:GetWay 模型:(WebFlux)(异步非阻塞)



 

二:三大核心概念

             1)Route(路由)概念:


             2)Predicate(断言)概念:


             3)Filter(过滤)概念:


             4)总体:





 

三:Gateway 工作流程

             1)官网总结




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



 

四:入门配置

             1)新建 Module:cloud-getway-getway-9527
             2)POM:(不能有 web 依赖)

    <dependencies>

        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
        </dependency>

        <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>
</project>


             3)YML:

server:
  port: 9527

spring:
  application:
    name: cloud-getway-getway-9527

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


             4)业务类:无

             5)主启动类:

@EnableEurekaClient
@SpringBootApplication
public class GetwayGetway9527 {

    public static void main(String[] args) {
        SpringApplication.run(GetwayGetway9527.class, args);
    }

}


             6)9527 网关,如何做路由映射:
                           a:cloud-provider-payment-8001 看看Controller的 访问地址:(localhost:8001/getPayment?id=1)
                           b:我们不想暴露 8001 端口,希望在 8001 外面套一层 9527:

             7)YML 新增网关配置:

server:
  port: 9527

spring:
  application:
    name: cloud-getway-getway-9527

  cloud:
    gateway:
      routes:  # 路由:(id、目标URL、断言和过滤器)
        - id: payment_route  # 路由的 id:没有固定规则但要求 唯一,建议配合 服务名
          uri: http://localhost:8001  # 断言 匹配后,提供服务的 路由地址
          predicates: # 断言:请求 和 断言 匹配的,则进行路由
            - Path=/getPayment/**

        - id: payment_route_2
          uri: http://localhost:8001
          predicates:
            - Path=/create/**

eureka:
  instance:
    hostname: cloud-getway-service
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
spring:
  cloud:
    gateway:
      routes:  // # 路由:(id、目标URL、断言和过滤器)
        - id: payment_route // # 路由的 id:没有固定规则但要求 唯一,建议配合 服务名
          uri: http://localhost:8001 // # 断言 匹配后,提供服务的 路由地址
          predicates: // # 断言:请求 和 断言 匹配的,则进行路由
            - Path=/getPayment/**





             8)测试:

                           a:正常访问:(localhost:8001/getPayment?id=1
                           b:通过网关访问:(localhost:9527/getPayment?id=1)(都能访问到)


             9)YML 配置说明:
                           a:Getway 网关路由有两种配置方式:
                                     1.在 配置文件 yml 中配置:(前面的配置)
                                     2.代码中 注入 RouteLocator 的 Bean:(编码方式)

             10)编码方式 进行 网关配置:
                           a:官网案例:



                           b:百度国内新闻地址,需要外网:
                           c:自己写一个:

@Configuration
public class GetwayConfig {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder) {

        // 访问:  http://localhost:9527/guonei
        // 跳转到:https://news.baidu.com/guonei
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_baidu", (r) -> r.path("/guonei")
                .uri("https://news.baidu.com/guonei")).build();

        return routes.build();
    }

}






 

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


 

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

             2)启动:7001/7002 + 8001/8002 + getway
             3)POM:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>


             4)YML:

spring:
  application:
    name: cloud-getway-getway-9527

  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  # 开启从 注册中心,动态创建路由的功能,利用为服务名进行路由。

      routes: # 路由:(id、目标URL、断言和过滤器)
        - id: payment_route  # 路由的 id:没有固定规则但要求 唯一,建议配合 服务名
          uri: lb://CLOUD-PROVIDER-PAYMENT  # 断言 匹配后,提供服务的 路由地址
          predicates: # 断言:请求 和 断言 匹配的,则进行路由
            - Path=/paymentInfo_OK/**

        - id: payment_route_2
          uri: lb://CLOUD-PROVIDER-PAYMENT
          predicates:
            - Path=/create/**



             5)测试:(localhost:9527/getPayment?id=1)通过gateway 实现了 负载均衡。


 

六:跨域问题:

             1)跨域问题:
                           a:跨域:指的是浏览器不能执行 其他网站脚本。它是由 浏览器 同源策略 造成的,是 浏览器对 JavaScript 施加的安全限制。
                           b:同源策略:协议、域名、端口;都要相同,其中有一个不同,就会产生跨域。
             2)跨域流程:

             3)解决跨域:(网关中统一配置跨域)

 

/**
 * @author Zhang Xudong
 * @date 2021/3/5 11:35 上午
 */
@Configuration
public class GuliMailCrosConfig {

    @Bean
    public CorsWebFilter corsWebFilter() {

        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();

        /* 配置跨域 */
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.setAllowCredentials(true);

        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);

        CorsWebFilter corsWebFilter = new CorsWebFilter(urlBasedCorsConfigurationSource);

        return corsWebFilter;

    }
}




 

六:Predicate 的使用

             1)是什么:启动 9527
                           a:启动中会显示如下:就有这么断言的方式。(11种)


             2)Route Predicate Factories 是什么:



             3)常用的 Route Predicate:
                      1.After:规定时间之后:2021-05-26T15:21:50.293+08:00[Asia/Shanghai]
                            --获取时间:
                      2.Before:规定时间之前
                      3.Between:规定区间时间之内

                      4.Cookie:规定携带什么样Cookie 才匹配:- Cookie=chocolate, ch.p(也就是 K:V)
                              
                               测试:curl  http://localhost:9527/discover --cookie "username=zhangsan"

                      5.Header:
规定携带什么样 Header 才匹配: - Header=X-Request-Id, \d+(K,V)

                      6.Host:根据主机进行拦截:- Host=**.somehost.org,**.anotherhost.org
                                        

                      7.Method:
根据请求方法类型进行拦截:- Method=GET,POST:
                                        

                      8.Path:根据请求路径进行拦截:- Path=/red/{segment},/blue/{segment}

                      9.Query:带查询条件,要带参数查询条件,值为参数才进行拦截:- Query=red, gree

                      10.小总结:
                               - 说白了,Predicate 就是为了实现一组匹配规则,让请求过来,找到我们对应的路由,进行处理。


 

七:Filter 的使用

             1)是什么:




             2)SpringCloud Gateway 的 Filter:
                           a:生命周期,Only Two:
                       
             - pre:前置拦截
                                     - post:后置拦截

                           b:种类,Only Two:(不需要,都是自定义类,实现借口)
                         
           - Gateway Filter:(31种之多)
                                     - Global Filter:(10 种之多)

             3)常见的 GatewayFilter:



             4)自定义 过滤器:(自定义全局 Global Filter )
                           a:两个主要接口介绍:
                                    - implements GlobalFilter ,Orderd
                           b:能干嘛:
                   
                - 全局日志记录:
                                    - 统一网关鉴权(权限校验):
                                    - 流量监控:
                                    - 参数校验:
                                    - 。。。。。


                           c:案例代码:(判断请求是不是每次都带着 username 参数)
                                    - 自定义 日志实现类:继承两个接口:

@Slf4j
@Component
public class MyLogGatewayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        System.out.println("come in MyLogGatewayFilter" + new Date());

        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if (username == null) {
            System.out.println("用户名为 null,非法");
            exchange.getResponse().setStatusCode(HttpStatus.MULTI_STATUS);
            return exchange.getResponse().setComplete();
        }
        //继续传下去
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //过滤链,数字越小,优先级越高。Ordered.HIGHEST_PRECEDENCE
        return 0;
    }

}


                           d:测试:(localhost:9527/getPayment?username=11)






 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值