在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如何获取异常的更多相关文章

  1. Python中获取异常(Exception)信息

    异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置.下面介绍几种python中获取异常信息的方法,这里获取异常(Exception)信息采用try...except...程序 ...

  2. ASP.NET Web API 异常处理 HttpResponseException 以及Angularjs获取异常信息并提示

    一.HttpResponseException 如果一个Web API控制器抛出一个未捕捉异常,默认地,大多数异常都会被转化成一个带有状态码“500 – 内部服务器错误”的HTTP响应.HttpRes ...

  3. Java异常---获取异常的堆栈信息

    Java 实例 - 获取异常的堆栈信息  Java 实例 以下实例演示了使用异常类的 printStack() 方法来获取堆栈信息: Main.java 文件 public class Main{ p ...

  4. 获取异常信息e.printStackTrace()的内容

    获取异常信息e.printStackTrace()的内容 最近做项目的时候需要记录操作的日志,但是记录异常信息的是发现使用e.getMessage()根本无法满足需要,并且e.getMessage() ...

  5. oracle存储过程获取异常信息码和异常信息

    oracle存储过程,可以通过sqlcode 获取异常编码.通过sqlerrm获取异常信息. 例子: create or replace procedure write2blob(p_id in nu ...

  6. Python中获取异常(try Exception)信息

    异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置. 这里获取异常(Exception)信息采用try...except...程序结构.如下所示: try: ... exce ...

  7. SQL server 获取异常

    一.try...... catch 获取异常信息 /*======================================== 相关错误消 息如下: ERROR_NUMBER() 返回错误号. ...

  8. 获取异常信息里再出异常就找不到日志了,我TM人傻了

    本系列是 我TM人傻了 系列第三期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 最近组 ...

  9. 权限获取异常(不能用ModuleId,得换个名字)目前还没搞清楚为啥

    CenterController: /// <summary> /// 访问模块,写入系统菜单Id /// </summary> /// <param name=&quo ...

随机推荐

  1. CRM客户管理软件如何帮助销售?

    对现代企业来说,销售团队的作用是举足轻重的.这与企业的利益密切相关,因此提高企业的销售绩效是企业的首要目标.CRM客户管理软件能够帮助企业做到以客户为中心,构建及改善客户关系,帮助企业优化业务流程,实 ...

  2. 3、集成springfox-swagger 3.0.0 + 集成knife4j

    集成springfox-swagger 3.0.0 + 集成knife4j 1.基本用法 1.1.导入依赖 <!-- web接口 --> <dependency> <gr ...

  3. 线程中的join()

    http://blog.itpub.net/31555134/viewspace-2221319/ 一直对join()方法不是很理解,在A线程中, B线程调用了join()方法,然后在内部实际是wai ...

  4. [转]CURL常用命令

    From:http://www.cnblogs.com/gbyukg/p/3326825.html p.p1 { margin: 0 0 2px; font: 14px ".PingFang ...

  5. Adaptive AUTOSAR 学习笔记 3 - AP 背景、技术及特征(中文翻译)

    本系列学习笔记基于 AUTOSAR Adaptive Platform 官方文档 R20-11 版本.本文从AUTOSAR_EXP_PlatformDesign.pdf开始,一边学习,一边顺带着翻译一 ...

  6. 前端009-vue框架

    vue-admin-element https://panjiachen.github.io/vue-element-admin-site/zh/ 基于vue的生态做的很好,提供的很多的文档,中文.并 ...

  7. asp.net c#从SQL2008读取图片显示到网页

    //图像数据表:tx//字段id (nvarchar(50) ,image(image)//tgav为图片ID,实质为上传前的主名 (省略了.jpg) using System; using Syst ...

  8. flex布局制作自适应网页

    网页布局是css的一个重点应用.传统的布局都是依赖display.position.float属性来实现的,但是特殊布局就不易实现,如垂直居中. 01 flex布局是什么?‍ Flex 是 Flexi ...

  9. 将已经基本完成的项目推送到gitee上管理

    1,首先在gitee上创建仓库,保留一个.gitigonore就行,这样就得到一个远程仓库地址 2,仓库有文件,那么就需要先将这个文件pull下来: 在本地的项目目录中执行:git init git ...

  10. selenium 配置ie11 浏览器

    1.IEDriverServer下载与配置 用淘宝的镜像地址:https://npm.taobao.org/mirrors/selenium/. 选3.0版本的  IEDriverServer_x64 ...