首页 > 其他分享 >7.Gateway

7.Gateway

时间:2023-05-27 13:55:28浏览次数:18  
标签:匹配 断言 gateway 限流 过滤器 Gateway 路由

8.Gateway

8.1.介绍

8.1.1.网关介绍

网关是微服务最边缘的服务,直接暴露给用户,用来做用户和微服务的桥梁

image-20230526125545541

没有网关:客户端直接访问我们的微服务,会需要在客户端配置很多的ip:port,如果user-service并发比较大,则无法完成负载均衡。

有网关:客户端访问网关,网关来访问微服务,(网关可以和注册中心整合,通过服务名称找到目标的ip:prot),这样只需要使用服务名称即可访问微服务,可以实现负载均衡,可以实现token拦截,权限验证,限流等操作。

8.1.2.Gateway简介

GatewaySpringCloud官方提供的用来取代zuul(netflix)的新一代网关组件(zuul的本质是一组过滤器,根据自定义的过滤器顺序来执行)

基于spring5.x、springboot2.x 和ProjectReactor等技术。

目地是让路由更加简单、灵活,还提供了一些强大的过滤器功能,例如:熔断、限流、重试,自义定过滤器等token校验ip黑名单等

SpringCloudGateway作为SpringCloud生态的网关,目标是替代Zuul,在SpringCloud2.0以上的版本中,没有对新版本的zuul2.0以上的最新高性能版本进行集成,仍然还是使用的zuul1.x,非Reactor模式的老版本。

为了提升网关的性能,SpringCloudGateway是基于webFlux框架实现的,webFlux框架底层则使用了高性能的Reactor模式通信框架的Netty

8.1.3.特征与功能

1.建立在SpringFramework5ProjectReactorSpringBoot2.0之上

2.能够匹配任何请求属性上的路由

3.谓词和过滤器特定于路由

4.Hystrix断路器集成。

5.SpringCloudDiscoveryClient集成

6.易于编写的谓词和过滤器

7.请求速率限制

8.路径改写

8.1.4.工作流程

image-20230526132826879

1客户端向springcloudGateway发出请求,然后在GatewayHandlerMapping 中找到与其请求相匹配的路由,将其发送到GatewayWebHandle

Handler再通过指定的过滤器来将请求发送到我们实际的服务的业务逻辑,然后返回。

过滤器之间用虚线分开是因为过滤器可能会在发送爱丽请求之前【pre】或之后【post】执行业务 逻辑,对其进行加强或处理。

Filter在【pre】类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等

在【post】类型的过滤器中可以做响应内容、响应头的修改、日志的输出,流量监控等有着非常重要的作用。

总结:核心逻辑就是路由转发+执行过滤器链

8.1.5.三大核心概念

①Route(路由)

路由信息的组成: 由一个ID、一个目的URL、一组断言工厂、一组Filter组成。

如果路由断言为真,说明请求URL和配置路由匹配。

②Predicate(断言)

SpringCloudGateway中的断言函数输入类型是Spring5.0框架中的 ServerWebExchange

SpringCloudGateway的断言函数允许开发者去定义匹配来自于HttpRequest 中的任何信息比如请求头和参数

③Filter(过滤)

一个标准的SpringWebFilterservletlistenerfilter以及interceptor组成。

SpringCloudGateway中的Filter分为两种类型的 Filter

  • GatewayFilter:针对某一个路由(路径)
  • GlobalFilter:针对全局

8.1.6.Nginx与Gateway的区别

Nginx在做路由、负载均衡、限流之前都有修改nginx.conf的配置文件,把需要负载均衡, 路由,限流的规则加在里面。(nginx做tomcat的负载均衡)

gateway则是自动的负载均衡和路由,gatewayeureka高度集成,实现 自动的路由,和Ribbon结合,实现了负载均衡,gateway也能轻易的实现限流和权限验证。

Nginxgateway的性能高一点。

本质区别就是:

  • Nginx:服务器级别的
  • Gateway:项目级别的

image-20230526133804696

8.2.快速入门

没有实现过滤功能

8.2.1.搭建login-service

①选择依赖

image-20230526134749592

只选择web即可。

②修改配置文件

image-20230526134104047

③添加controller类

image-20230526134427595

8.2.2.搭建Gateway-server

①选择依赖

image-20230526134617060

只需要选择gateway即可。

②修改配置文件

image-20230526135823637

8.2.3.搭建eureka-server

这里和上面的一样,不做多重复

8.2.4.访问测试

http://localhost/login

http://localhost:8001/login

返回出现token即为成功。

8.3.路由

8.3.1.配置方式之代码方式

image-20230526170743705

访问测试:localhost:80/path路径

8.3.2.配置方式之yml方式

image-20230526171945826

8.3.3.动态路由

默认情况下Gateway会根据注册中心的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能

需要注意的是uri的协议为lb(load Balance),表示启用Gateway的负载均衡功能。

lb://服务名称SpringCloudGateway在微服务中自动为我们创建的负载均衡uri

例:lb://login-service

8.3.4.动态路由使用

改造刚才的例子

