[英]Spring Boot App Doesn't Work on AWS - Tomcat Throws UnsatisfiedDependencyExceptions
[英]AWS Instance Profile doesn't work with Spring Cloud AWS
我有一個小的Spring Boot應用程序,使用Spring Cloud AWS( 1.0.0.RELEASE
)來訪問SQS隊列。 它部署在具有實例配置文件集的EC2實例上。 似乎AWS的一面正在發揮作用,因為我可以訪問相關的元數據鏈接: iam/info
和iam/security-credentials/role-name
,它們確實包含正確的信息。 只是為了確定,我已經使用了aws cmdline實用程序(aws sqs list-queues)並且確實有效,所以我猜設置正常。 但是,當應用程序啟動時,它會讀取application.properties
(包含行cloud.aws.credentials.instanceProfile=true
),然后在警告之后刪除: com.amazonaws.util.EC2MetadataUtils: Unable to retrieve the requested metadata
並最終拋出異常:
Caused by: com.amazonaws.AmazonServiceException: The security token included in the request is invalid. (Service: AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1071)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:719)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:454)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:294)
at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2291)
at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.java:516)
at com.amazonaws.services.sqs.buffered.AmazonSQSBufferedAsyncClient.getQueueUrl(AmazonSQSBufferedAsyncClient.java:278)
at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:78)
at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:37)
at org.springframework.messaging.core.CachingDestinationResolverProxy.resolveDestination(CachingDestinationResolverProxy.java:88)
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:295)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.start(SimpleMessageListenerContainer.java:38)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
... 17 common frames omitted
...這意味着由於某種原因,Spring Cloud AWS沒有獲得實例配置文件憑據。 我在com.amazonaws.request
上啟用了debug
日志級別,看來請求是在沒有訪問密鑰和密鑰的情況下發送的。
DEBUG --- com.amazonaws.request : Sending Request: POST https://sqs.eu-west-1.amazonaws.com / Parameters: (Action: GetQueueUrl, Version: 2012-11-05, QueueName: xxxxxxxxxxxxx, ) Headers: (User-Agent: aws-sdk-java/1.9.3 Linux/3.14.35-28.38.amzn1.x86_64 Java_HotSpot(TM)_64-Bit_Server_VM/25.45-b02/1.8.0_45 AmazonSQSBufferedAsyncClient/1.9.3, )
任何人都知道我缺少什么或至少有任何提示如何進一步調試這個?
編輯:經過spring-cloud-aws代碼之后,我有點向前邁進了。 與jar捆綁的配置文件application.properties
具有accessKey
和secretKey
一些文本值。 我的自定義application.properties
沒有獲得這些屬性,這可能導致spring將捆綁文件中的值用作默認值。 我用空值包含它們,這將異常更改為com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain
。 似乎AWS SDK配置了DefaultProviderChain,但它仍然無法獲取實例配置文件憑據。
這個問題的解決方案來自兩個截然不同的事實。
僅當application.properties
將instanceProfile
屬性設置為true
且 accessKey
設置為null
( ContextCredentialsAutoConfiguration )時, 才會使用實例配置文件憑據。
即使您將提供自定義的application.properties
文件,Spring也會讀取與app jar捆綁在一起的application.properties
文件(如果它確實存在)。 如果是這種情況,兩個文件中的屬性將總結為創建執行環境。 我懷疑首先解析捆綁文件,然后自定義第二個,覆蓋捆綁文件中存在的任何屬性。
在我的例子中,捆綁的application.properties
具有accessKey和secretKey占位符(具有虛假值),只要他想在EC2環境之外進行一些測試,就會由開發人員填寫。 這使得accessKey不為null,因此排除了實例配置文件路徑。 我剛從jar中刪除了application.properties文件,解決了這個問題。
cloud:
aws:
credentials:
accessKey:
secretKey:
instanceProfile: true
useDefaultAwsCredentialsChain: true
如果您使用最新的(2.XX)Spring AWS Cloud,這將成功。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.