0

我们使用 CAP 通过 ODATA V2 调用者查询数据。但是在我的本地环境测试期间出现了异常。我可以在一开始就成功地得到结果。在我测试了几次之后,它每次都会引发异常。请帮我解决这个问题。

目的地设置:

URL=https\://cxs-calmdevprovider-calmdev-sap-calm-imp-pjm-srv.cfapps.sap.hana.ondemand.com
Name=PJM-SRV-DEST
TrustAll=TRUE
ProxyType=Internet
Type=HTTP
Authentication=AppToAppSSO

两个应用程序绑定到一个 XSUAA。并将 VCAP_SERVICE 设置为本地运行。

        try {

            logger.debug("==> now execute query on Products");
            FilterExpression filter = new FilterExpression("project_guid", "eq",
                    ODataType.of(UUID.fromString("10c0b945-1ff5-4510-a160-24294bfe3b58")));

            CacheKey cKey = CacheKey.ofTenantAndUserIsolation();
            ODataQueryResult result = ODataQueryBuilder.withEntity("/odata/v2/CBLD_PROJECT_SRV", "CBLD_C_PROJECT_MS_TP")
                    .filter(filter).enableMetadataCache(cKey).build().execute("PJM-SRV-DEST");

            logger.debug("==> After calling backend OData V2 service: result: " + result);

            List<ProjectMilestone> projectMilestones = result.asList(ProjectMilestone.class);
            logger.info(projectMilestones.toString());

        } catch (Exception e) {
            logger.error("==> Exception calling backend OData V2 service for Query of Products: " + e.getMessage());
            ErrorResponse errorResponse =
                    ErrorResponse.getBuilder().setMessage("There is an error.  Check the logs for the details.")
                            .setStatusCode(500).setCause(e).response();
            return UpdateResponse.setError(errorResponse);
        }

异常堆栈:

2019-08-20 14:05:03,446 DEBUG [http-nio-8081-exec-2] - [com.sap.calm.imp.tkm.srv.odata.handler.TaskServiceHandler] [tenant_id=05e65d26-f3e2-4937-9987-eb412f4cd732, component_id=7d44b23e-c4c1-42ba-9c60-0048c14a6937, component_name=cxs-calm-build-tkm-srv, organization_name=-, component_type=application, endpoint=PATCH: /odata/v2/CBLD_TASK_SRV/CBLD_C_TASK_TP(guid%27cba383f1-809f-40f1-8c76-cddd2b381c4c%27), space_name=CALMDev, component_instance=0, organization_id=-, correlation_id=825395c1-583d-4e5c-8ae4-6f9eaf19aae2, space_id=3bbd276d-7965-4625-aae9-da06139845ea, request_id=-, container_id=-] - ==> now execute query on Products
2019-08-20 14:05:12,322 WARN  [http-nio-8081-exec-2] - [com.netflix.config.sources.URLConfigurationSource] [tenant_id=05e65d26-f3e2-4937-9987-eb412f4cd732, component_id=7d44b23e-c4c1-42ba-9c60-0048c14a6937, component_name=cxs-calm-build-tkm-srv, organization_name=-, component_type=application, endpoint=PATCH: /odata/v2/CBLD_TASK_SRV/CBLD_C_TASK_TP(guid%27cba383f1-809f-40f1-8c76-cddd2b381c4c%27), space_name=CALMDev, component_instance=0, organization_id=-, correlation_id=825395c1-583d-4e5c-8ae4-6f9eaf19aae2, space_id=3bbd276d-7965-4625-aae9-da06139845ea, request_id=-, container_id=-] - No URLs will be polled as dynamic configuration sources.
2019-08-20 14:05:19,270 ERROR [http-nio-8081-exec-2] - [com.sap.cloud.sdk.odatav2.connectivity.ODataQuery] [tenant_id=05e65d26-f3e2-4937-9987-eb412f4cd732, component_id=7d44b23e-c4c1-42ba-9c60-0048c14a6937, component_name=cxs-calm-build-tkm-srv, organization_name=-, component_type=application, endpoint=PATCH: /odata/v2/CBLD_TASK_SRV/CBLD_C_TASK_TP(guid%27cba383f1-809f-40f1-8c76-cddd2b381c4c%27), space_name=CALMDev, component_instance=0, organization_id=-, correlation_id=825395c1-583d-4e5c-8ae4-6f9eaf19aae2, space_id=3bbd276d-7965-4625-aae9-da06139845ea, request_id=-, container_id=-] - Could not connect to destination service [No Access] :com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException: Failed to get destinations: com.sap.cloud.sdk.cloudplatform.connectivity.DestinationServiceCommand#t=05e65d26-f3e2-4937-9987-eb412f4cd732#u= timed-out and fallback disabled. If your application is running on Cloud Foundry, make sure to have a binding to both the destination service and the authorization and trust management (xsuaa) service, AND that you either properly secured your application or have set the "ALLOW_MOCKED_AUTH_HEADER" environment variable to true. Please note that authentication types with user propagation, for example, principal propagation or the OAuth2 SAML Bearer flow, require that you secure your application and will not work when using the "ALLOW_MOCKED_AUTH_HEADER" environment variable. If your application is not running on Cloud Foundry, for example, when deploying to a local container, consider declaring the "destinations" environment variable to configure destinations.
2019-08-20 14:05:19,271 ERROR [http-nio-8081-exec-2] - [com.sap.cloud.sdk.odatav2.connectivity.ODataQuery] [tenant_id=05e65d26-f3e2-4937-9987-eb412f4cd732, component_id=7d44b23e-c4c1-42ba-9c60-0048c14a6937, component_name=cxs-calm-build-tkm-srv, organization_name=-, component_type=application, endpoint=PATCH: /odata/v2/CBLD_TASK_SRV/CBLD_C_TASK_TP(guid%27cba383f1-809f-40f1-8c76-cddd2b381c4c%27), space_name=CALMDev, component_instance=0, organization_id=-, correlation_id=825395c1-583d-4e5c-8ae4-6f9eaf19aae2, space_id=3bbd276d-7965-4625-aae9-da06139845ea, request_id=-, container_id=-] - Could not connect to destination service [No Access] : [Ljava.lang.StackTraceElement;@7beb95af
2019-08-20 14:05:19,280 ERROR [http-nio-8081-exec-2] - [com.sap.calm.imp.tkm.srv.odata.handler.TaskServiceHandler] [tenant_id=05e65d26-f3e2-4937-9987-eb412f4cd732, component_id=7d44b23e-c4c1-42ba-9c60-0048c14a6937, component_name=cxs-calm-build-tkm-srv, organization_name=-, component_type=application, endpoint=PATCH: /odata/v2/CBLD_TASK_SRV/CBLD_C_TASK_TP(guid%27cba383f1-809f-40f1-8c76-cddd2b381c4c%27), space_name=CALMDev, component_instance=0, organization_id=-, correlation_id=825395c1-583d-4e5c-8ae4-6f9eaf19aae2, space_id=3bbd276d-7965-4625-aae9-da06139845ea, request_id=-, container_id=-] - ==> Exception calling backend OData V2 service for Query of Products: Unable to execute the OData operation : Failed to execute OData request.

4

1 回答 1

1

从您的DEBUG消息到第一条消息需要将近 9 秒WARN,抱怨超时。事实上,SAP Cloud SDK内部的默认超时DestinationServiceCommand设置为6 秒


如果在您的情况下查询所有目的地确实需要超过6 秒,那么我会建议一种解决方法,直到我们找到合适的解决方案:

1.) 创建一个新类 CustomHystrixPropertiesStrategy

