spring cloud系列gateway(熔断,限流,转发)

“有一天晚上,梦一场,你白发苍苍,说带我流浪,我还是没犹豫,就随你去天堂”


网关在微服务体系中有这非常的重要的地位,有了网关,外部直接与网关通信,我们不需要暴露太多微服务的信息,而且访问也方便

搭建

  • 依赖
'org.springframework.cloud:spring-cloud-starter-gateway:2.1.1.RELEASE'

如果引用了web的依赖,需要删掉,spring cloud gateway 使用webflux,和web会冲突

  • 主类加注解,添加eureka的注解
@SpringBootApplication
@EnableDiscoveryClient
public class GetawayApplication {

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

}
  • 修改配置
server:
  port: 9000

spring:
  application:
    name: ADMIN-GETAWAY
  cloud:
    gateway:
      discovery:
        locator:
          # 开启服务发现
          enabled: true
          # 忽略注册中心服务的大小写
          lower-case-service-id: true

eureka:
  instance:
#    ip-address: ${server.address}
#    hostname: ${server.address}
    non-secure-port: ${server.port}
    prefer-ip-address: true
#    instance-id: ${server.address}:${server.port}
    lease-renewal-interval-in-seconds: 10
  client:
    serviceUrl:
      defaultZone: http://192.168.1.137:38001/eureka/
    fetch-registry: true
    register-with-eureka: true

在注册中心,即可看见我们的网关微服务
现在我什么也没有配置,我们访问网关的IP:端口/指定微服务的名称/接口,即可访问我们的微服务
在这里插入图片描述
这样我们的网关就搭建成功了,网关还可以集成swagger,需要的可以看我的这篇博客
https://blog.csdn.net/zlhmeng/article/details/100521118

路由转发

现在配置文件里面什么也没有配置,默认的转发机制,我们访问网关的ip:port/微服务名/接口即可访问相应的微服务
比如我的注册中心有这几个微服务
在这里插入图片描述

  • 其中conmuser通过openfign调用了provider1和provider2
    访问
    在这里插入图片描述
    默认就实现了动态路由,但这暴露了我们的微服务名称和接口,安全性不太好,有些时候我们也有需求不想暴露我们的api,所以就有配置路由转发,或者对路由进行过滤。
    添加配置:
