2014-11-25 193 views
0

我想了解Hystrix是如何處理非故障錯誤和HystrixBadRequestException,特別是在驗證領域。我用我所有的豆類JSR-303 Bean驗證(Hibernate驗證):Hystrix:HystrixBadRequestException失敗驗證

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裏面的命令(不在其外面)。根據文檔,這個例外是針對非故障例外的,包括非法參數。我只是沒有看到如何將我的驗證放入命令中並利用它(例如,失敗的驗證不會計入我的指標/統計)。

回答

2

事實證明,您需要將HystrixBadRequestException放入的 impl。在我的情況下,解決辦法是驗證移動到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); 
    } 
} 

現在,如果驗證失敗,外層的異常是HystrixBadRequestException,它不會佔用斷路器統計或發佈的指標。