我想处理任何例外的假客户,即使服务是不可用的。但是,我不能用try/catch来捕捉它们。这是我的假客户:
@FeignClient(name = "api-service", url ="localhost:8888")
public interface ClientApi extends SomeApi {
}其中api是:
@Path("/")
public interface SomeApi {
@GET
@Path("test")
String getValueFromApi();
}尝试/捕捉客户端的使用:
@Slf4j
@Service
@AllArgsConstructor
public class SampleController implements SomeApi {
@Autowired
private final ClientApi clientApi;
@Override
public String getValueFromApi() {
try {
return clientApi.getValueFromApi();
} catch (Throwable e) {
log.error("CAN'T CATCH");
return "";
}
}
}依赖关系出现在版本中:
代码应该按照如何处理假错误?工作。
我收到了很少的长堆栈跟踪,其中有例外:
如何正确捕获假出口,即使客户端服务(在本例中为localhost:8888)是不可用的?
Ps。当假客户服务可用时,它就能工作,好的。我只是专注于例外方面。
发布于 2020-01-01 14:42:52
一个更好的方法,以处理情况下,您的服务是不可用的是使用断路器模式。幸运的是,它很容易使用Netflix作为断路器模式的一个实现。
首先,您需要在应用程序配置中为伪客户端启用Hystrix。
application.yml
feign:
hystrix:
enabled: true然后,应该为指定的假冒伪劣客户端接口编写一个回退类。在这种情况下,回退类中的getValueFormApi方法在很大程度上将像您编写的catch块一样(当电路处于打开状态且不尝试原始方法时例外)。
@Component
public class ClientApiFallback implements ClientApi {
@Override
public String getValueFromApi(){
return "Catch from fallback";
}
}最后,您只需要为假冒伪劣客户端指定回退类。
@FeignClient(name = "api-service", url ="localhost:8888", fallback = ClientApiFallback.class)
public interface ClientApi extends SomeApi {
}这样,您的方法getValueFromApi是失败安全的。如果出于任何原因,从getValueFromApi转义任何未察觉的异常,则将调用ClientApiFallback方法。
发布于 2021-02-16 20:45:34
要启用断路器并配置应用程序以处理意外错误,您需要:
1.-开启断路器本身
@SpringBootApplication
@EnableFeignClients("com.perritotutorials.feign.client")
@EnableCircuitBreaker
public class FeignDemoClientApplication {2.-创建备份bean
@Slf4j
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PetAdoptionClientFallbackBean implements PetAdoptionClient {
@Setter
private Throwable cause;
@Override
public void savePet(@RequestBody Map<String, ?> pet) {
log.error("You are on fallback interface!!! - ERROR: {}", cause);
}
}在回退实现时,您必须记住一些事情:
3.-您的ErrorDecoder,根据返回的HTTP错误实现回退启动:
public class MyErrorDecoder implements ErrorDecoder {
private final ErrorDecoder defaultErrorDecoder = new Default();
@Override
public Exception decode(String methodKey, Response response) {
if (response.status() >= 400 && response.status() <= 499) {
return new MyCustomBadRequestException();
}
if (response.status() >= 500) {
return new RetryableException();
}
return defaultErrorDecoder.decode(methodKey, response);
}
}4.-在配置类中,将Retryer和ErrorDecoder添加到Spring上下文中:
@Bean
public MyErrorDecoder myErrorDecoder() {
return new MyErrorDecoder();
}
@Bean
public Retryer retryer() {
return new Retryer.Default();
}还可以向Retryer添加自定义:
class CustomRetryer implements Retryer {
private final int maxAttempts;
private final long backoff;
int attempt;
public CustomRetryer() {
this(2000, 5); //5 times, each 2 seconds
}
public CustomRetryer(long backoff, int maxAttempts) {
this.backoff = backoff;
this.maxAttempts = maxAttempts;
this.attempt = 1;
}
public void continueOrPropagate(RetryableException e) {
if (attempt++ >= maxAttempts) {
throw e;
}
try {
Thread.sleep(backoff);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
}
@Override
public Retryer clone() {
return new CustomRetryer(backoff, maxAttempts);
}
}如果您想获得一个关于如何在应用程序中实现假冒伪劣的功能示例,请阅读这文章。
https://stackoverflow.com/questions/59545710
复制相似问题