web-dev-qa-db-fra.com

Comment dire Hystrix pour ne pas déclencher de repli pour certaines des exceptions dans la commande Hystrix

Nous utilisions la fonctionnalité Hystrix en étendant directement la classe HystrixCommand. Mais pour certaines des exceptions commerciales, la méthode de secours d'Hystrix est déclenchée.

Je ne veux pas déclencher le repli Hystrix pour certaines des exceptions spécifiques à l'entreprise. Comment puis-je y parvenir sans annotation basée?

11
LazyGuy

Utilisez le paramètre d'annotation ignoreExceptions

@HystrixCommand(ignoreExceptions = { BaseException.class, MissingServletRequestParameterException.class, TypeMismatchException.class })

Voir https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#error-propagation

Je vois que vous étendez HystrixCommand au lieu d'utiliser l'annotation, mais cela n'a pas d'importance, définissez simplement cette propriété dans la commande et cela devrait avoir le même effet.

Malheureusement, une commande Hystrix est créée par un modèle Builder, vous devrez donc faire du piratage. L'ignoreExceptions a été ajoutée à DefaultProperties.Java, qui est utilisé dans HystrixCommandBuilder

1
sercasti

Deux façons de procéder.

  1. Utilisation de l'annotation HystrixCommand et spécification des types d'exception.

    @HystrixCommand(ignoreExceptions = { HttpStatusCodeException.class, JsonMappingException.class })
    
  2. En utilisant "HystrixBadRequestException" et personnalisez votre code de manière à ignorer quelques cas d'exception ou codes d'état. Cette implémentation vérifiera les codes d'erreur spécifiques sur les exceptions attendues avec votre contrat d'API backend et n'invoque pas le repli hystrix. Lancer "HystrixBadRequestException" ne sera pas considéré comme une erreur hystrix.

    @HystrixCommand(commandKey = "MyHystrixCommand", fallbackMethod = "myHystrixFallback", threadPoolKey = "ThreadPoolKey")
    public ResponseEntity<String> getServiceCallResponse(String serviceUrl, HttpEntity<?> entity) {
    ResponseEntity<String> resp = null;
    try {
    resp = restTemplate.exchange(serviceUrl, HttpMethod.POST, entity, String.class)
            .getBody();
    }
    catch(Exception e) {
        handleExceptionForHystrix("getServiceCallResponse", e);
    }
    return resp;
    }
    
    private void handleExceptionForHystrix(String function, Exception e) {
            if (e instanceof HttpStatusCodeException) {
                HttpStatus httpStatusCode = ((HttpStatusCodeException)e).getStatusCode();
                if(httpStatusCode.equals(HttpStatus.BAD_REQUEST) || httpStatusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
                    throw new HystrixBadRequestException("Hystrix Bad Request Exception Occurred" + httpStatusCode, e);
                }
                throw new RuntimeException(function, e);
            }
            throw new RuntimeException(function, e);
        }
    
    
    public ResponseEntity<String> myHystrixFallback(String serviceUrl, HttpEntity<?> entity, Throwable hystrixCommandExp) {
            return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    
1
Achu22

Si vous encapsulez votre logique dans un try/catch et relancez toutes les exceptions dans une HystrixBadRequestException, cela ne déclenchera pas le repli.

@Override
protected Object run() throws Exception {
    try {
        return //call goes here
    }
    catch (Throwable e) {
        //We wrap any exceptions in a HystrixBadRequestException because this way any other errors will not
        //trip the short circuit
        throw new HystrixBadRequestException("Exception thrown hystrix call", e);
    }
}

À partir des documents: http://netflix.github.io/Hystrix/javadoc/com/netflix/hystrix/exception/HystrixBadRequestException.html

Une exception représentant une erreur avec les arguments ou l'état fournis plutôt qu'un échec d'exécution. Contrairement à toutes les autres exceptions levées par un HystrixCommand, cela ne déclenchera pas de repli, ne comptera pas contre les mesures de défaillance et ne déclenchera donc pas le disjoncteur.

REMARQUE: cela ne doit être utilisé que lorsqu'une erreur est due à une entrée utilisateur telle que IllegalArgumentException, sinon elle va à l'encontre de l'objectif de tolérance aux pannes et du comportement de secours.

1
devo