Gateway-server改造:

image-20230526183057827

image-20230526183111447

login-service改造:

image-20230526183140622

image-20230526183149260

访问测试:http://localhost/login-service/login

http://localhost:80/服务名称/path路径

出现token即为成功。

8.4.断言

断言就是一些布尔表达式,满足条件的返回true,不满足的返回false。

SpringCloudGateway将路由作为SpringWebFluxHandlerMapping基础架构的一部分进行匹配。

SpringCloudGateway包括许多内置的路由断言工厂。

所有这些断言都与HTTP请求的不同属性匹配。可以将多个路由断言可以组合使用SpringCloudGateway创建对象时,使用RoutePredicateFactory创建 Predicate对象,Predicate对象可以赋值给Route

配置规则

image-20230526233532171

使用

spring:
    cloud:
        gateway:
        enabled: true #开启网关,默认是开启的
        routes: #设置路由,注意是数组,可以设置多个,按照 id 做隔离
            - id: user-service #路由 id,没有要求,保持唯一即可
            uri: lb://provider #使用 lb 协议 微服务名称做负均衡
            predicates: #断言匹配
                - Path=/info/** #和服务中的路径匹配,是正则匹配的模式
                - After=2020-01-20T17:42:47.789-07:00[Asia/Shanghai] #此断言匹配发生在指定日期时间之后的请求,ZonedDateTime dateTime=ZonedDateTime.now()获得
                - Before=2020-06-18T21:26:26.711+08:00[Asia/Shanghai] #此断言匹配发生在指定日期时间之前的请求
                -Between=2020-06-18T21:26:26.711+08:00[Asia/Shanghai],2020-06-18T21:32:26.711+08:00[Asia/Shanghai]
                #此断言匹配发生在指定日期时间之间的请求
                - Cookie=name,xiaobai #Cookie 路由断言工厂接受两个参数,Cookie 名称和 regexp(一个 Java 正则表达式)。此断言匹配具有给定名称且其值与正则表达式匹配的 cookie
                - Header=token,123456 #头路由断言工厂接受两个参数,头名称和 regexp(一个 Java 正则表达式)。此断言与具有给定名称的头匹配,该头的值与正则表达式匹配。
                - Host=**.bai*.com:* #主机路由断言工厂接受一个参数:主机名模式列表。该模式是一个 ant 样式的模式。作为分隔符。此断言匹配与模式匹配的主机头
                - Method=GET,POST #方法路由断言工厂接受一个方法参数,该参数是一个或多个参数:要匹配的 HTTP 方法
                - Query=username,cxs #查询路由断言工厂接受两个参数:一个必需的 param 和一个可选的 regexp(一个 Java 正则表达式)。
                - RemoteAddr=192.168.1.1/24 #RemoteAddr 路由断言工厂接受一个源列表(最小大小 1),这些源是 cidr 符号(IPv4 或 IPv6)字符串,比如 192.168.1.1/24(其中 192.168.1.1 是 IP 地址,24 是子网掩码)

还有一个访问权重的设置,比如说:

80%的请求,由https://weighthigh.org 这个 url 去处理

20%的请求,由https://weightlow.org 去处理

spring:
	cloud:
        gateway:
            routes:
                - id: weight_high
                    uri: https://weighthigh.org
                    predicates:
                        - Weight=group1, 8
                - id: weight_low
                    uri: https://weightlow.org
                    predicates:
                        - Weight=group1, 2

8.5.过滤

gateway的过滤器和Servlet的过滤器功能差不多,路由过滤器可以用于修改进入Http请求和返回Http响应

8.5.1.分类

生命周期分类

pre:在业务逻辑之前

post:在业务逻辑之后

种类分类

GatewayFilter需要配置某个路由才能过滤。

如果需要使用全局路由,需要配置DefaultFilters

GlobalFilter全局过滤器,不需要配置路由,系统初始化作用到所有路由上 全局过滤器

8.5.2.自定义过滤

在上面的测试中添加一个类测试即可。

image-20230527093447555

8.5.3.IP认证拦截

修改上面的自定义过滤类即可。

image-20230527100727888

测试访问:http://127.0.0.1/login

image-20230527100637430

8.6.限流

限制一段时间内,用户访问资源的次数,减轻服务器压力。

限流分为

1.IP限流(一段时间内只能访问x次,超过则限制不让访问,过一段时间才可继续访问)

2.请求量限流(只要在一段时间内(窗口期),请求次数达到阀值,就直接拒绝后面来的访问了, 过一段时间才可以继续访问)(粒度可以细化到一个api/url,一个服务)

结合redis实现

①添加依赖

SpringCloudGateway已经内置了一个 RequestRateLimiterGatewayFilterFactory

RequestRateLimiterGatewayFilterFactory的实现依赖于Redis,所以需要引入spring-boot-starter-data-redis-reactive这个依赖。

<!--限流要引入 Redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

②添加配置

server:
    port: 80
spring:
    application:
        name: gateway-server
	cloud:
		gateway:
			routes:
                - id: user-service-router
                uri: lb://login-service
                predicates:
                    - Path=/login
                filters:
                    - name: RequestRateLimiter
                        args:
                            key-resolver: '#{@hostAddrKeyResolver}' #用于限流的键的解析器的Bean对象的名字。使用SpEL表达式根#{@beanName}从Spring容器中获取Bean对象
                            redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率
                            redis-rate-limiter.burstCapacity: 3 #令牌桶容量
	redis: #redis 的配置
        host: localhost
        port: 6379
        database: 0
eureka:
    instance:
        instance-id: ${spring.application.name}:${server.port}
        prefer-ip-address: true
    client:
        service-url:
            defaultZone: http://localhost:8761/eureka

③添加config类

@Configuration
public class RequestRateLimiterConfig {
    /*
    * IP 限流
    * 把用户的 IP 作为限流的 Key
    */
    @Bean
    @Primary
    public KeyResolver hostAddrKeyResolver() {
        return (exchange) -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
    }
    /**
    * 用户 id 限流
    * 把用户 ID 作为限流的 key
    */
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
    }
    /**
    * 请求接口限流
    * 把请求的路径作为限流 key
    */
    @Bean
    public KeyResolver apiKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getPath().value());
    }
}

