【发布时间】:2019-03-27 20:45:01
【问题描述】:
我遇到了@CircuitBreaker 没有重试的问题。
我有一个服务类(例如 UserService 类和方法名称 getUser),该方法调用另一个 Spring bean(例如 AppClient 和 execute),后者又调用远程服务(REST 调用)。 execute 方法用 Spring-Retry 的 @CircuitBreaker 注释。
我已经在 rest 控制器中公开了对服务方法(类 UserService 和方法名称 getUser)的调用,并使用 Postman 对其进行了测试。这是发生的事情 - 如果发生超时错误,它会调用 @Recover 方法。但它不会重试调用远程服务三次(默认值)。
如果我通过 Postman 手动运行 3 次,断路器状态变为 OPEN 并将调用重定向到 @Recover 方法,并且在重置超时后,它会继续调用远程服务。
另外,我用@Retryable 替换了@CircuitBreaker,这使得调用3 次(默认值)。我正在使用 spring-retry 版本 1.2.1.RELEASE 和 aspectjtools 版本 1.6.2。
为什么不使用@CircuitBreaker 重试?我希望同时具有断路器和重试功能。根据文档@CircuitBreaker 应该两者都做。任何帮助将不胜感激。
@Configuration
@EnableRetry
public class cfgUserApp
{
}
@RestController
public class UserController
{
@Autowired
UserService userService;
@RequestMapping(value = "/user/{userId}", method = RequestMethod.GET, headers = "Accept=application/json")
public ResponseEntity<User> getUser(@PathVariable String userId) {
return ok(userService.getUser(userId));
}
}
/* Spring Bean -- userService */
public class UserServiceImpl
implements userService
{
@Override
public User getUser( final String userId )
{
checkArgument( User != null && !User.isEmpty(), "User Id can not be null or empty." );
try
{
final HttpGet request = buildGetUserRequest( userId );
final User userResult = appClient.execute( request,
response -> createGetReservationResult( response ) );
return userResult;
}
catch ( final IOException e )
{
LOG.error( "getUser failed.", e );
throw new AppException(e.getMessage(), e);
}
}
}
public Class Appclient {
@Recover
public <T> T recover(AppException appException, final HttpUriRequest request,
final ResponseHandler<T> responseFunction )
{
System.out.println("In Recovery");
return <T>new User();
}
@CircuitBreaker( include = AppException.class, openTimeout = 5000l, resetTimeout = 10000l )
public <T> T execute( final HttpUriRequest request,
final ResponseHandler<T> responseFunction )
{
// HTTP call
}
}
【问题讨论】:
标签: spring-retry circuit-breaker