SpringCloud-Gateway搭建保姆级教程

springcloud,gateway,搭建,保姆,教程 · 浏览次数 : 4

小编点评

## Gateway服务器限流配置详解 **1.添加依赖** * Spring Bootstarter Data Redis Reactive * Commons Pool2 * Redis RateLimiter **2.配置keyResolver** * 使用exchange.getRequest().getQueryParams().getFirst("user")作为令牌桶的key * 返回exchange.getRequest().getURI().getPath() **3.配置服务的限流规则** * Spring Gateway routes中设置请求 rate limiter * args中设置redis-rate-limiter.replenishRate、burstCapacity、requestedTokens、每个请求消耗多少个令牌 * key-resolver属性设置#{@keyResolver} **4.配置服务的限流规则** * Spring Gateway routes中设置请求 rate limiter * args中设置redis-rate-limiter.replenishRate、burstCapacity、requestedTokens、每个请求消耗多少个令牌 * filters属性设置RequestRateLimiter * args中设置redis-rate-limiter.replenishRate、burstCapacity、requestedTokens **5.总结** * 生成内容时需要带简单的排版 *配置限流规则时需要设置多个属性 *使用keyResolver设置令牌桶key

正文

一、网关介绍

1、什么是网关?

使⽤服务⽹关作为接⼝服务的统⼀代理,前端通过⽹关完成服务的统⼀调⽤

2、⽹关可以⼲什么?

路由:接⼝服务的统⼀代理,实现前端对接⼝服务的统⼀访问
过滤:对⽤户请求进⾏拦截、过滤(⽤户鉴权)、监控
限流:限制⽤户的访问流量

3、常⽤的⽹关

Nginx
Spring Cloud Netflix zuul
Spring Cloud Gateway

二、使⽤Nginx实现⽹关服务

Nginx通常被⽤作应⽤服务器⽹关,服务⽹关通常使⽤zuul或者gateway

三、使用Zuul实现网关服务

四、使用Gateway实现网关服务

1、搭建gateway服务器

创建SpringBoot应⽤,添加gateway依赖

2、配置路由规则

