itlihao

1. 什么是API网关

API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。

API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。

API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。

API网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:

客户端请求多个微服务,各个服务ip不一样,增加客户端复杂度。
存在跨域,在一定场景下处理相对复杂。
认证复杂,每个服务都需要独立认证。
与微服务耦合太强,微服务变更,客户端需要变更



2. 使用API网关的好处

所有的外部请求都会先经过API 网关这一层。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 API 网关来做,这样既提高业务灵活性又不缺安全性。

  • 易于监控
  • 统一认证
  • 减少客户端与微服务交互,解耦接口依赖





3. 常用网关

Nginx+lua
Zuul                              Zuul是一种提供动态路由、监视、弹性、安全性等功能的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器
SpringCoud Gateway                Spring Cloud GateWay是Spring Cloud的⼀个全新项⽬【SpringCloud公司开发的】,⽬标是取代Netflix Zuul。
                                  它基于Spring5.0+SpringBoot2.0+WebFlux(基于⾼性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能⾼于Zuul。
                                  官⽅测试,GateWay是Zuul的1.6倍,旨在为微服务架构提供⼀种简单有效的统⼀的API路由管理⽅式。





4. gateWay入门使用

4.-1 基本概念

  • 路由:路由是构建网关的基本模块,它由ID,目标URI,一系列的断言Predicates和过滤器Filters组成,如果断言为true,则匹配该路由。
  • 断言:参考Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容,例如请求头或请求参数,如果请求与断言相匹配则进行路由。
  • 过滤:Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或后对请求进行修改。基于过滤器可以实现:安全,监控,限流等问题。

4.0 创建一个服务

ip配置为80端口,当访问这个服务,就是访问我们的getWay。

# 服务端口
server.port=80
# 服务名
spring.application.name=service-gateway

4.1 请求转发的实现

导入依赖

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

添加配置文件

server:
  port: 9527

spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:               # routes 是路由,一个GateWay可以包含多个route
        - id: to-user                   # 路由的id,必须唯一 
          uri: http://localhost:8002    # 路由地址,表示目标跳转目的路径
          predicates:       # predicates  是断言,一个gateWay可以包含多个predicate
            - Path=/*/user/**           # 断言规则,表示代理什么路径

        # 上述表示:    当访问 http://localhost:9527/XX/user/XX/XX 时    会真正访问 http://localhost:8002/XX/user/XX/XX

---若有注册中心,按如下配置---

spring:
  application:
    name: springcloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848  # 当有了注册中心时,网关也是一个服务,所以需要注册到注册中心去。

    gateway:
      discovery:
        locator:
          enabled: true     # 让gateway从nacos中获取服务信息        
      routes:               # routes 是路由,一个GateWay可以包含多个route
        - id: to-user                       # 路由的id,必须唯一 
          uri: lb://springcloud-consumer    # lb 动态路由。  因为有了注册中心,uri可以不像上面那样写死了。所以这里  *****后面跟要调用的服务名称,而不再是具体哪个地址******,因为你可能用了rabbon做负载均衡,会有多个不同的端口。但是你的服务名肯定是一样的
          predicates:                       # predicates  是断言,一个ateWay可以包含多个predicate
            - Path=/*/user/**               # 断言规则,表示代理什么路径

      # 动态路由           GateWay支持动态路由。

路由断言工厂:Spring Cloud Gateway包括许多内置的路由断言工厂。所有这些断言都与HTTP请求的不同属性匹配。您可以将多个路由断言工厂与逻辑 and 语句结合使用。





4.2 跨域问题的解决

在4.1 getWay服务下,创建全局配置类:

@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);

        return new CorsWebFilter(source);
    }
}

or

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


















5. Gateway内置网关(局部)过滤器

Gateway分为Pre类型的过滤器和Post类型的过滤器。

  • Pre类型的过滤器在请求转发到后端微服务之前执行,在Pre类型过滤器链中可以做鉴权、限流等操作。
  • Post类型的过滤器在请求执行完成之后、将结果返回给客户端之前执行。

在Spring Cloud Gateway中内置了很多Filter,自定义Filter有两种实现,分别是GatewayFilter和GlobalFilter。


GlobalFilter全局过滤器会应用到所有的路由上。

GatewayFilter网关过滤器只会应用到单个路由或者一个分组的路由上。


5.1 Path路径过滤器(常用)

Path过滤器可以实现URL重写,通过重写URL可以实现隐藏真实路径提高安全性。

5.1.1 RewritePath网关过滤器

RewritePath网关过滤器工厂采用路径正则表达式参数和替换参数,使用Java正则表达式来灵活地重写请求路径。






6. Gateway内置网关(全局)过滤器

前言:全局过滤器加上网关过滤器组成过滤器链,该过滤器链的执行顺序是根据@Order注解指定的数字大小,从小到大进行排序,数字越小,优先级越高。

# 对输出响应头设置属性


spring:
  cloud:
    gateway:
     # 配置全局默认过滤器
      default-filters:
      # 往响应过滤器中加入信息
        - AddResponseHeader=token,48945165


7. Gateway自定义网关(局部)过滤器GatewayFilter

自定义(局部)网关过滤器:https://www.bilibili.com/video/BV1R7411774f?p=42&spm_id_from=pageDriver
因为Gateway提供了很多Gateway内置网关(局部)过滤器,所以一般很少使用Gateway自定义网关过滤器。



8. Gateway自定义网关(全局)全局过滤器GlobalFilter

常见需求:用户需要登录了才放行。

自定义类实现 GlobalFilter , Ordered 接口,加上@Component注解即可;

@Component
public class MyCustomerGlobalFilter implements GlobalFilter ,Ordered {

  // 参数1:ServerWebExchange是一个HTTP请求-响应交互的契约。提供对HTTP请求和响应的访问,并公开额外的服务器端处理相关属性和特性,如请求属性。
  // 参数2:用于承载请求相关的属性和请求体,Spring Cloud Gateway中底层使用Netty处理网络请求。
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    System.out.println("自定义全局过滤器"); // 在这里面做逻辑处理,判断token,并验证账号密码
    return chain.filter(exchange);
  }

  // 该方法用于声明该过滤器执行的优先级
  @Override
  public int getOrder() {   // 返回值越低,表示过滤器执行的优先级越高。
    return -2;
  }
}



分类:

技术点:

相关文章:

  • 2021-12-21
  • 2021-10-23
  • 2021-06-17
  • 2021-09-23
  • 2021-11-26
  • 2022-12-23
  • 2021-04-09
猜你喜欢
  • 2021-11-08
  • 2021-10-07
  • 2021-11-20
  • 2021-12-29
相关资源
相似解决方案