天天看点

SpringCloud服务网关GatewaySpringCloud GatewayGateway三大核心概念Gateway工作流程Gateway网关的使用通过Java代码配置网关通过微服务名称实现动态路由Predicates规则过滤器(Filter)

SpringCloud Gateway

SpringCloud Gateway是Spring Cloud的一个全新项目,基于Spring5.0 + Spring Boot2.0和Project Reactor等技术开发的网关,它的宗旨是在为微服务架构提供一种简单有效的统一的API路由管理方式。

SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul,在Sptring Cloud2.0以上版本中,没有对新版本的Zuul2.0以上最新高性能版本进行集成,仍然还是使用Zuul1.0非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

Gateway三大核心概念

  • 路由:路由时候构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤组成,如果断言为true则匹配该路由
  • 断言:开发人员可以1匹配HTTP请求的所有内容,如果请求与断言匹配则进行路由
  • 过滤:指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改

Gateway工作流程

SpringCloud服务网关GatewaySpringCloud GatewayGateway三大核心概念Gateway工作流程Gateway网关的使用通过Java代码配置网关通过微服务名称实现动态路由Predicates规则过滤器(Filter)

客户端向Spring Cloud Gateway发出请求。然后再Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到Gateway Web Handler。Handler再通过制定的过滤器链来将请求发送到我们实际的服务执行业务逻辑。

Gateway网关的使用

  1. SpringBoot项目添加maven依赖
    <!--   gateway   -->
    <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>
               
  2. 配置文件添加网关路由配置
    server:
      port: 9527
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
           - id: payment_route            #路由id,自定义唯一值
             uri: http://localhost:8001   #真实提供服务的地址
             predicates:
              - Path=/payment/get/**       #断言:路径相匹配的进行路由
           - id: payment_route2
             uri: http://locahost:8001
             predicates:
              - Path=/payment/delete/**
    
    #eureka client
    eureka:
      instance:
        hostname: cloud-gateway-service
      client:
        service-url:
          register-with-eureka: true
          fetch-registry: true
          defaultZone: http://eureka1.com:7001/eureka/
               
  3. 启动类
    @SpringBootApplication
    @EnableEurekaClient
    public class GatewayApplication {
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class,args);
        }
    }
               
  4. 请求测试,通过网关访问实际接口
    SpringCloud服务网关GatewaySpringCloud GatewayGateway三大核心概念Gateway工作流程Gateway网关的使用通过Java代码配置网关通过微服务名称实现动态路由Predicates规则过滤器(Filter)

通过Java代码配置网关

可以不用上面配置文件的方法配置网关,直接在Spring中注入RouteLocator,通过Java代码实现网关路由配置

@Configuration
public class GatewayConfig {

    /**
     * spring中注入bean  RouteLocator
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        //路由配置
        routes.route("payment_route",r -> r.path("/payment/get/**").uri("http://localhost:8001")).build();
        routes.route("paymemt_route1", r -> r.path("/payment/delete/**").uri("http://localhost:8001")).build();
        return routes.build();
    }
}
           

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

Gateway注册进服务注册中心。配置文件开启动态创建路由,服务访问地址换成微服务名称

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
       - id: payment_route
         uri: lb://cloud-payment-service   # 提供服务的路由地址 lb://{服务名称}
         predicates:
          - Path=/payment/get/**
      discovery:
        locator:
          enabled: true  #开启从注册中心动态创建路由功能,利用微服务名称进行路由

#eureka client
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka1.com:7001/eureka/
           

Predicates规则

predicates:
 - Path=/payment/get/**  #服务地址
 - After=2021-03-22T20:38:31.461+08:00[Asia/Shanghai] #在这个时间之后才能访问
 - Before=2021-03-22T25:38:31.461+08:00[Asia/Shanghai] #在这个时间之前才能访问
 - Cookie=[cookiename],[正则表达式] #cookie里对应的cookiename符合正则表达式才可以访问
 - Header=[headername],[正则表达式] #请求头里对应的name符合正则才可以访问
 - Method=GET #只允许get方法请求
 - Query=[paramName],[正则表达式] #参数paramName的值必须符合正则才可以访问,比如 price,[1-9]\d+(.\d{1,2})?,参数price必须是大于0的金额才能访问
 - Host=**.baidu.com #符合的host才可以访问
           

过滤器(Filter)

路由过滤器可用于修改进入的HTTP请求和返回HTTP响应(跟web.xml配置的过滤器一样)。Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生。

自定义过滤器

/**
 * 全局自定义过滤器
 * 继承GlobalFilter,Ordered
 */
@Component
public class MyFilter implements GlobalFilter,Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取参数
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if(username == null){
            System.out.println("======非法请求======");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
            //拦截请求直接返回
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 加载过滤器的顺序,越小优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}