GateWay学习

GateWay学习

官网学习地址

官网:https://spring.io/projects/spring-cloud-gateway
3.0.3版本文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter

概述

Gateway是在spring生态系统之上构建的API网关服务,基于Spring5、Springboot2和Projext Reactor等技术。

Gateway旨在提供一种简单而有效的方式来统一对API路由进行管理,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等。

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

Gateway使用的是Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架

Gateway特性

  1. 基于Spring5、Springboot2和Projext Reactor构建
  2. 动态路由:能够匹配任何请求属性
  3. 可以对路由指定Predicate(断言)和Filter(过滤器)
  4. 集成Hystrix的熔断器功能、
  5. 集成Spring Cloud服务发现功能
  6. 易于编写的Predicate(断言)和Filter(过滤器)
  7. 请求限流功能
  8. 支持路径重写

GateWay核心概念

Route(路由):路由是构建网关的基本模块,他有ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由

Predicate(断言):开发可以匹配 HTTP请求中的所有内容(例如请求头和请求参数),如果请求与断言相匹配则进行路由转发

Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改

GateWay实操

依赖添加

<dependencies>
    <!--gateway网关,默认集成了boot-stater,所以不需要再次添加-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--eureka注册-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

yaml配置路由转发

server:
  port: 9527

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        - id: payment-service
          uri: lb://PAYMENT-SERVICE    #通过lb://注册中心服务名称,可实现负载的切换
          #uri: http://127.0.0.1:8001  #通过http://ip:port配置
          predicates: #After表示在该时间之后,此路由配置才生效
            - After=2021-08-08T18:22:43.948+08:00[Asia/Shanghai]
            #还有时间前Before、时间之间Between
            #- Cookie=chocolate, ch.p      #该cookiename和regexp(其是Java正则表达式)
            #- Header=X-Request-Id, \d+    #请求头name和一个regexp(其是Java正则表达式)
            #- Host=**.somehost.org,**.anotherhost.org   #主机名的列表patterns
            #- Method=GET,POST		#methods的参数,它是一个或多个参数
            #- Path=/red/{segment},/blue/{segment}   #路径匹配
            #。。。。。等等,用的时候再去官网找吧!
eureka:
  client:
    #true表示向注册中心注册服务
    register-with-eureka: true
    fetch-registry: true
    service-url:
      #设置Eureka Server交互的地址查询,服务查询和服务注册都需要依赖这个地址
      defaultZone: http://eureka7001.com:7001/eureka
  instance:
    instance-id: gateway        # 设置status中的名字
    prefer-ip-address: true        # 设置显示IP地址

路由超时配置

spring:
  cloud:
    gateway: #全局超时配置
      httpclient:
        connect-timeout: 1000
        response-timeout: 5000

#指定的路由超时配置
spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        - id: payment-service
          uri: lb://PAYMENT-SERVICE    #通过lb://注册中心服务名称,可实现负载的切换
          predicates: #After表示在该时间之后,此路由配置才生效
            - After=2021-08-08T18:22:43.948+08:00[Asia/Shanghai]
          metadata: #路由超时配置
            response-timeout: 200
            connect-timeout: 200

获取当前时区,用于断言配置

ZonedDateTime zdt = ZonedDateTime.now();
System.out.println(zdt);
//得到
2021-08-08T18:22:43.948+08:00[Asia/Shanghai]

启动类编写

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

通过配置类实现路由转发

@Configuration
public class GateWayConfig {

    @Bean
    public RouteLocator myRouteLocator(RouteLocatorBuilder routeBuilder){
        //配置百度的财经映射:http://news.baidu.com/finance
        //访问http:127.0.0.1:9527/finance的时候转发请求至http://news.baidu.com/finance
        return routeBuilder.routes().route("finance",url -> {
            return url.path("/finance")
                    //添加过滤、一般不用,直接设置全局过滤
//                    .filters(f -> f.addRequestHeader("header1", "header-value-1"))
                    .uri("http://news.baidu.com");
        }).build();
    }
}

全局过滤器配置

@Component
public class MyGlobalFilter implements GlobalFilter, Order {

    @Override
    public Class<? extends Annotation> annotationType() {
        return null;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
        List<String> username = queryParams.get("username");
        if(username==null||username.size()<1){
            //没有用户不允许访问
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            //抛出异常,定义全局异常处理类进行处理返回
//            return Mono.error(new Throwable("没有用户权限"));
            //直接返回
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 过滤器的执行优先级,越小先执行
     * @return
     */
    @Override
    public int value() {
        //order最小的值
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

代码参考及更多

参考:mz-gateway

更多:去看官网和源码!

posted @ 2021-08-08 19:09  幸运刘  阅读(68)  评论(0)    收藏  举报