connectivity - 问:在 SAP Cloud SDK 弹性中使用断路器
问题描述
当我尝试使用 ResilienceDecorator.executeCallable() 来启用断路器时,我必须在我的可调用对象中抛出 ResilienceRuntimeException 以使断路器工作。示例代码如下。没有它,断路器总是闭合的。这是正确的方法吗?
response = ResilienceDecorator.executeCallable(() -> {
HttpResponse response1 = tryHttpClient.get().execute(request);
if (response1.getStatusLine().getStatusCode() == 404){
throw new ResilienceRuntimeException("404 error is raised when calling SB api");
}
return response1;
},
ResilienceConfiguration.of(SubscriptionBillingAdapter.class).isolationMode(ResilienceIsolationMode.TENANT_OPTIONAL).timeLimiterConfiguration(ResilienceConfiguration.TimeLimiterConfiguration.of().timeoutDuration(Duration.ofSeconds(6L))).circuitBreakerConfiguration(ResilienceConfiguration.CircuitBreakerConfiguration.of().waitDuration(Duration.ofSeconds(600000L)).failureRateThreshold(1).closedBufferSize(1).halfOpenBufferSize(1)),
e -> {LOG.warn("resiliience fallback call: " + e); return response1;});
我问,因为我没有看到它的任何文件。此外,当我检查如何检索 SCP 中的目标配置时,我在 com.sap.cloud.sdk.cloudplatform.connectivity.DestinationService 中看到了以下代码。在使用 ResilienceDecorator.executeCallable() 时,它不会抛出 ResilienceRuntimeException。所以我的问题是我需要抛出 ResilienceRuntimeException 还是不让断路器工作?如果我不需要,我的代码有什么问题吗?
return (String)ResilienceDecorator.executeCallable(() -> {
XsuaaCredentials xsuaaCredentials = (new ServiceCredentialsRetriever()).getClientCredentials("destination");
AccessToken accessToken;
if (propagateUser) {
accessToken = xsuaaService.retrieveAccessTokenViaUserTokenExchange(xsuaaCredentials.getXsuaaUri(), xsuaaCredentials.getCredentials(), useProviderTenant);
} else {
accessToken = xsuaaService.retrieveAccessTokenViaClientCredentialsGrant(xsuaaCredentials.getXsuaaUri(), xsuaaCredentials.getCredentials(), useProviderTenant);
}
return this.fetchDestinationsJson(servicePath, accessToken);
}, ResilienceConfiguration.of(DestinationService.class).isolationMode(ResilienceIsolationMode.TENANT_OPTIONAL).timeLimiterConfiguration(TimeLimiterConfiguration.of().timeoutDuration(Duration.ofSeconds(6L))).circuitBreakerConfiguration(CircuitBreakerConfiguration.of().waitDuration(Duration.ofSeconds(6L))));
解决方案
不,您不必抛出ResilienceRuntimeException
. 实际上,SDK 仅使用它来将已检查和未检查的异常包装到未检查的异常中,该异常包装了弹性调用中发生的各种故障。
请详细说明您的问题,然后我将扩展此答案:
- 您使用的是哪个版本的 SDK?
- 您如何(以及多久)调用装饰的可调用对象?请展开代码块。
- 请指定您观察到的确切行为。调用修饰的可调用对象时会引发什么异常?如果断路器打开,这应该是一个
CallNotPermittedException
包裹在一个ResilienceRuntimeException
- 减少可调用以简单地抛出异常以简化代码
- 减少弹性配置以仅使用断路器(杠杆
ResilienceConfiguration.empty()
)。如果可行,请再次添加内容,直到无效为止。
作为参考,还请找到SDK 在后台使用弹性 4j 的文档来执行弹性操作。
推荐阅读
- python - Jinja2 默认值为 None
- node.js - 节点。部署在 digitalOcean,ES 模块错误
- python - 使用 numpy 查找 2 个列表列表之间的交集
- realm - 如何在多租户应用程序中使用 keyclaok
- ruby-on-rails - Rails 对必填字段的自定义验证
- c# - C# Azure Functions 和 Application Insights - LogError 未显示异常
- c# - 如何从在 asp.net core C# 中调用的线程调用公共异步任务方法()?
- python - jsonb 连接在 sqlalchemy 中无法正常工作
- sql-server - 如何将逻辑 OR 应用于 BINARY 列,以便结果是所有正确的值?
- google-sheets - 获取 A 和 B 之间的数字数组?