欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Cloud Gateway Hystrix fallback获取异常信息的处理

程序员文章站 2022-06-25 10:18:18
gateway hystrix fallback获取异常信息gateway 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”本身,并且没有异常信息:

Spring Cloud Gateway Hystrix fallback获取异常信息的处理

后来我重新到hystrixgatewayfilterfactory类中去查看,发现了异常信息其实在exchange里:

Spring Cloud Gateway Hystrix fallback获取异常信息的处理

而请求的接口也通过debug找到了:

Spring Cloud Gateway Hystrix fallback获取异常信息的处理

所以将代码改成如下:

@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);
    }
}

正常取到请求路径以及异常信息:

Spring Cloud Gateway Hystrix fallback获取异常信息的处理

关于 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}

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