【教程】SpringCloud+Nacos+Feign+Gateway ( 七 ) Nacos-Gateway 网关 熔断降级(推荐)
这种熔断只能针对服务网关调用后端服务接口超时才会生效,后端服务抛异常无效
为什么要实现熔断降级?
在分布式系统中,网关作为流量的入口,因此会有大量的请求进入网关,向其他服务发起调用,其他服务不可避免的会出现调用失败(超时、异常),失败时不能让请求堆积在网关上,需要快速失败并返回给客户端,想要实现这个要求,就必须在网关上做熔断、降级操作。
为什么在网关上请求失败需要快速返回给客户端?
因为当一个客户端请求发生故障的时候,这个请求会一直堆积在网关上,当然只有一个这种请求,网关肯定没有问题(如果一个请求就能造成整个系统瘫痪,那这个系统可以下架了),但是网关上堆积多了就会给网关乃至整个服务都造成巨大的压力,甚至整个服务宕掉。因此要对一些服务和页面进行有策略的降级,以此缓解服务器资源的的压力,以保证核心业务的正常运行,同时也保持了客户和大部分客户的得到正确的相应,所以需要网关上请求失败需要快速返回给客户端。
1. pom.xml
重要
<!-- hystrix 熔断、降级 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
完整
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 引入父项目 -->
<parent>
<groupId>com.gw</groupId>
<artifactId>gwcloud-module</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.gw</groupId>
<artifactId>gwcloud-module-gateway</artifactId>
<version>1.0-SNAPSHOT</version>
<name>gwcloud-module-gateway</name>
<dependencies>
<!-- gwcloud 微服务基础依赖-->
<dependency>
<groupId>com.gw</groupId>
<artifactId>gwcloud-starter-init</artifactId>
<exclusions>
<exclusion>
<groupId>com.gw</groupId>
<artifactId>gwcloud-base-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- spring-cloud网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 熔断、降级 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
2. application.yml
全局熔断降级配置 与 单个路由熔断器配置
server:
port: 9999
spring:
application:
name: gwcloud-module-gateway
cloud:
gateway:
discovery:
locator:
# 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务
enabled: true
globalcors:
cors-configurations:
'[/**]':
allowCredentials: true
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
#如果启用nacos或者数据库配置请删除以下配置
# 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。)
routes:
#路由标识(id:标识,具有唯一性) 简单尝试
- id: gwcloud-user-provide-service
# 目标服务地址(uri:地址,请求转发后的地址) lb://服务名
uri: lb://gwcloud-user-provide-service
# 路由条件(predicates:断言,匹配 HTTP 请求内容)
predicates:
## 转发地址格式为 uri/archive
- Path=/nacos-config/**
filters:
# 熔断器
- name: Hystrix
args:
name: fallbackCmd
fallbackUri: 'forward:/fallbackCmd'
#路由标识(id:标识,具有唯一性) 简单尝试
- id: gwcloud-user-provide-service
# 目标服务地址(uri:地址,请求转发后的地址) lb://服务名
uri: lb://gwcloud-user-provide-service
# 路由条件(predicates:断言,匹配 HTTP 请求内容)
predicates:
## 通过请求参数过滤
- Query=token
# 全局熔断降级配置
default-filters:
- name: Hystrix
args:
name: default
#转发地址
fallbackUri: 'forward:/fallback'
# hystrix 信号量隔离,5秒后自动超时
hystrix:
# enabled: true
# shareSecurityContext: true
command:
default: # 默认
execution:
isolation:
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 60000
fallbackCmd:
execution:
isolation:
# strategy: SEMAPHORE
thread: # 5秒没响应自动熔断 跳转到配置的fallbackUri
timeoutInMilliseconds: 5000
3. 代码
package com.gw.module.gateway.fallback;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
/**
* @Title: 响应超时熔断处理器
* @Description: 当服务无法访问时会跳转到这里
* @Version: v1.0
* @Author: Mr.Guan
* @Mail GuanWeiMail@163.com
* @DateTime: 2021-03-03
* @Project springcloud-gw-parent
* @Package com.gw.module.gateway.fallback
*/
@RestController
public class FallbackController {
/**
* fallbackCmd熔断处理
* @return
*/
@RequestMapping("/fallbackCmd")
public Mono<String> fallbackCmd() {
return Mono.just("访问超时,请稍后再试!Cmd");
}
/**
* 全局熔断处理
* @return
*/
@RequestMapping("/fallback")
public Mono<String> fallback() {
return Mono.just("访问超时,请稍后再试!");
}
}