史上最火网关系列---Spring CloudGateway!

目录

1、Gateway概述

1.1 什么是API网关

1.2 Gateway的简介

核心特性

1.3 为什么选择Gateway网关

Gateway和Zuul的对比

2、Gateway使用

 3、网关的工作流程

4、Predicate断言工厂

5、Gateway Filter使用

5.1 Filter Factories局部过滤器

5.2 GlobalFilter全局过滤器

 6、跨域


1、Gateway概述

1.1 什么是API网关

API网关就是指系统的统一入口,提供内部服务的路由中转,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等。提供防攻击、防重放、请求加密、身份认证、权限管理、流量控制等多重手段保证API安全,降低API开放风险。

简单说:API网关就是各系统的管理工具,拦截任意的恶意请求,加上认证、授权、限流、监控等功能。

1.2 Gateway的简介

官网

Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到api,并为它们提供横切关注点,例如:安全性、监控/指标和弹性。基于Spring Framework 5, Project Reactor和Spring Boot 2.0构建;能够匹配任何请求属性的路由;谓词和过滤器是特定于路由的;断路器集成;Spring Cloud DiscoveryClient集成;请求速率限制;路径重写。

核心特性
  • 权限控制:网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。
  • 请求路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。
  • 限流 :当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。

1.3 为什么选择Gateway网关

Gateway和Zuul的对比

Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。

Zuul 1.x:Netflix开源的网关,基于Servlet框架构建。一个线程处理一次连接请求,这种方式在内部延迟严重、设备故障较多情况下会引起存活的连接增多和线程增加的情况发生。

Zuul 2.x:采用了Netty实现异步非阻塞编程模型,每个 CPU 核一个线程,处理所有的请求和响应,请求和响应的生命周期是通过事件和回调来处理的,这种方式减少了线程数量,因此开销较小。

gateway:Spring Cloud Gateway 基于Spring Boot 2.x、Spring WebFlux和Project Reactor,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。

2、Gateway使用

新建gateway-server模块

  • pom.xml
<!-- gateway网关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!-- nacos-discovery服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
  • 主启动类GatewayApplication
@SpringBootApplication
public class GatewayApplication {

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

}
  • application.yml
server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway  # 网关服务名称
  cloud:
    nacos:
      server-addr: localhost:8848  # nacos地址
    gateway:
      routes: # 网关路由
        - id: user-service  # 路由唯一id
          uri: lb://userservice  # 路由目标路径,lb负载均衡
          predicates:   # 路由断言,判断请求是否符合路由规则条件
            - Path=/user/**  # 路由路径匹配

通过访问网关端口10010,测试localhost:10010/user/{id},并且负载均衡不同服务上~

 3、网关的工作流程

 总结:用户发起的请求根据网关路由id判断路由规则条件是否符合服务的路由断言的路径匹配,由Gateway的Handler处理器发送到实际的服务处理业务逻辑。根据负载均衡转发到各自的服务实例上。从nacos注册中心上拉取服务实例。

4、Predicate断言工厂

Spring Cloud Gateway包括许多内置的路由谓词工厂。所有这些谓词都匹配HTTP请求的不同属性。可以将多个路由谓词工厂与逻辑和语句组合在一起。参考官网Predicate:

解释

实例

After

是某个时间点后的请求

- After=2037-01-20T17:42:47.789-07:00[America/Denver]

Before

是某个时间点之前的请求

- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

Between

是某两个时间点之前的请求

- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]

Cookie

请求必须包含某些cookie

- Cookie=chocolate, ch.p

Header

请求必须包含某些header

- Header=X-Request-Id, \d+

Host

请求必须是访问某个host(域名)

-Host=.somehost.org,.anotherhost.org

Method

请求方式必须是指定方式

- Method=GET,POST

Path

请求路径必须符合指定规则

- Path=/red/{segment},/blue/**

Query

请求参数必须包含指定参数

- Query=name, Jack或者- Query=name

RemoteAddr

请求者的ip必须是指定范围

- RemoteAddr=192.168.1.1/24

Weight

权重处理

主要需要熟练使用Path路由规则~~

5、Gateway Filter使用

5.1 Filter Factories局部过滤器

Spring Cloud Gateway包括许多内置的GatewayFilter工厂

  •  AddRequestHeader请求头过滤器
          filters:   # 局部过滤器
            - AddRequestHeader=Truth,hfnu science is awesome!   # 添加请求头
  • default-filters默认过滤器
default-filters:   # 默认过滤器
            - AddRequestHeader=Truth,hfnu science is awesome!

5.2 GlobalFilter全局过滤器

 全局过滤器就是处理一切进入网关的请求和微服务响应。

自定义全局请求过滤器filter/MyAuthorizeFilter

@Order(-1)
@Component
public class MyAuthorizeFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取当前请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        //2.获取authorization参数
        String authorization = params.getFirst("authorization");
        //3. 校验
        if ("admin".equals(authorization)){
            //放行
            return chain.filter(exchange);
        }
        //4.拦截
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        return exchange.getResponse().setComplete();
    }
}

 请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器:

 过滤器@Order(-1)的值越小,优先级越高,执行顺序越靠前。过滤器的order值一样时,会按照 默认过滤器defaultFilter > 路由过滤器 > 全局过滤器GlobalFilter

 6、跨域

简单说:浏览器客户端从一个域名的网页去请求另一个域名的资源。发生跨域问题:客户端与服务端发起的ajax请求,被客户端浏览器拦截器拦截。

CORS:(跨域资源共享)CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

gateway-server模块application.yml

globalcors:  # 全局处理跨域处理
        add-to-simple-url-handler-mapping: true   # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins:   # 允许哪些网站的跨域请求
              - "http://localhost:8090"
            allowedMethods:  # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "PUT"
              - "DELETE"
              - "OPTIONS"
            allowedHeaders:   # 允许在请求中携带的头信息
            allowCredentials: true  # 是否允许携带cookie
            maxAge: 360000   # 这次跨域检测的有效期

官方文档关于CORS:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Husp0707

你的小小点赞、关注是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值