首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >捕捉异常假象

捕捉异常假象
EN

Stack Overflow用户
提问于 2019-12-31 15:04:49
回答 2查看 3K关注 0票数 0

我想处理任何例外的假客户,即使服务是不可用的。但是,我不能用try/catch来捕捉它们。这是我的假客户:

代码语言:javascript
复制
@FeignClient(name = "api-service", url ="localhost:8888")
public interface ClientApi extends SomeApi {

}

其中api是:

代码语言:javascript
复制
@Path("/")
public interface SomeApi {

  @GET
  @Path("test")
  String getValueFromApi();

}

尝试/捕捉客户端的使用:

代码语言:javascript
复制
@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 "";
    }
  }
}

依赖关系出现在版本中:

  • 弹簧-启动2.2.2
  • 春云Hoxton.SR1

代码应该按照如何处理假错误?工作。

我收到了很少的长堆栈跟踪,其中有例外:

  1. 由: java.net.ConnectException:连接拒绝(连接拒绝)引起
  2. 由:feign.RetryableException引起:连接拒绝(连接拒绝)执行GET http://localhost:8888/test
  3. 原因: com.netflix.hystrix.exception.HystrixRuntimeException: ClientApi#getValueFromApi()失败,没有备用的。

如何正确捕获假出口,即使客户端服务(在本例中为localhost:8888)是不可用的?

Ps。当假客户服务可用时,它就能工作,好的。我只是专注于例外方面。

EN

回答 2

Stack Overflow用户

发布于 2020-01-01 14:42:52

一个更好的方法,以处理情况下,您的服务是不可用的是使用断路器模式。幸运的是,它很容易使用Netflix作为断路器模式的一个实现。

首先,您需要在应用程序配置中为伪客户端启用Hystrix。

application.yml

代码语言:javascript
复制
feign:
  hystrix:
    enabled: true

然后,应该为指定的假冒伪劣客户端接口编写一个回退类。在这种情况下,回退类中的getValueFormApi方法在很大程度上将像您编写的catch块一样(当电路处于打开状态且不尝试原始方法时例外)。

代码语言:javascript
复制
@Component
public class ClientApiFallback implements ClientApi {

  @Override
  public String getValueFromApi(){
    return "Catch from fallback";
  }
}

最后,您只需要为假冒伪劣客户端指定回退类。

代码语言:javascript
复制
@FeignClient(name = "api-service", url ="localhost:8888", fallback = ClientApiFallback.class)
public interface ClientApi extends SomeApi {

}

这样,您的方法getValueFromApi是失败安全的。如果出于任何原因,从getValueFromApi转义任何未察觉的异常,则将调用ClientApiFallback方法。

票数 0
EN

Stack Overflow用户

发布于 2021-02-16 20:45:34

要启用断路器并配置应用程序以处理意外错误,您需要:

1.-开启断路器本身

代码语言:javascript
复制
@SpringBootApplication
@EnableFeignClients("com.perritotutorials.feign.client")
@EnableCircuitBreaker
public class FeignDemoClientApplication {

2.-创建备份bean

代码语言:javascript
复制
@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);
    }
}

在回退实现时,您必须记住一些事情:

  • 必须标记为@Component,它们在应用程序中是唯一的。
  • 回退bean应该有一个原型范围,因为我们希望为每个异常创建一个新的范围。
  • 为测试目的使用构造函数注入。

3.-您的ErrorDecoder,根据返回的HTTP错误实现回退启动:

代码语言:javascript
复制
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上下文中:

代码语言:javascript
复制
@Bean
public MyErrorDecoder myErrorDecoder() {
  return new MyErrorDecoder();
}

@Bean
public Retryer retryer() {
    return new Retryer.Default();
}

还可以向Retryer添加自定义:

代码语言:javascript
复制
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);
    }
}

如果您想获得一个关于如何在应用程序中实现假冒伪劣的功能示例,请阅读文章。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59545710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档