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}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。