0

我试图了解 Hystrix 如何处理非故障错误HystrixBadRequestException,尤其是在验证领域。我对所有 bean 使用 JSR-303 bean 验证(Hibernate 验证器):

public class User {
    @Min(1L)
    private Long id;

    @NotNull
    @Email      
    private String email;
}

public class UserValidator {
    private Validator validator;

    // Throw exception if the user is invalid; return void otherwise.
    public void validateUser(User user) {
        Set<ConstraintViolation<User>> violations = validator.validate(user);
        if(!violations.isEmpty()) {
            return new BadEntityException(violations);
        }
    }
}

// Hystrix command.
public class SaveUserCommand extends HystrixCommand<User> {
    public User user;

    public void doSaveUser(User user) {
        this.user = user;
        execute();
    }

    @Override
    protected User run() {
        // Save 'user' somehow
    }

    @Override
    protected User getFallback() {
        return null;
    }
}

// My service client that uses my Hystrix command.
public class UserClient {
    private SaveUserCommandFactory factory = new SaveUserCommandFactory();
    private UserValidator validator = new UserValidator();

    public User saveUser(User user) {
        SaveUserCommand saveUserCommand = factory.newSaveUserCommand();
        validator.validate(user);
        user = saveUserCommand.doSaveUser(user);

        return user;
    }
}

虽然这应该可行,但我觉得它HystrixBadRequestException是为此目的而创建的,并且我可以以某种方式将命令validator 放在命令内部(而不是在命令外部)。根据文档,此异常旨在用于非故障异常,包括非法参数。我只是没有看到如何将我的验证放入命令中并利用它(这样失败的验证不计入我的指标/统计数据)。

4

1 回答 1

2

事实证明,您需要将impl放入HystrixBadRequestException 内部。HystrixCommand就我而言,解决方案是将验证器移到SaveUserCommand#run()方法中:

@Override
protected void run() {
    try {
        validator.validate(user);
        // Save user somehow
    } catch(BadEntityException bexc) {
        log.error(bexc);
        throw new HystrixBadRequestException("Hystrix caught a bad request.", bexc);
    }
}

现在,如果验证失败,外部异常是 aHystrixBadRequestException并且它不会计入断路器统计信息或已发布的指标。

于 2014-11-29T19:19:36.120 回答