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>
appication.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
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" ;
    }
}
下記のような異常が発生します。
Whiteelabel Errer Page
This appication hasのexplicit mapping for/error、so you are seeigng this as a fallback.
Fri May 25 14:27:51 CST 2018
The e e was an unexpected error(type=Internal Server Error、status=500)
fallback method wasn't found:addServiceFallback([class java.lang.Integer])
これは指定された代替方法addServiceFallbackと元の方法get Bookのパラメータの個数とパラメータのタイプが異なることによるものである。
addServiceFallback方法を修正します。

public  String addServiceFallback(Integer  bookId){
    System.out.println("error addServiceFallback.... ");
    return  "error" ;
}
運転を続けると、以下のような異常が発生します。
Whiteelabel Errer Page
This appication hasのexplicit mapping for/error、so you are seeigng this as a fallback.
Fri May 25 14:32:24 CST 2018
The e e was an unexpected error(type=Internal Server Error、status=500)
Incomptible return types.Command method:public comp.bmcc.springboott.model.Book comp.bmcc.spring boot.service.BookService.getBook(java.lang.Integer);Fallback method:public java.lang.String comple.bmcc.springboot.service.Book Service.addServiceFallback(java.lang.Integer);Hist:Fallback method'public java.lang.String comple.bmcc.spring boott.service.BookServicer.addServiceFallback(java.lang.Integer)'mst return:class comp.bcc.sprigboot.spring
これは、指定された代替方法addServiceFallbackと元の方法get Bookがパラメータの個数であり、パラメータのタイプが同じであるが、方法の戻り値のタイプが異なるためである。
addServiceFallback方法を修正します。

public  Book  addServiceFallback(Integer  bookId){
    System.out.println("error addServiceFallback.... ");
    return  new Book() ;
}
運転を継続すると、サービスプロバイダが異常に閉鎖された時、消費者(消費者はポーリング方式で消費サービスを利用している)が再度サービスにアクセスした時、異常ページを投げずに次のように見える。

{"bookId":0,"bookName":null,"price":null,"publisher":null}
以上は個人の経験ですので、参考にしていただければと思います。