④访问测试

快速访问多次:http://localhost/login,之后出现429错误即为成功

8.7.跨域

代码实现

@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);
    }
}

配置文件实现

spring:
    cloud:
        gateway:
            globalcors:
                corsConfigurations:
                    '[/**]': // 针对哪些路径
                    allowCredentials: true #可以携带cookie
                    allowedHeaders: '*'
                    allowedMethods: '*'
                    allowedOrigins: '*

标签:匹配,断言,gateway,限流,过滤器,Gateway,路由
From: https://www.cnblogs.com/Myvlog/p/17436645.html

相关文章

  • SpringGateway不用注册中心实现负载均衡
    1、pom<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/PO......
  • 关于AWS中VPC下的IGW-internet gateway的创建与说明
    关于AWS中VPC下有一个资源叫做 Internetgateways,也就是我们常说的IGW关于IGW,我们可以参考官网文档 AmazonVPC/ UserGuide中有如下说明:Aninternetgatewayisahorizontallyscaled,redundant,andhighlyavailableVPCcomponentthatallowscommunicationbetw......
  • 博学谷学习记录 自我总结 用心分享 | Alibaba- GateWay
    SpringCloudNetflix项目进入维护模式,SpringCloudNetflix将不再开发新的组件,我们知道SpringCloud版本迭代算是比较快的,因而出现了很多中岛的ISSUE都来不及Fix就又推另一个Release了。进入维护模式意思就是目前已知以后一段时间SpringCloudNetflix提供的服......
  • 网关服务——Spring Cloud Gateway
    为什么要用网关?1.请求路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当路由的目标服务有多个时,还需要做负载均衡。2.权限控制:网关作为微服务的入口,需要校验用户是否具有请求资格,如果没有资格就要进行拦截......
  • 服务器上安装Power BI Data Gateway
    安装时注意事项  服务器开通好网络策略,例如一些相关的目标地址和IP加到服务器防火墙里,服务器可以联网后,还需要做浏览器相关设置,如下:   1)浏览器Tools->Internetoptions->security->customlevel->Scripting->Enableactivescripting&enablescriptingofJavaapple......
  • [SpringCloud]Spring-Cloud-Gateway之启动过程(源码分析)
    1前言1.1环境信息Spring-Cloud-Gateway:2.2.9.RELEASEorg.springframework.boot:spring-boot:2.3.12.RELEASEio.projectreactor.netty:reactor-netty:0.9.20.RELEASEio.netty:netty-transport:4.1.65.FINAL2启动过程#与Netty的调用链路2.1简版(V1.0)cn.seres.b......
  • Prometheus监控Spring Cloud Gateway
    概述API网关作为应用服务与外部交互的入口,通过对API网关的监控,可以清晰的知道应用整体的请求量,以便根据不同的并发情况进行扩容处理。对API网关的监控也是相当必要的。通过Prometheus监控Gateway与监控普通Springboot项目几乎没有区别。基本步骤都是引入pom依赖,然后修改端点暴露m......
  • workerman下框架gateway报错 worker[thinkphp:30776] exit with status 64000
    wokerman启动之后一直报错Worker[30477]processterminatedworker[thinkphp:30477]exitwithstatus64000Worker[30533]processterminatedworker[thinkphp:30533]exitwithstatus64000Worker[30571]processterminatedworker[thinkphp:30571]exitwithstatus64......
  • Gateway使用时不走全局过滤器
    报错今天配置nacos+gateway作为项目的基础,想通过gateway的过滤器进行token的校验。百度后,发送请求,进行网关找到对应的服务,但是没有进行token校验。每次请求都能够进入到方法体中。自定义过滤器:@ComponentpublicclassTokenFilterimplementsGatewayFilter,Ordered{@......
  • SpringCloud gateway Actuator
    要启用gateway的Actuator交互首先添加依赖:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>其次在application.properties配置:management.end......