springClould之Gateway服务网关

  • 中文官网文档:

https://www.springcloud.cc/spring-cloud-greenwich.html#_spring_cloud_gateway

一、前奏

1.1、什么是服务网关

  • PI Gateway(APIGW / API 网关),顾名思义,是出现在系统边界上的一个面向 API 的、串行集中式的强管控服务,这里的边界是企业 IT 系统的边界,可以理解为企业级应用防火墙,主要起到隔离外部访问与内部系统的作用。在微服务概念的流行之前,API 网关就已经诞生了,例如银行、证券等领域常见的前置机系统,它也是解决访问认证、报文转换、访问统计等问题的。
  • API 网关的流行,源于近几年来移动应用与企业间互联需求的兴起。移动应用、企业互联,使得后台服务支持的对象,从以前单一的Web应用,扩展到多种使用场景,且每种使用场景对后台服务的要求都不尽相同。这不仅增加了后台服务的响应量,还增加了后台服务的复杂性。随着微服务架构概念的提出,API网关成为了微服务架构的一个标配组件。
  • API 网关是一个服务器,是系统对外的唯一入口。API 网关封装了系统内部架构,为每个客户端提供定制的 API。所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有非业务功能。API 网关并不是微服务场景中必须的组件,如下图,不管有没有 API 网关,后端微服务都可以通过 API 很好地支持客户端的访问。

在这里插入图片描述
但对于服务数量众多、复杂度比较高、规模比较大的业务来说,引入 API 网关也有一系列的好处:

  1. 性能:API 高可用,负载均衡,容错机制。
  2. 安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
  3. 日志:日志记录,一旦涉及分布式,全链路跟踪必不可少。
  4. 缓存:数据缓存。
  5. 监控:记录请求响应数据,API 耗时分析,性能监控。
  6. 限流:流量控制,错峰流控,可以定义多种限流规则。
  7. 灰度:线上灰度部署,可以减小风险。
  8. 路由:动态路由规则。
  9. 黑名单等

1.2、什么是Gateway

  • Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的 网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
  • Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。比如内置了 10 多种Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便

1.3、 Gateway和Zuul的性能比较

  • Spring Cloud Gateway基于Spring 5、Project Reactor、Spring Boot 2,使用非阻塞式的API,内置限流过滤器,支持长连接(比如 websockets),在高并发和后端服务响应慢的场景下比Zuul1的表现要好。

  • Zuul基于Servlet2.x构建,使用阻塞的API,没有内置限流过滤器,不支持长连接。

1.4、Nginx与网关的区别

1.4.1、相同点

都是可以实现对api接口的拦截,负载均衡、反向代理、请求过滤等,可以实现和网关一样的效果;

1.4.2、不同点

  • Nginx采用C语言编写的,在微服务领域中,都是自己语言编写的,比如我们使用java构建微服务项目,Gateway就是java语言编写的。毕竟Gateway属于Java语言编写的, 能够更好对微服务实现扩展功能,相比Nginx如果想实现扩展功能需要结合Nginx+Lua语言等。

  • Nginx属于服务器端负载均衡器,而Gateway采用本地负载均衡器的形式。

二、使用

2.1依赖、yml配置

2.1.1、 依赖

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

注意: 如果引入了Gateway的依赖,就不能引入 spring-boot-starter-web 的依赖,否则会报错!!!

2.1.2、 yml配置

    name: gateway_test   cloud:
    gateway:
      routes:
        - ##路由Id,唯一
       - id: test1
         ##转发的uri
         uri: http://localhost:8081
         ##断言
         predicates:
           #path的路径会加到uri后边,比如访问http:/test1/getXXX,那么路由转发的地址就为http://localhost:8081/test1/getXXX
           - Path=/test1/ **(注意**前边没有空格,因为连着在markdown做笔记的样式有问题,所以加了一个)
       - id: test2
         ##  uri以lb://开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称
         uri: lb://test2
         predicates:
           #path的路径会加到uri后边,
           - Path=/test2/**`

2.2 断言

断言的类型如下(具体使用看文档,最上边):
在这里插入图片描述

2.3 过滤器

Spring Cloud Gateway 根据作用范围划分为 GatewayFilterGlobalFilter,二者区别如下:
GatewayFilter:网关过滤器,需要通过 spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过 spring.cloud.default-filters 配置在全局,作用在所有路由上。
GlobalFilter:全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter 包装成 GatewayFilterChain 可识别的过滤器,它为请求业务以及路由的 URI 转换为真实业务服务请求地址的核心过滤器,不需要配置系统初始化时加载,并作用在每个路由上。

2.3.1 全局过滤局使用

/**
 * @author ly
 */
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {

    private static final int order=1;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("in MyGlobalFilter..");
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        MultiValueMap<String, String> params = request.getQueryParams();
        List<String> nameList = params.get("token");
        if (nameList != null) {
            /*
             .....一系列验证代码
             */
            //chain.filter(exchange);表示放行,这里
            return chain.filter(exchange);
        }
        //返回前端消息(不放行)
        DataBuffer buffer = response.bufferFactory().wrap("亲,没有token数据哟".getBytes());
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //指定编码,否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 指定顺序
     *
     */
    @Override
    public int getOrder() {
        return order;
    }
}

2.3.2 GatewayFilter

  • 网关过滤器用于拦截并链式处理 Web 请求,可以实现横切与应用无关的需求,比如:安全、访问超时的设置等。修改传入的 HTTP 请求或传出 HTTP 响应。Spring Cloud Gateway 包含许多内置的网关过滤器工厂一共有 22 个,包括头部过滤器、 路径类过滤器、Hystrix 过滤器和重写请求 URL 的过滤器, 还有参数和状态码等其他类型的过滤器。根据过滤器工厂的用途来划分,可以分为以下几种:Header、Parameter、Path、Body、Status、Session、Redirect、Retry、RateLimiter 和 Hystrix。
    在这里插入图片描述
    具体的使用看官方文档(最上边)
(1) 定义filter

实现GatewayFilter接口,代码如下

/**
 * @author ly
 */
public class MyGateFilter implements GatewayFilter, Ordered {
    
    private static final int ORDER = -1;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("in MyGateFilter..");
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        HttpMethod method = request.getMethod();
        if (!HttpMethod.POST.equals(method.name())) {
            DataBuffer buffer = response.bufferFactory().wrap("请用post方法调用接口".getBytes());
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //指定编码,否则在浏览器中会中文乱码
            response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return response.writeWith(Mono.just(buffer));
        }
        //放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return ORDER;
    }
}
(2)配置路由
/**
 * @author ly
 */
@Configuration
public class RouteLocatorConfig {
    
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder) {
        return routeLocatorBuilder.routes().route(r ->
                r.path("/test2/**")
                        .uri("lb://test2")
                        .id("test2")
                        .filter(new MyGateFilter()))
                .build();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值