Spring Cloud Gateway Hystrix fallback获取异常信息的处理
gateway hystrix fallback获取异常信息
gateway fallback后,需要知道请求的是哪个接口以及具体的异常信息,根据不同的请求以及异常进行不同的处理。一开始根据网上一篇博客上的做法:
pom.xml:
<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>
application.yml:
spring: cloud: gateway: discovery: locator: enabled: false lowercaseserviceid: true routes: - id: auth-server uri: lb://ms-oauth2-server predicates: - path=/** default-filters: - name: hystrix args: name: fallbackcmd fallbackuri: forward:/fallback
然后fallback就是这样:
@restcontroller @slf4j public class fallbackcontroller { @requestmapping(value = "/fallback") @responsestatus public mono<map<string, object>> fallback(serverwebexchange exchange, throwable throwable) { map<string, object> result = new hashmap<>(3); serverhttprequest request = exchange.getrequest(); log.error("接口调用失败,url={}", request.getpath().pathwithinapplication().value(), throwable); result.put("code", 60002); result.put("data", null); result.put("msg", "接口调用失败!"); return mono.just(result); } }
但是测试发现,这样取出来的接口地址只是“/fallback”本身,并且没有异常信息:
后来我重新到hystrixgatewayfilterfactory类中去查看,发现了异常信息其实在exchange里:
而请求的接口也通过debug找到了:
所以将代码改成如下:
@restcontroller @slf4j public class fallbackcontroller { @requestmapping(value = "/fallback") @responsestatus public mono<map<string, object>> fallback(serverwebexchange exchange) { map<string, object> result = new hashmap<>(3); result.put("code", 60002); result.put("data", null); exception exception = exchange.getattribute(serverwebexchangeutils.hystrix_execution_exception_attr); serverwebexchange delegate = ((serverwebexchangedecorator) exchange).getdelegate(); log.error("接口调用失败,url={}", delegate.getrequest().geturi(), exception); if (exception instanceof hystrixtimeoutexception) { result.put("msg", "接口调用超时"); } else if (exception != null && exception.getmessage() != null) { result.put("msg", "接口调用失败: " + exception.getmessage()); } else { result.put("msg", "接口调用失败"); } return mono.just(result); } }
正常取到请求路径以及异常信息:
关于 hystrix 的异常 fallback method wasn't found
消费者服务--service 的实现如下:
@service public class bookservice { @autowired public resttemplate resttemplate; @hystrixcommand(fallbackmethod = "addservicefallback") public book getbook( integer bookid ){ return resttemplate.getforobject("http://provider-service/boot/book?bookid={bookid}",book.class , bookid); } public string addservicefallback(){ system.out.println("error addservicefallback.... "); return "error" ; } }
就会出现如下所述的异常
whitelabel error page
this application has no explicit mapping for /error, so you are seeing this as a fallback.fri may 25 14:27:51 cst 2018
there was an unexpected error (type=internal server error, status=500).
fallback method wasn't found: addservicefallback([class java.lang.integer])
这是因为指定的 备用方法 addservicefallback 和 原方法getbook 的参数个数,参数类型 不同造成的;
修改addservicefallback 方法:
public string addservicefallback(integer bookid){ system.out.println("error addservicefallback.... "); return "error" ; }
继续运行,就会出现如下所述的异常
whitelabel error page
this application has no explicit mapping for /error, so you are seeing this as a fallback.fri may 25 14:32:24 cst 2018
there was an unexpected error (type=internal server error, status=500).
incompatible return types. command method: public com.bmcc.springboot.model.book com.bmcc.springboot.service.bookservice.getbook(java.lang.integer); fallback method: public java.lang.string com.bmcc.springboot.service.bookservice.addservicefallback(java.lang.integer); hint: fallback method 'public java.lang.string com.bmcc.springboot.service.bookservice.addservicefallback(java.lang.integer)' must return: class com.bmcc.springboot.model.book or its subclass
这是因为指定的 备用方法 addservicefallback 和 原方法getbook 虽然 参数个数,参数类型 相同 ,但是 方法的返回值类型不同造成的;
修改addservicefallback 方法:
public book addservicefallback(integer bookid){ system.out.println("error addservicefallback.... "); return new book() ; }
继续运行,这样就可以看到当一个服务提供者异常关闭时, 消费者(消费者采用轮询的方式消费服务)再继续访问服务时,不会抛出异常页面,而是如下:
{"bookid":0,"bookname":null,"price":null,"publisher":null}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
记录spring-cloud-gateway获取post请求body参数,以及后端服务处理后的响应参数过程 gateway:2.2.0.RELEASE
-
Spring Cloud Gateway Hystrix fallback获取异常信息的处理
-
记录spring-cloud-gateway获取post请求body参数,以及后端服务处理后的响应参数过程 gateway:2.2.0.RELEASE
-
Spring Cloud Gateway全局通用异常处理的实现
-
Spring Cloud Gateway的全局异常处理的介绍(代码示例)
-
Spring Cloud Gateway Hystrix fallback获取异常信息的处理
-
Spring Cloud Gateway的全局异常处理的介绍(代码示例)