• gateway


    为什么需要网关

    网关功能:

    • 身份认证和权限校验
    • 服务路由、负载均衡
    • 请求限流

    gateway

    SpringCloudGateway 作为SpringCloud生态系统的网关,目标是为了代替zuul,zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。

    Spring Cloud Gateway 底层使用了高性能的通信框架Netty

    Gateway 由三部分组成:

    1. Filter(过滤器):
      使用它拦截和修改请求,并且对上游的响应,进行二次处理。
    2. Route(路由):
      一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
    3. Predicate(断言):
      这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。

    gateway 整合nacos

    1. 引入依赖

        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-gatewayartifactId>
        dependency>
        
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    2. 创建配置文件applicaion.yml

      server:
        port: 8070
      spring:
        application:
          name: api-gateway
        cloud:
          #gateway的配置
          gateway:
            #路由配置 [路由 就是指定当请求满足什么条件的时候转到哪个微服务]
            routes:
              - id: order_route #路由的唯一标识,路由到order
                uri: lb://order-service #需要转发的地址,lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
                #断言规则,就是路由转发要满足的条件
                predicates:
                  - Path=/order-ser/** #当请求路径满足Path指定的规则时,才进行路由转发
                  # 当客户端访问http://localhost:8070/order-ser/order/add 会路由到↓
                  #  http://localhost:8081/order-ser/order/add,这个无法访问,需要filters过滤下
                filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
                  - StripPrefix=1 # 转发之前去掉第一层路由
                  # StripPrefix的操作会将上述http://localhost:8081/order-ser/order/add 路由到
                  # http://localhost:8081/order/add
            #        - id: stock_route
          #配置nacos
          nacos:
            discovery:
              server-addr: 127.0.0.1:8848
              username: nacos
              password: nacos
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28

      路由断言工厂Route Predicate Factory
      Spring提供了11种基本的Predicate工厂:

    3. applicaion.yml简单配置

      server:
        port: 8070
      spring:
        application:
          name: api-gateway
        cloud:
          #gateway的配置
          gateway:
            discovery:
              locator:
                enabled: true #是否启动自动识别nacos服务
          #配置nacos
          nacos:
            discovery:
              server-addr: 127.0.0.1:8848
              username: nacos
              password: nacos
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

    gateway GlobalFilter全局过滤器

    添加全局过滤器

    package com.example.gateway.filters;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Component
    public class LogFilter implements GlobalFilter {
    
        Logger log = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            log.info(exchange.getRequest().getPath().value());
            return chain.filter(exchange);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    过滤器执行顺序
    DefaultFilter、当前路由的过滤器、GlobalFilter

    gateway请求日志记录

    要启用 Reactor Netty 访问日志,请设置-­Dreactor.netty.http.server.accessLogEnabled=true.
    
    • 1

    在这里插入图片描述

    gateway跨域处理

    1. 配置文件方式 application.yml

      server:
        port: 8070
      spring:
        application:
          name: api-gateway
        cloud:
          #gateway的配置
          gateway:
            #跨域配置
            globalcors:
              cors-configurations:
                '[/**]':  # 允许跨域访问的资源
                  allowedOrigins: "*" #跨域允许来源
                  allowedMethods: #跨域允许方法
                    - GET
                    - POST
            #路由配置 [路由 就是指定当请求满足什么条件的时候转到哪个微服务]
            routes:
              - id: order_route #路由的唯一标识,路由到order
                uri: lb://order-service #需要转发的地址,lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
                #断言规则,就是路由转发要满足的条件
                predicates:
                  # 当客户端访问http://localhost:8070/order/add 会路由到↓
                  #  http://localhost:8081/order/add,这个无法访问,因为order服务添加上下午路径/myorder
                  #  需要filters过滤下
                  - Path=/order/** #当请求路径满足Path指定的规则时,才进行路由转发
                filters:
                  - PrefixPath=/myorder # 添加前缀  对应微服务需要配置context-path
                  - CheckAuth=zhangsan
          #配置nacos
          nacos:
            discovery:
              server-addr: 127.0.0.1:8848
              username: nacos
              password: nacos
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
    2. 配置类方式

      package com.example.gateway.config;
      
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.cors.CorsConfiguration;
      import org.springframework.web.cors.reactive.CorsWebFilter;
      import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
      import org.springframework.web.util.pattern.PathPatternParser;
      
      @Configuration
      public class CorsConfig {
      
          @Bean
          public CorsWebFilter corsWebFilter(){
              CorsConfiguration config = new CorsConfiguration();
              config.addAllowedMethod("*"); //允许的method
              config.addAllowedOrigin("*"); //允许的来源
              config.addAllowedHeader("*"); //允许的请求头参数
      
              //允许访问的资源
              UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
              source.registerCorsConfiguration("/**",config);
      
              return new CorsWebFilter(source);
          }
      }
      
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28

    gateway整合sentinel流控降级

    1. 添加依赖

              
              <dependency>
                  <groupId>org.springframework.cloudgroupId>
                  <artifactId>spring-cloud-starter-gatewayartifactId>
              dependency>
      
              
              <dependency>
                  <groupId>com.alibaba.cloudgroupId>
                  <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
              dependency>
      
              
              <dependency>
                  <groupId>com.alibaba.cloudgroupId>
                  <artifactId>spring-cloud-alibaba-sentinel-gatewayartifactId>
              dependency>
      
              
              <dependency>
                  <groupId>com.alibaba.cloudgroupId>
                  <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
              dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    2. 测试代码

      package com.example.order.controller;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.*;
      import org.springframework.web.client.RestTemplate;
      
      import java.util.concurrent.TimeUnit;
      
      @RestController
      @RequestMapping("/order")
      public class OrderController {
      
          @Autowired
          private RestTemplate restTemplate;
      
          @RequestMapping("/add")
          public String add(){
              System.out.println("下单成功");
              String forObject = restTemplate.getForObject("http://stock-service/stock/reduck", String.class);
              return "Hello World " + forObject;
          }
      
          @RequestMapping("/header")
          public String header(@RequestHeader("X-Request-color") String color){
              return color;
          }
      
          @RequestMapping("/flow")
          public String flow(){
              return "正常访问";
          }
      
      
          @RequestMapping("/flowThread")
          public String flowThread() throws InterruptedException {
              TimeUnit.SECONDS.sleep(2);
              System.out.println("正常访问");
              return "正常访问";
          }
      
      
          @RequestMapping("/err")
          public String err(){
              int a = 1/0;
              return "err";
          }
      
          /**
           * 热点规则,必须使用@SentinelResource
           * @param id
           * @return
           */
          @RequestMapping("/get/{id}")
          public String getById(@PathVariable("id") Integer id){
              System.out.println("正常访问");
              return "正常访问";
          }
      
          @RequestMapping("/get")
          public String get(){
              return "查询订单";
          }
      }
      
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
    3. 启动 sentinel 控制台,在控制台中进行测试

  • 相关阅读:
    使用消息队列解决RTOS多线程同时打印串口乱序问题
    Docker实战-第一章欢迎来到Docker世界
    PostgreSQL 导出数据为CSV
    SpringBoot核心知识点总结【Spring Boot 复习】
    【20221204】【每日一题】监控二叉树
    软设上午题错题知识点7
    Flink1.17 DataStream API
    操作系统绪论习题
    11.8 实现重置文件时间戳
    控制 el-tooltip 组件是否显示:有省略号显示,没有省略号不显示
  • 原文地址:https://blog.csdn.net/AliEnCheng/article/details/126523882