spring:
  application:
    name: ADMIN-GETAWAY
  cloud:
    gateway:
      discovery:
        locator:
          #开启服务注册和发现功能
          enabled: true
          #将服务名称转换为小写
          lower-case-service-id: true
      routes:
        - id: byb-provide1
          uri: lb://TS-PROVIDER1
          predicates:
            - Path=/demo/**
          filters:
            - StripPrefix=1

前面的配置之前就有,为了直观的看出层级关系都附上了,重点在routes配置

  • id:标识此路由的唯一id,就给这个路由取一个不会重复的好理解的名字
  • uri:顾名思义,路由的uri,你可以写成ip:port的形式,因为我们使用了注册中心,所有使用lb://微服务名,即可定位到指定微服务
  • predicates:这里就是配置断言,也就是路由的规则,这里配置了path,表示我要根据路径过滤路由,会将/demo开头的路由转发到我们上面配置的微服务,基本上http请求的参数都可以断言,可以参考下面的官方文档。
  • filters:过滤器,我配置了StripPrefix=1也就是截取url前面的一位,截取过后的后面一位才是真正的api,比如说我么的断言不是一个/demo而是两个/demo/demo/**,并且截取一位,那么路由到微服务的时候就会多出一个/demo(一个demo会变成ip:port/test1,两个只截取了一个,接口就会变成ip:port/demo/test1),除非有/demo/…的接口,否者访问不到
    在这里插入图片描述

结果和上面一样,当然routes还有很多的参数,比如断言的权重,可能相对比较重要,官方文档都有,可以了解一下,根据自己的需求觉得使用什么参数
https://cloud.spring.io/spring-cloud-gateway/reference/html/#gateway-request-predicates-factories

上面的配置也可以使用代码进行配置,个人建议使用yaml配置文件的方式,这样比代码更直观,而且搭配spring cloud config非常方便,更改时修改配置文件就行,不用修改代码。

熔断

我们之前使用openfign可以实现熔断,但这是服务间调用,我们的请求都会经过网关,当有大量的请求访问时,我们都不敢保证不会因为各种原因而请求失败,但我们不能让请求一直堆积在网关,如果网关死了,整个体系就断了,所以我们需要使用熔断,失败时直接给客服端返回失败,不要堆积。
添加配置

spring:
  application:
    name: ADMIN-GETAWAY
  cloud:
    gateway:
      discovery:
        locator:
          #开启服务注册和发现功能
          enabled: true
          #将服务名称转换为小写
          lower-case-service-id: true
      routes:
        - id: byb-provide1
          uri: lb://TS-PROVIDER1
          predicates:
            - Path=/demo/**
          filters:
            - StripPrefix=1
            - name: Hystrix
              args:
                name: hystest
                fallbackUri: forward:/hysTest
# 熔断时间
hystrix:
  command:
    fallbackcmd:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000
    

在filter下面我们添加了名为Hystrix的过滤器实现熔断,下面是参数,name表示过滤器的名称此处必须为Hystrix,fallbackuri表示熔断定位,大概就是发生熔断后要干嘛,我这里配置了forward表示转发,所以我们需要配置hsyTest的接口

@RestController
public class HysFallback {

    @GetMapping("/hysTest")
    public String fallback(){
        return "网关熔断测试成功";
    }
}

上面的配置我们的熔断超时时间是3秒,我们让他让问的接口睡眠4秒即可测试是否熔断成功,修改provider1中的代码

 @GetMapping("/test1")
    public String test1() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String info = "uri=test1,我是服务提供者一。欢迎光临。";
        logger.info(info);
        return info;
    }

访问
在这里插入图片描述

完美

限流

系统高并发的时候,系统可能过载,也有可能有人就估计攻击服务器,为了保证系统的正常运行我们需要做一下限流,spring cloud gateway使用redis实现限流
添加配置

spring:
  application:
    name: ADMIN-GETAWAY
  cloud:
    gateway:
      discovery:
        locator:
          #开启服务注册和发现功能
          enabled: true
          #将服务名称转换为小写
          lower-case-service-id: true
      routes:
        - id: byb-provide1
          uri: lb://TS-PROVIDER1
          predicates:
            - Path=/demo/**
          filters:
            - StripPrefix=1
            - name: Hystrix
              args:
                name: hystest
                fallbackUri: forward:/hysTest
            - name: RequestRateLimiter
              args:
                # 使用SpEL名称引用Bean,与上面新建的RateLimiterConfig类中的bean的name相同
                key-resolver: '#{@KeyResolverTest}'
                # 每秒最大访问次数
                redis-rate-limiter.replenishRate: 2
                # 令牌桶最大容量
                redis-rate-limiter.burstCapacity: 10
  redis:
    host: 192.168.1.137
    port: 6379
    database: 0
  • name: RequestRateLimiter为过滤器名称,这是spring cloud gateway官方提供的过滤器
  • key-resolver:使用 SpEL查找bean,我们下面会定义一个bean,用来定义通过什么方式限流
  • redis-rate-limiter.replenishRate:允许用户每秒处理多少个请求
  • redis-rate-limiter.burstCapacity:令牌桶的容量
    后面两个解释可以参考:https://www.cnblogs.com/forezp/p/10140316.html
    定义bean
@Configuration
public class keyResolverConfig {

    @Bean(value = "KeyResolverTest")
    public KeyResolver KeyResolverTest() {
        // 根据ip限流
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
        // 根据接口限流
//        return exchange -> Mono.just(exchange.getRequest().getPath().value());
        // 根据用户限流
//        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    }
}

这个bean通过过滤器筛选请求,不难发现他是通过gateway的过滤器去过滤的,没有了解过spring cloud gateway过滤机制的看完可以去了解一下。
把之前provider中的睡眠去掉,使用测试工具测试一下,我这里使用jmeter
在这里插入图片描述
完毕

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值