import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesCommandDefault;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;

import javax.annotation.Nonnull;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CustomHystrixPropertiesStrategy extends HystrixPropertiesStrategy
{
    private final Map<HystrixCommandKey, HystrixCommandProperties> commandProperties = new ConcurrentHashMap<>();

    @Nonnull
    private HystrixPropertiesStrategy delegate;

    public static CustomHystrixPropertiesStrategy register()
    {
        final HystrixPropertiesStrategy delegate = HystrixPlugins.getInstance().getPropertiesStrategy();
        final CustomHystrixPropertiesStrategy strategy = new CustomHystrixPropertiesStrategy();

        HystrixPlugins.reset();
        HystrixPlugins.getInstance().registerPropertiesStrategy(strategy);
        strategy.delegate = delegate;

        return strategy;
    }

    public void addProperties(
        @Nonnull final HystrixCommandKey key,
        @Nonnull final HystrixCommandProperties.Setter customSetter )
    {
        final HystrixCommandProperties properties = new HystrixPropertiesCommandDefault(key, customSetter);
        commandProperties.put(key, properties);
    }

    @Override
    public
        HystrixCommandProperties
        getCommandProperties( final HystrixCommandKey key, final HystrixCommandProperties.Setter builder )
    {
        if( commandProperties.containsKey(key) ) {
            return commandProperties.get(key);
        }
        return delegate.getCommandProperties(key, builder);
    }
}

2.) 注册自定义策略实例

您需要运行以下操作并保留返回的实例。这可能发生在您的应用程序的中心点或静态地发生在您的服务类中,这样指令只运行一次

final CustomHystrixPropertiesStrategy strategy = CustomHystrixPropertiesStrategy.register();

注意:如果你想确保它只运行一次,你可以把它放到一个静态块中:

static {
  final CustomHystrixPropertiesStrategy strategy = CustomHystrixPropertiesStrategy.register();
}

3.) 为特定的 Hystrix 命令添加自定义超时属性。

您可以在(当前)中断调用之前添加以下代码。

// reconstruct existing command key
final String tenantId = TenantAccessor.getCurrentTenantIfAvailable().map(Tenant::getTenantId).orElse(null);
final String commandKey = HystrixUtil.getCommandKey(DestinationServiceCommand.class, tenantId, null);
final HystrixCommandKey destinationServiceCommandKey = HystrixCommandKey.Factory.asKey(commandKey);

// construct custom command properties
final HystrixCommandProperties.Setter customSetter =
    HystrixCommandProperties
        .Setter()
        .withExecutionTimeoutInMilliseconds(60000) // 60 SECONDS INSTEAD OF 6 SECONDS
        .withCircuitBreakerEnabled(true)
        .withCircuitBreakerSleepWindowInMilliseconds(1000)
        .withFallbackEnabled(false);

// apply custom Command properties
strategy.addProperties(destinationServiceCommandKey, customSetter);

确保对自定义策略的引用在范围内。

CustomHystrixPropertiesStrategy strategy;

如果它没有按预期工作,请尝试添加断点或一些日志输出,以确保在应用程序运行时实际到达新代码。

于 2019-08-22T12:44:29.160 回答