Spring boot 在本地运行的最新Spring云升级后,Spring云启动失败
在将我们的SpringCloud微服务(打包为Docker映像)部署到AWS之前,我们在本地针对LocalStack进行测试。因此,我们在代码库中定义了如下自动配置的bean:Spring boot 在本地运行的最新Spring云升级后,Spring云启动失败,spring-boot,spring-cloud,spring-cloud-stream,Spring Boot,Spring Cloud,Spring Cloud Stream,在将我们的SpringCloud微服务(打包为Docker映像)部署到AWS之前,我们在本地针对LocalStack进行测试。因此,我们在代码库中定义了如下自动配置的bean: @Bean("amazonKinesisAsyncMyBean") @Primary @Conditional(value = {LocalStackProfileCondition.class}) public AmazonKinesisAsync localAmazonKinesi
@Bean("amazonKinesisAsyncMyBean")
@Primary
@Conditional(value = {LocalStackProfileCondition.class})
public AmazonKinesisAsync localAmazonKinesisAsync(
final LocalStackProfileProperties localStackProfileProperties,
final LocalStackProperties localStackProperties,
AWSCredentialsProvider awsCredentialsProvider) {
System.setProperty(SDKGlobalConfiguration.AWS_CBOR_DISABLE_SYSTEM_PROPERTY, "true");
System.setProperty(SDKGlobalConfiguration.DISABLE_CERT_CHECKING_SYSTEM_PROPERTY, "true");
return AmazonKinesisAsyncClientBuilder.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
generateUriString(
localStackProperties.getProtocol().toLowerCase(),
localStackProperties.getHost(),
localStackProperties.getKinesis().getPort()),
localStackProfileProperties.getClient().getRegion()))
.withCredentials(awsCredentialsProvider)
.build();
}
通过Spring Boot 2.3.5.RELEASE、Spring Cloud Hoxton.SR4和Spring Cloud Stream Binder Kinesis 2.0.1.RELEASE,我们能够在本地针对LocalStack成功地测试Docker容器。但是,升级到Spring Cloud Hoxton.SR9后,我们的堆栈跟踪失败:
Caused by: com.amazonaws.SdkClientException: Unable to execute HTTP request: Connect to squid.acme.com:8080 [squid.acme.com/x.x.x.x, squid.acme.com/x.x.x.x, squid.acme.com/x.x.x.x] failed: connect timed out
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1207)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1153)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
at com.amazonaws.services.kinesis.AmazonKinesisClient.doInvoke(AmazonKinesisClient.java:2809)
at com.amazonaws.services.kinesis.AmazonKinesisClient.invoke(AmazonKinesisClient.java:2776)
at com.amazonaws.services.kinesis.AmazonKinesisClient.invoke(AmazonKinesisClient.java:2765)
at com.amazonaws.services.kinesis.AmazonKinesisClient.executeDescribeStream(AmazonKinesisClient.java:875)
at com.amazonaws.services.kinesis.AmazonKinesisClient.describeStream(AmazonKinesisClient.java:846)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.createOrUpdate(KinesisStreamProvisioner.java:135)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.provisionProducerDestination(KinesisStreamProvisioner.java:91)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.provisionProducerDestination(KinesisStreamProvisioner.java:57)
at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindProducer(AbstractMessageChannelBinder.java:223)
... 33 common frames omitted
我们的本地开发环境与internet隔离,因此通过代理连接超时。无论如何,首先的问题是,升级SpringCloud后,Kinesis绑定器似乎正在尝试连接到AWS以获取碎片列表。在使用新配置运行时,如何确保这些请求路由到LocalStack而不是AWS
更新1:
将Spring Cloud Stream Kinesis Binder更新为2.0.3.RELEASE后,我现在收到的堆栈跟踪如下:
Caused by: com.amazonaws.SdkClientException: Unable to execute HTTP request: Connect to squid.acme.com:8080 [squid.acme.com/x.x.x.x, squid.acme.com/x.x.x.x, squid.acme.com/x.x.x.x] failed: connect timed out
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1207)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1153)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
at com.amazonaws.services.kinesis.AmazonKinesisClient.doInvoke(AmazonKinesisClient.java:2809)
at com.amazonaws.services.kinesis.AmazonKinesisClient.invoke(AmazonKinesisClient.java:2776)
at com.amazonaws.services.kinesis.AmazonKinesisClient.invoke(AmazonKinesisClient.java:2765)
at com.amazonaws.services.kinesis.AmazonKinesisClient.executeListShards(AmazonKinesisClient.java:1557)
at com.amazonaws.services.kinesis.AmazonKinesisClient.listShards(AmazonKinesisClient.java:1528)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.getShardList(KinesisStreamProvisioner.java:141)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.getShardList(KinesisStreamProvisioner.java:122)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.createOrUpdate(KinesisStreamProvisioner.java:167)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.provisionProducerDestination(KinesisStreamProvisioner.java:93)
at org.springframework.cloud.stream.binder.kinesis.provisioning.KinesisStreamProvisioner.provisionProducerDestination(KinesisStreamProvisioner.java:59)
at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindProducer(AbstractMessageChannelBinder.java:223)
... 33 common frames omitted
更新2:
将org.springframework
日志记录级别设置为DEBUG
后,我能够捕获以下条件评估报告:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
ContextCredentialsAutoConfiguration matched:
- @ConditionalOnClass found required class 'com.amazonaws.auth.AWSCredentialsProvider' (OnClassCondition)
KinesisBinderConfiguration matched:
- @ConditionalOnMissingBean (types: org.springframework.cloud.stream.binder.Binder; SearchStrategy: all) did not find any beans (OnBeanCondition)
KinesisBinderConfiguration#dynamoDBStreams matched:
- @ConditionalOnMissingBean (types: com.amazonaws.services.dynamodbv2.AmazonDynamoDBStreams; SearchStrategy: all) did not find any beans (OnBeanCondition)
KinesisBinderConfiguration.KinesisBinderHealthIndicatorConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.boot.actuate.health.HealthIndicator' (OnClassCondition)
- @ConditionalOnEnabledHealthIndicator management.health.defaults.enabled is considered true (OnEnabledHealthIndicatorCondition)
KinesisBinderConfiguration.KinesisBinderHealthIndicatorConfiguration#kinesisBinderHealthIndicator matched:
- @ConditionalOnMissingBean (names: kinesisBinderHealthIndicator; SearchStrategy: all) did not find any beans (OnBeanCondition)
Negative matches:
-----------------
KinesisBinderConfiguration#amazonKinesis:
Did not match:
- @ConditionalOnMissingBean (types: com.amazonaws.services.kinesis.AmazonKinesisAsync; SearchStrategy: all) found beans of type 'com.amazonaws.services.kinesis.AmazonKinesisAsync' amazonKinesisAsyncMyBean (OnBeanCondition)
KinesisBinderConfiguration#cloudWatch:
Did not match:
- @ConditionalOnMissingBean (types: com.amazonaws.services.cloudwatch.AmazonCloudWatchAsync; SearchStrategy: all) found beans of type 'com.amazonaws.services.cloudwatch.AmazonCloudWatchAsync' amazonCloudWatchAsync (OnBeanCondition)
Matched:
- @ConditionalOnProperty (spring.cloud.stream.kinesis.binder.kpl-kcl-enabled) matched (OnPropertyCondition)
KinesisBinderConfiguration#dynamoDB:
Did not match:
- @ConditionalOnMissingBean (types: com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync; SearchStrategy: all) found beans of type 'com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync' amazonDynamoDBAsync (OnBeanCondition)
KinesisBinderConfiguration#dynamoDBLockRegistry:
Did not match:
- @ConditionalOnProperty (spring.cloud.stream.kinesis.binder.kpl-kcl-enabled=false) found different value in property 'spring.cloud.stream.kinesis.binder.kpl-kcl-enabled' (OnPropertyCondition)
KinesisBinderConfiguration#kinesisCheckpointStore:
Did not match:
- @ConditionalOnProperty (spring.cloud.stream.kinesis.binder.kpl-kcl-enabled=false) found different value in property 'spring.cloud.stream.kinesis.binder.kpl-kcl-enabled' (OnPropertyCondition)
KinesisBinderConfiguration#kinesisProducerConfiguration:
Did not match:
- @ConditionalOnMissingBean (types: com.amazonaws.services.kinesis.producer.KinesisProducerConfiguration; SearchStrategy: all) found beans of type 'com.amazonaws.services.kinesis.producer.KinesisProducerConfiguration' kinesisProducerConfiguration (OnBeanCondition)
Matched:
- @ConditionalOnProperty (spring.cloud.stream.kinesis.binder.kpl-kcl-enabled) matched (OnPropertyCondition)
Exclusions:
-----------
None
Unconditional classes:
----------------------
None
让我们再看一次这种情况:
KinesisBinderConfiguration#amazonKinesis:
Did not match:
- @ConditionalOnMissingBean (types: com.amazonaws.services.kinesis.AmazonKinesisAsync; SearchStrategy: all) found beans of type 'com.amazonaws.services.kinesis.AmazonKinesisAsync' amazonKinesisAsync (OnBeanCondition)
请注意
amazonKinesisAsync
bean名称。看起来它不属于您配置中提到的localAmazonKinesisAsync
bean。可能你的条件不起作用了,另一个AmazonKinesisAsync
bean赢了,它已经指向了squid.acme.com:8080
端点…请尝试升级到Kinesis binder2.0.3
,并与我们共享已经存在的堆栈跟踪。看起来我无法将堆栈跟踪与代码库相关联。另一种想法。您提到了“您自己的自动配置”之类的内容。您是否在KinesisBinderConfiguration
或BinderFactoryAutoConfiguration
之前配置了它?我的意思是,我们需要确保在Kinesis活页夹开始配置之前,您的自定义AmazonKinesisAsync
已真正加载。我将活页夹更新为2.0.3,并使用更新的堆栈跟踪更新了我的帖子@ArtemBilan,我如何判断bean是在KinesisBinderConfiguration
或BinderFactoryAutoConfiguration
之前还是之后配置的?或者更好的是,我如何确保我的bean总是在这些之前配置?@ArtemBilan,根据我在原始帖子中添加的第二次更新中的第一次负匹配,我的AmazonKinesisAsync
bean似乎在KinesisBinderConfiguration
运行时已经创建好了。你同意吗?当我最初发布时,我忘了复制@Bean(“amazonKinesisAsync”)
行,所以条件实际上与我的Bean匹配。可以肯定的是,我将名称改为@Bean(“amazonKinesisAsyncMyBean”)
,然后重新运行测试。我已经用完整的bean定义和最新的条件评估报告更新了我的原始帖子。您将看到,实际上,条件中引用的是我的bean。很抱歉,我一开始就忽略了@Bean
行。我不知道为什么它尝试不连接到LocalStack。有机会和我们分享一个简单的项目吗?我必须创建一个完全独立的项目。不幸的是,我被严格禁止分享我目前正在使用的任何代码。当然!但是我认为创建一个新的普通项目不需要太多的代码。我们需要证明的只是调用getShardList()
时使用LocalStack的一种方法。或者LocalStack没有为我们实现那个API?。。