CircuitBreaker断路器Fallback如何获取异常
在Spring Cloud 2020新版里, 可以使用新版的 CircuitBreaker 断路器, 可以配置Fallback, 可以是内部的, 也可以是外部的Fallback.
内部 Fallback
这里搭建一个内部fallback, 配置如下:
server:
port: 8900
spring:
application:
name: ms-gateway
main:
allow-bean-definition-overriding: true
cloud:
zookeeper:
connect-string: ${ZK_HOSTS:127.0.0.1:2181}
discovery:
enabled: true
preferIpAddress: true
loadbalancer:
ribbon:
enabled: false
gateway:
discovery:
locator:
lowerCaseServiceId: true
enabled: true
routes:
- id: default
uri: lb://ms-fundmain-service
predicates:
- Path=/fundmain/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/defaultfallback
- name: Retry
args:
retries: 2
series: SERVER_ERROR
fallback拦截了服务端异常, defaultfallback的实现如下:
@RestController
public class DefaultFallback {
private static final Logger logger = LoggerFactory.getLogger(GatewayErrorAttributes.class);
@RequestMapping("/defaultfallback")
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, Object> defaultfallback() {
Map<String, Object> map = new HashMap<>();
map.put("code", 5001);
map.put("msg", "服务异常");
return map;
}
}
这样就可以实现一个最简单的fallback, 如果要获取服务的实际错误信息, 则改造如下:
@RestController
public class DefaultFallback {
private static final Logger logger = LoggerFactory.getLogger(GatewayErrorAttributes.class);
@RequestMapping(value = "/defaultfallback")
@ResponseStatus
public Mono<Map<String, Object>> fallback(ServerWebExchange exchange) {
Map<String, Object> result = new HashMap<>(4);
result.put("code", 5001);
Exception exception = exchange.getAttribute(ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR);
ServerWebExchange delegate = ((ServerWebExchangeDecorator) exchange).getDelegate();
logger.error("服务调用失败,URL={}", delegate.getRequest().getURI(), exception);
result.put("uri", delegate.getRequest().getURI());
if (exception instanceof TimeoutException) {
result.put("msg", "服务超时");
}
else if (exception != null && exception.getMessage() != null) {
result.put("msg", "服务错误: " + exception.getMessage());
}
else {
result.put("msg", "服务错误");
}
return Mono.just(result);
}
}
这次注入了一个 ServerWebExchange, 然后获取保存在 CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 里面的实例, 拿到相应的异常信息.
外部Fallback
请参考 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/, 使用 FallbackHeaders 即可.
spring:
application:
name: ms-gateway
main:
allow-bean-definition-overriding: true
redis:
host: 127.0.0.1
port: 6379
database: 0
cloud:
zookeeper:
connect-string: ${ZK_HOSTS:127.0.0.1:2181}
discovery:
enabled: true
preferIpAddress: true
loadbalancer:
ribbon:
enabled: false
gateway:
discovery:
locator:
lowerCaseServiceId: true
enabled: true
routes:
- id: testoutsidefallback
uri: lb://ms-fundmain-service
predicates:
- Path=/fundmain2/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: fetchIngredients2
fallbackUri: forward:/externalfallback
- id: ingredients-fallback
uri: lb://ms-fundmain-service
predicates:
- Path=/externalfallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Exception-Type
executionExceptionMessageHeaderName: Exception-Message
支持四个字段:
- executionExceptionTypeHeaderName ("Execution-Exception-Type")
- executionExceptionMessageHeaderName ("Execution-Exception-Message")
- rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
- rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")
实现示例 Fallback如下: (注意, 此Controller不能放在网关项目里, 否则就要用内部Fallback才行)
@RestController
public class ExternalFallback {
private static final Logger logger = LoggerFactory.getLogger(ExternalFallback.class);
private static final String EXECUTION_EXCEPTION_TYPE = "Exception-Type";
private static final String EXECUTION_EXCEPTION_MESSAGE = "Exception-Message";
@RequestMapping("/externalfallback")
@ResponseStatus
public Map<String, Object> externalfallback(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
map.put("code", 5002);
map.put("msg", "服务异常");
map.put(EXECUTION_EXCEPTION_TYPE, request.getHeader(EXECUTION_EXCEPTION_TYPE));
map.put(EXECUTION_EXCEPTION_MESSAGE, request.getHeader(EXECUTION_EXCEPTION_MESSAGE));
return map;
}
}
这次注入了一个 HttpServletRequest, 然后获取保存在 Header 里面的信息, 拿到相应的异常.
CircuitBreaker断路器Fallback如何获取异常的更多相关文章
- Python中获取异常(Exception)信息
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置.下面介绍几种python中获取异常信息的方法,这里获取异常(Exception)信息采用try...except...程序 ...
- ASP.NET Web API 异常处理 HttpResponseException 以及Angularjs获取异常信息并提示
一.HttpResponseException 如果一个Web API控制器抛出一个未捕捉异常,默认地,大多数异常都会被转化成一个带有状态码“500 – 内部服务器错误”的HTTP响应.HttpRes ...
- Java异常---获取异常的堆栈信息
Java 实例 - 获取异常的堆栈信息 Java 实例 以下实例演示了使用异常类的 printStack() 方法来获取堆栈信息: Main.java 文件 public class Main{ p ...
- 获取异常信息e.printStackTrace()的内容
获取异常信息e.printStackTrace()的内容 最近做项目的时候需要记录操作的日志,但是记录异常信息的是发现使用e.getMessage()根本无法满足需要,并且e.getMessage() ...
- oracle存储过程获取异常信息码和异常信息
oracle存储过程,可以通过sqlcode 获取异常编码.通过sqlerrm获取异常信息. 例子: create or replace procedure write2blob(p_id in nu ...
- Python中获取异常(try Exception)信息
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置. 这里获取异常(Exception)信息采用try...except...程序结构.如下所示: try: ... exce ...
- SQL server 获取异常
一.try...... catch 获取异常信息 /*======================================== 相关错误消 息如下: ERROR_NUMBER() 返回错误号. ...
- 获取异常信息里再出异常就找不到日志了,我TM人傻了
本系列是 我TM人傻了 系列第三期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 最近组 ...
- 权限获取异常(不能用ModuleId,得换个名字)目前还没搞清楚为啥
CenterController: /// <summary> /// 访问模块,写入系统菜单Id /// </summary> /// <param name=&quo ...
随机推荐
- Java hashCode&&equals
/** 为保证向Set中添加的对象其所在的类必须要重写hashCode和equals方法: 重写的原则:hashCode和equals尽量保持一致性: 两个相同的对象equals()返回true时,那 ...
- acwing 868. 筛质数
线性筛 #include<bits/stdc++.h> #define N 1000010 using namespace std; int v[N],p[N]; void pr(int ...
- CentOS-Docker搭建MinIO(单点)
下载镜像 $ docker pull minio/minio 创建相关目录 $ mkdir /home/minio/data /home/minio/config -p 运行镜像(自定义Access和 ...
- java设计模式(9):模板方法模式(TemplateMethod)
一,定义:模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 二,类图: 三,通过小例子讲解: 这个模式一般用在 ...
- MySQL基础篇(一)
本文主要内容为MySQL的基础语句以及正则表达式等内容. 本文操作的数据库内容存在个人github:https://github.com/YuanGao-1/blog_demo.git init_sc ...
- 选择适合入门的自动化测试框架TestNG 基于Java语言的入门选择之一
对于测试工程师新手来说,最痛苦的莫过于入门,其实只要入门3个月左右,对于自动化测试,所有的测试工程师除了喜爱,就是更爱.自动化测试工作,是从根本上解放人性,不用重复去完成鼠标的点点点,例如以下测试常常 ...
- python 按行查找文本文件,找出答案,并提示置顶答案
1.整理好答案文件为文本文件:不能有空行:每个题干前有数字做为题号:每个题答案第一个字符为字母,答案占一行import time import time import sys import os im ...
- python 操作word
pip install python.docx from docx import DocumentDoc = Document() 解释:from 从 docx这个文件中,导入一个叫Document的 ...
- 电脑通过WIFI连接手机ADB
1.搜索adb wifi 2.安装并开启:根据提示 3.电脑:adb connect 192.168.1.134 a安装ADB TOOLS b安装ADB DRIVER c将ADB TOOLS复制到c: ...
- DataFrame的创建
DataFrame的创建从Spark2.0以上版本开始,Spark使用全新的SparkSession接口替代Spark1.6中的SQLContext及HiveContext接口来实现其对数据加载.转换 ...