网关gateway

  1. 服务网关在完成客户端与服务器端报文格式转换的同时,它可能还具有身份验证、监控、缓存、请求管理、静态响应处理等功能。另一方面,也可以在网关层制定灵活的路由策略。针对一些特定的 API,我们需要设置白名单、路由规则等各类限制。

  2. spring cloud中通常使用Gateway

    • 能够匹配任何请求属性上的路由;

    • 断言和过滤器特定于路由;

    • Hystrix、sentinel集成;

    • Spring Cloud DiscoveryClient的集成

    • 易于编写的谓词和过滤器;

    • 请求速率限制;

    • 路径改写;

  3. Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关,提供一种简单而高效的方法来将请求路由到API。网关作为流量的入口,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。

  4. gateway的搭建

    • 单独的一个module,引入相关依赖
    <!-- 配置管理服务 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!-- 服务发现,也要注册到nacos中 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--spring-cloud-starter-gateway 网关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    
    • 配置文件的编写
    spring:
      application:
        #服务名字
        name: gateway
      cloud:
        # 服务发现
        nacos:
          discovery:
            server-addr: localhost:8448
            namespace: ${spring.profiles.active}
            file-extension: yaml      
            username: nacos
            password: nacos
        #配置网关
        gateway:
          discovery:
            locator:
              #启用DiscoveryClient网关集成,可以实现服务的发现
              enabled: true 
    
          #配置网关路由转发规则
          routes:
              # 路由的id唯一
            - id: route1
              # 服务地址 lb:负载均衡
              uri: lb://userservice
              # #断言 是否匹配
              predicates: 
                #- Path:匹配的路径
                - Path=/user/**
                #- After=2020-08-15T22:35:25.335+08:00[Asia/Shanghai]
                #- Before=2020-09-15T17:35:25.335+08:00[Asia/Shanghai]
                #- Between=2020-08-13T17:35:25.335+08:00[Asia/Shanghai], 2020-08-14T17:35:25.335+08:00[Asia/Shanghai]
                #- Cookie=token, 123456
                #- Header=X-Request-Id, \d+
                #- Query=token
                #- Token=123456
                #- AccessTime=下午6:00, 上午6:00
                # 过滤器
              # filters:
                  # 请求头过滤
              #   - AddRequestHeader=X-Request-red, blue
                  # 请参数过滤
              #   - AddRequestParameter=color, red
    
  5. 路由断言工厂

    • Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。 Spring Cloud Gateway包括许多内置的路由断言工厂。 所有这些断言都与HTTP请求的不同属性匹配。 您可以将多个路由断言工厂与逻辑和语句结合使用。

  6. 过滤器

    • 路由过滤器允许以某种方式修改传入的HTTP请求或传出HTTP响应。路由过滤器的作用域是特定的路由。SpringCloudGateway包含许多内置网关过滤器工厂。
    • 针对某个服务的
    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_header_route
            uri: https://example.org
            filters:
            - AddRequestHeader=X-Request-red, blue
    
    • 设置全局过滤器
    spring:
      cloud:
        gateway:
          default-filters:
          - AddResponseHeader=X-Response-Default-Red, Default-Blue
          - PrefixPath=/httpbin
    
  7. 可自定义业务逻辑的Global Filters全局过滤器

    @Component
    public class CustomGlobalFilter implements GlobalFilter, Ordered {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            log.info("custom global filter");
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {
            return -1;
        }
    }
    
  8. 过滤器的执行顺序:通过Order值进行排序执行,Order值越小越先执行

    • 两个GlobalFilter类型的过滤器Order值相同时,根据文件名字母排序,文件名靠前的优先更高。
    • GlobalFilter类型和GatewayFilter类型的过滤器Order值相同时,GlobalFilter类型优先更高。
  9. 跨域问题的解决

    • 域名不一致就是跨域。
    • 跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题。
    • 解决方案:CORS

    CORS(跨域资源共享)是一种用于在Web浏览器和服务器之间进行跨域 HTTP 请求的机制。在 Web 开发中,浏览器的同源策略(Same-Origin Policy)限制了从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。CORS 允许服务器指定哪些源(域)有权访问其资源,以及哪些HTTP方法(例如GET、POST)和头信息是允许的。

    通过在 HTTP 响应头中添加 CORS 相关的头信息,如 Access-Control-Allow-Origin,服务器可以告知浏览器哪些源是被允许的。这允许跨域的 Ajax 请求和其他跨域资源请求变得安全可行,同时仍然受到一定的限制,确保了 Web 应用的安全性。CORS 是现代 Web 应用中解决跨域请求问题的一种标准化方式。

    • 创建全局过滤器
    @Configuration
    public class CorsFilter {
     
        @Bean
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public GlobalFilter corsFilter() {
            return (exchange, chain) -> {
                ServerWebExchange.Builder webExchangeBuilder = exchange.mutate();
                webExchangeBuilder
                        .request(exchange.getRequest())
                        .response(exchange.getResponse());
     
                webExchangeBuilder
                        .response(exchange.getResponse()
                                .mutate()
                                .header("Access-Control-Allow-Origin", "*")
                                .header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS")
                                .header("Access-Control-Allow-Headers", "Content-Type")
                                .build());
     
                return chain.filter(webExchangeBuilder.build());
            };
        }
    
    • 编写配置文件
    spring:
        cloud:
            gateway:
              # 
              globalcors: # 全局的跨域处理
                add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
                corsConfigurations:
                  '[/**]':
                    allowedOrigins: # 允许哪些网站的跨域请求 
                      - "http://localhost:8090"
                      - "http://localhost:8081"
                    allowedMethods: # 允许的跨域ajax的请求方式
                      - "GET"
                      - "POST"
                      - "DELETE"
                      - "PUT"
                      - "OPTIONS"
                    allowedHeaders: "*" # 允许在请求中携带的头信息
                    allowCredentials: true # 是否允许携带cookie
                    maxAge: 360000 # 这次跨域检测的有效期
    
posted @ 2024-05-24 11:25  Hanyta  阅读(8)  评论(0编辑  收藏  举报