1.SpringCloud Gateway 介绍
Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
**对比zuul:**
-  功能 Gateway内部实现了限流、负载均衡等,扩展性更强 
-  异步支持 zuul仅支持同步,gateway支持异步 
-  性能 Zuul1.X是阻塞的,Gateway是非阻塞的,Gateway性能更好 
-  选型建议 Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul 新项目建议采用Gateway,但老项目已采用Zuul不建议替换 
**相关概念:**
-  Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。 
-  Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。 
-  Filter(过滤器):这是 org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。

2. 搭建Gateway
2.1 创建Maven Module
2.2 pom
==gateway基于webflux,注意不要引入web依赖==
<dependencies>
<!-- gateway依赖 -->
<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>
<!-- 如果springboot是1.5.X版本 <artifactId>spring-cloud-starter-eureka</artifactId> -->
</dependency>
</dependencies>
2.3 yml
server:
   port: 8111
   
 spring:
   cloud:
     gateway:
       routes:
       - id: emall-emp-consumer       
         uri: lb://emall-emp-consumer  # lb代表从注册中心获取服务
         predicates:
         - Path=/emall-emp/**  
         filters:
         - StripPrefix=1  # 如果去除掉前面两个前缀,则值为2,类推
         
         
 eureka:
   client:
     register-with-eureka: false
     service-url:
       defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
           
2.4 启动类
@SpringBootApplication
 @EnableEurekaClient
 public class GatewayApp {
     public static void main(String[] args) {
         SpringApplication.run(KmallGatewayApp.class, args);
     }
 }
3. 微服务名称转发
spring:
   cloud:
     gateway:
       discovery:
         locator:
           enabled: true
           lower-case-service-id: true
4. 全局过滤
@Component
 public class MyGatewayFilter implements GlobalFilter, Ordered {
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         System.out.println("进入过滤器...");
         // 判断请求token
         // 获取请求对象request
         ServerHttpRequest request = exchange.getRequest();
         /*List<String> tokens = request.getHeaders().get("kgc-token");
         System.out.println("tokens: " + tokens);
         if(tokens == null || tokens.size()==0){
             exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
             return  exchange.getResponse().setComplete();
         }*/
         String token = request.getHeaders().getFirst("kgc-token");
         if(token == null){
             exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
             
             // 直接返回
             //return exchange.getResponse().setComplete();
             
             // 返回json
             Result result = new Result(20001,"token无效,请重新登录",null);
             DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(JSONObject.toJSON(result).toString().getBytes());
             ServerHttpResponse response = exchange.getResponse();
             response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
             return response.writeWith(Mono.just(buffer));
         }
        
         return chain.filter(exchange);
     }
    @Override
     public int getOrder() {
         return 0;
     }
 }