application.yml
server:
  port: 9999
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        # 配置api-service1路由规则
        - id: api-service1
          uri: 'http://localhost:8001'
          predicates:
            - Path=/product/**
        # 配置api-service2路由规则
        - id: api-service2
          uri: 'http://localhost:8002'
          predicates:
            - Path=/order/**

五、Gateway⼯作原理

1、名词解释

Route: 路由是⽹关的基本组成部分,它是由id、⽬标uri、断⾔组成,如果断⾔为true,则匹配该路由,转向到当前路由的URI
Predicate:断⾔,⽤户请求的匹配规则
Filter:过滤器,⽤于对请求进⾏前置、后置处理(可以在⽹关实现对请求或相应的加⼯处理)

2、Gateway⼯作流程图

六、Predicate断⾔

SpringCloud Gateway提供了多种断⾔匹配的⽅式:
  • After
  • Before
  • Between
  • Cookie
  • Header
  • Host
  • Method
  • Path
  • Query
  • RemoteAddr
  • Weight

1、Path

根据请求路径的正则匹配
spring:
  application: null
  name: gateway-server
  cloud: null
  gateway: null
  routes:
    - id: aaa
      uri: 'http://localhost:8001'
      predicates:
        - Path=/product/**
    - id: bbb
      uri: 'http://localhost:8002'
      predicates:
        - Path=/order/**

2、Query

根据请求携带的参数匹配路由
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        - id: aaa
          uri: 'http://localhost:8001'
          predicates:
            # 如果请求url中带有name参数 ---> http://localhost:8001
            - Query=name
        - id: bbb
          uri: 'http://localhost:8002'
          predicates:
            #如果请求url中带有pwd参数 ---> http://localhost:8002
            - Query=pwd

3、Header 

根据Header中携带的参数匹配
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        - id: aaa
          uri: 'http://localhost:8001'
          predicates:
            - Header=token
        - id: bbb
          uri: 'http://localhost:8002'
          predicates:
            - 'Header=aa,haha'

七、过滤器

1、Gateway内置⽹关过滤器

gateway⽹关可以对⽤户的请求和响应进⾏处理,gateway提供了多个内置的过滤器,
不同的过滤器可以完成不同的请求或者响应的处理
1. AddRequestHeader 在请求头中添加参数
2. AddRequestParameter 添加请求参数
3. AddResponseHeader
4. The DedupeResponseHeader GatewayFilter Factory
5. The Hystrix GatewayFilter Factory
6. Spring Cloud CircuitBreaker GatewayFilter Factory
7. The FallbackHeaders GatewayFilter Factory
8. The MapRequestHeader GatewayFilter Factory
9. The PrefixPath GatewayFilter Factory
10. The PreserveHostHeader GatewayFilter Factory
11. The RequestRateLimiter GatewayFilter Factory
12. The RedirectTo GatewayFilter Factory
13. The RemoveRequestHeader GatewayFilter Factory
14.  RemoveResponseHeader GatewayFilter Factory
15.  The RemoveRequestParameter GatewayFilter Factory
16.  The RewritePath GatewayFilter Factory
17.  RewriteLocationResponseHeader GatewayFilter Factory
18.  The RewriteResponseHeader GatewayFilter Factory
19.  The SaveSession GatewayFilter Factory
20.  The SecureHeaders GatewayFilter Factory
21.  The SetPath GatewayFilter Factory
22.  The SetRequestHeader GatewayFilter Factory
23.  The SetResponseHeader GatewayFilter Factory
24.  The SetStatus GatewayFilter Factory
25.  The StripPrefix GatewayFilter Factory
26.  The Retry GatewayFilter Factory
27.  The RequestSize GatewayFilter Factory
28.  The SetRequestHostHeader GatewayFilter Factory
29.  Modify a Request Body GatewayFilter Factory
30.  Modify a Response Body GatewayFilter Factory
31.  Default Filters
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        - id: aaa
          uri: 'http://localhost:8001'
          predicates:
            - Path=/red/aaa/product/**
      filters:
        - 'AddRequestHeader=token,wahahaawahaha'
        - 'AddRequestParameter=username, ergou'
        - SetStatus=404
        - StripPrefix=2

2、⾃定义服务过滤器

2.1、创建⽹关过滤器 - 实现GatewayFilter

1、实现GatewayFilter, Ordered

public class MyFilter01 implements GatewayFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); System.out.println("---------------⾃定义过滤器"); return chain.filter(exchange); }
@Override
public int getOrder() { return 0; } }

2、配置过滤器

@Configuration
public class GatewayConfig {
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder){ System.out.println("-----------------------init"); RouteLocator routeLocator = builder.routes().route( r->     r.path("/product/**") // predicates      .filters(f->f.filters( new MyFilter01() )) //filters     .uri("http://localhost:8001") //uri   ).build(); return routeLocator; }
}

2.2、创建⽹关过滤器 - 继承AbstractNameValueGatewayFilterFactory

相当于扩展Gateway内置的⽹关过滤器
/**
* 创建⼀个类继承AbstractNameValueGatewayFilterFactory,类名必须以GatewayFilterFactory结尾,类名前⾯的部分即为当前⾃定义⽹关过滤器的 名字
* 添加@Component注解,注册到Spring容器
*/
@Component
public class MyFilterGatewayFilterFactory extends
AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        System.out.println("name:"+config.getName());
        System.out.println("value:"+config.getValue());
        //创建⾃定义⽹关过滤器并返回
        GatewayFilter gatewayFilter = new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⾃定义⽹关过滤器");
                return chain.filter(exchange);
            }
        };
        return gatewayFilter;
    }
}
配置:
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        - id: bbb
          uri: 'http://localhost:8002'
          predicates:
            - Path=/order/**
      filters:
        - 'MyFilter=aa,bb'

3、全局过滤器

上述我们讲到的过滤器,都是配置在某个路由/服务中,我们称之为 ⽹关服务过滤器 ,
Gateway提供了内置的全局过滤器,会拦截过滤所有到达⽹关服务器的请求。
内置的全局过滤器默认⽣效,⽆需开发者⼲预。
根据业务的需求我们也可以⾃定义全局过滤器以实现对所有⽹关请求的拦截和处理。
 
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("----------------------------------------------MyGlobalFilter"); List<String> list = exchange.getRequest().getHeaders().get("token"); if (list != null && list.size()>0){ String token = list.get(0); System.out.println("token:"+token); return chain.filter(exchange); } else{ //如果没有token,或者token过期 ServerHttpResponse response = exchange.getResponse(); //设置响应头 response.getHeaders().add("ContentType","application/json;charset=utf-8"); //设置状态码 response.setStatusCode(HttpStatus.UNAUTHORIZED); // 封装响应数据 String str = ""; DataBuffer dataBuffer = response.bufferFactory().wrap(str.getBytes()); return response.writeWith(Mono.just(dataBuffer)); } }
@Override
public int getOrder() { return 0; } }

八、Gateway动态路由配置

如果在Gateway⽹关的路由配置中,直接将服务的ip port配置进去,将导致:
1.如果服务的地址变更,必须要重新配置gateway的路由规则
2.如果服务采⽤集群部署,则不能实现负载均衡

 

1、Gateway服务器添加eureka-server依赖

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

2、配置⽹关路由

application.yml
server:
  port: 9999
spring:
  application:
    name: gateway-server
  main:
    web-application-type: reactive
  cloud:
    gateway:
      routes:
        - id: aaa
          uri: 'lb://api-service1'
          predicates:
            - Path=/product/**
        - id: bbb
          uri: 'lb://api-service2'
          predicates:
            - Path=/order/**
eureka:
  client:
    service-url:
      defaultZone: 'http://localhost:8761/eureka'

九、⽹关限流

1、⽹关限流介绍

服务的统⼀访问
使⽤过滤器实现鉴权
使⽤⽹关实现限流:通过限制⽤户的请求进⼊到服务中,有效控制应⽤系统的QPS,达到保护系统的⽬的
在互联⽹应⽤的⽣产环境中,可以由于⽤户增⻓超过预期、竞争对⼿恶意请求等外界的原因都有可能导致服务器⽆法处理超预期的⾼并发请求导致服务器宕机

2、⽹关限流的常⻅算法

2.1、计数器算法

就是通过记录在单位时间请求的数量,在这个时间周期内达到设置定值之后就拒绝后续请求的进⼊。
缺点:如果⽤户请求频率不均匀,有导致短时间、⾼并发的⻛险

2.2、漏桶算法

就是通过控制“漏桶”流出的速率以限制到达服务的⽤户流量
缺点:⽹关会承载⽐较⼤的压⼒

2.3、令牌桶算法

就是所有进⼊⽹关的请求必须从令牌桶中得到令牌才可以进⾏服务调⽤,我们可以通过控制令牌桶的容量、令牌的产⽣速率达到控制⽤户流量的⽬的

3、Gateway⽹关限流

Gateway是基于令牌桶算法,使⽤redis作为“桶”结合过滤器实现了⽹关限流。

 

1、添加依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-pool2</artifactId>
   <version>2.9.0</version>
</dependency>

2、配置keyResolver

@Configuration
public class AppConfig {
    @Bean
    public KeyResolver keyResolver() {
        //http://localhost:9999/order/query?user=1
        //使⽤请求中的user参数的值作为令牌桶的key
        //return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
        return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
    }
}

3、配置服务的限流规则

server:
  port: 9999
spring:
  application:
    name: gateway-server
  main:
    web-application-type: reactive
  cloud:
    gateway:
      routes:
        - id: aaa
          uri: 'lb://api-service1'
          predicates:
            - Path=/product/**
        - id: bbb
          uri: 'lb://api-service2'
          predicates:
            - Path=/order/**
      filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 1  #令牌桶每s的填充速度
            redis-rate-limiter.burstCapacity: 2  #令牌桶容量
            redis-rate-limiter.requestedTokens: 1  #每个请求消耗多少个令牌
            key-resolver: '#{@keyResolver}'        #令牌桶key生成
  redis:
    host: 47.96.11.185
    port: 7001
    password: qfedu123
    database: 0
    lettuce:
      pool:
        max-active: 10
        max-wait: 1000
        max-idle: 5
        min-idle: 3
eureka:
  client:
    service-url:
      defaultZone: 'http://localhost:8761/eureka'

 

与SpringCloud-Gateway搭建保姆级教程相似的内容:

SpringCloud-Gateway搭建保姆级教程

一、网关介绍 1、什么是网关? 使⽤服务⽹关作为接⼝服务的统⼀代理,前端通过⽹关完成服务的统⼀调⽤ 2、⽹关可以⼲什么? 路由:接⼝服务的统⼀代理,实现前端对接⼝服务的统⼀访问 过滤:对⽤户请求进⾏拦截、过滤(⽤户鉴权)、监控 限流:限制⽤户的访问流量 3、常⽤的⽹关 Nginx Spring Cl

Spring Cloud Gateway编码实现任意地址跳转

面对同样的客户端请求,SpringCloud Gateway可以转发给不同的服务去处理,掌握这个技能,让请求从微服务入口处被掌控,被调度

聊聊Spring Cloud Gateway

Spring Cloud Gateway是基于Spring Boot 2.0、Spring WebFlux和Project Reactor等技术开发的网关,它不仅提供了统一的路由请求的方式,还基于过滤链的方式提供了网关最基本的功能;解决了Spring Cloud Zuul的性能问题。

Spring Cloud Gateway 使用示例

Spring Cloud Gateway 使用示例 作者: Grey 原文地址: 博客园:Spring Cloud Gateway 使用示例 CSDN:Spring Cloud Gateway 使用示例 说明 Spring Cloud Gateway 用于构建 API 网关,基于 Spring We

SpringCloud解决feign调用token丢失问题

背景讨论 feign请求 在微服务环境中,完成一个http请求,经常需要调用其他好几个服务才可以完成其功能,这种情况非常普遍,无法避免。那么就需要服务之间的通过feignClient发起请求,获取需要的 资源。 认证和鉴权 一般而言,微服务项目部署环境中,各个微服务都是运行在内网环境,网关服务负责请

[转帖]springcloud nacos配置

配置文件中的nacos配置,discovery和config配置项 版本: 2.3.2.RELEASE Hoxton.SR9

SpringCloud-ZipKin搭建保姆级教程

服务链路追踪 一、服务追踪说明 微服务架构是通过业务来划分服务的,使⽤REST调⽤。对外暴露的⼀个接⼝,可能需要 很多个服务协同才能完成这个接⼝功能,如果链路上任何⼀个服务出现问题或者⽹络超 时,都会形成导致接⼝调⽤失败。 随着业务的不断扩张,服务之间互相调⽤会越来越复杂,它们之间的调⽤关系也许如下

SpringCloud-Config配置中心搭建保姆级教程

一、分布式配置中⼼ 在使⽤微服务架构开发的项⽬中,每个服务都有⾃⼰的配置⽂件(application.yml),如果将每个服务的配置⽂件直接写在对应的服务中,存在以下问题: 1. 服务开发完成之后,需要打包部署,配置⽂件也会打包在jar⽂件中,不便于项⽬部署之后的配置修改(在源码中修改——重新打包—

SpringCloud-Hystrix服务熔断与降级工作原理&源码

在生活中,如果电路的负载过高,保险箱会自动跳闸,以保护家里的各种电器,这就是熔断器的一个活生生例子。在Hystrix中也存在这样一个熔断器,当所依赖的服务不稳定时,能够自动熔断,并提供有损服务,保护服务的稳定性。在运行过程中,Hystrix会根据接口的执行状态(成功、失败、超时和拒绝),收集并统计这些数据,根据这些信息来实时决策是否进行熔断。

SpringCloud搭建保姆级教程

一、搭建服务注册与发现中⼼ 使⽤Spring Cloud Netflix 中的 Eureka 搭建服务注册与发现中⼼ 1、创建SpringBoot应用添加依赖 1、spring web 2、eureka server 2、配置服务注册与发现中⼼ ## 设置服务注册与发现中⼼的端⼝ server: p