一、Gateway简单介绍

在微服务中,经过运用Gateway网关能够统一管理对外揭露的服务供给端口,起到服务供给内部和外部的阻隔,维护服务供给方的安全性。经过运用Gateway网关,能够进行反向署理、鉴权、流量控制、熔断和日志监控等。

Gateway三大中心概念:

  1. Route(路由):路由是构建网关的基本模块,它由ID,方针URI,一系列的断语和过滤器组成,假如断语为true则匹配该路由
  2. Predicate(断语):参考的是Java8的java.util.function.Predicate,开发人员能够匹配HTTP恳求中的一切内容(例如恳求头或恳求参数),假如恳求与断语相匹配则进行路由
  3. Filter(过滤):指的是Spring框架中GatewayFilter的实例,运用过滤器,能够在恳求被路由前或者之后对恳求进行修正。

Gateway作业原理

客户端向 Spring Cloud Gateway 发出恳求。然后在 Gateway Handler Mapping 中找到与恳求相匹配的路由,将其发送到 Gateway Web Handler。

Handler 再经过指定的过滤器链来将恳求发送到咱们实际的服务执行事务逻辑,然后回来。过滤器之间用虚线分开是因为过滤器可能会在发送署理恳求之前(“pre”)或之后(“post”)执行事务逻辑。

Filter在“pre”类型的过滤器能够做参数校验、权限校验、流量监控、日志输出、协议转换等,
在“post”类型的过滤器中能够做呼应内容、呼应头的修正,日志的输出,流量监控等有着非常重要的作用。

二、基本运用(applicaiton.yml版)

增加依赖

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

增加装备

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规矩但要求仅有,主张合作服务名
          uri: http://localhost:8001          #匹配后供给服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断语,途径相匹配的进行路由
        - id: payment_routh2 #payment_route    #路由的ID,没有固定规矩但要求仅有,主张合作服务名
          uri: http://localhost:8001          #匹配后供给服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断语,途径相匹配的进行路由
eureka:
  instance:
    hostname: cloud-gateway-service
  client: #服务供给者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

缺陷:不利于应用于集群服务

集群服务装备(动态路由)

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #敞开从注册中心动态创建路由的功用,运用微服务名进行路由
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规矩但要求仅有,主张合作服务名
          uri: lb://cloud-payment-service #匹配后供给服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断语,途径相匹配的进行路由
        - id: payment_routh2 #payment_route    #路由的ID,没有固定规矩但要求仅有,主张合作服务名
          uri: lb://cloud-payment-service #匹配后供给服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断语,途径相匹配的进行路由
eureka:
  instance:
    hostname: cloud-gateway-service
  client: #服务供给者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

三、编码版

装备路由

import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GateWayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_atguigu",
                r -> r.path("/guoji").uri("http://news.baidu.com/guonei")).build();
        return routes.build();
    }
}

四、Predicate(断语)的运用

Predicate本质上便是路由匹配条件,经过匹配特定的Predicate条件,假如为true,则匹配到方针url。说白了,Predicate便是为了实现一组匹配规矩,让恳求过来找到对应的Route进行处理。

常用的Route Predicate:

  1. After Route Predicate
  2. Before Route Predicate
  3. Between Route Predicate
  4. Cookie Route Predicate
  5. Header Route Predicate
  6. Host Route Predicate
  7. Method Route Predicate
  8. Path Route Predicate
  9. Query Route Predicate

运用实例:

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #敞开从注册中心动态创建路由的功用,运用微服务名进行路由
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规矩但要求仅有,主张合作服务名
          uri: http://localhost:8001          #匹配后供给服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断语,途径相匹配的进行路由
        - id: payment_routh2 #payment_route    #路由的ID,没有固定规矩但要求仅有,主张合作服务名
          uri: http://localhost:8001          #匹配后供给服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断语,途径相匹配的进行路由
            - After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
            - Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
            - Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] ,  2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
            #            curl http://localhost:9527/payment/lb --cookie "username=zzyy"
            - Cookie=username,zzyy   #Cookie=cookieName,正则表达式
            # 恳求头要有X-Request-Id属性并且值为整数的正则表达式 curl http://localhost:9527/payment/lb --cookie "username=zzyy" -H "X-Request-Id:11"
            - Header=X-Request-Id, \d+
            - Host=**.atguigu.com  # curl http://localhost:9527/payment/lb -H "Host:afae.atguigu.com"

五、Filter的运用

路由过滤器可用于修正进入的HTTP恳求和回来的HTTP呼应,路由过滤器只能指定路由进行运用。

Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生。

Filter品种有GatewayFilter(Gateway供给的) 、GlobalFilter(自定义的大局Filter)

自定义过滤器

package com.hlt.springcloud.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if(username == null){
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
    /**
     * 加载过滤器次序,数字越小优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}