从 Spring Boot 连接到 AWS SQS 时出错

Posted

技术标签:

【中文标题】从 Spring Boot 连接到 AWS SQS 时出错【英文标题】:Error while connecting to AWS SQS from spring boot 【发布时间】:2017-09-26 05:36:19 【问题描述】:

我正在尝试使用 spring cloud AWS 将 AWS SQS 集成到我的 springboot 应用程序中,但不断收到此错误(发布在下面),有人可以帮忙吗?

这是我的文件。

org.springframework.beans.factory.BeanCreationException: 错误 创建名称为“simpleMessageListenerContainer”的bean 类路径资源 [org/springframework/cloud/aws/messaging/config/annotation/SqsConfiguration.class]: 调用 init 方法失败;嵌套异常是 java.lang.NoSuchMethodError: com.amazonaws.http.ExecutionContext.setCredentials(Lcom/amazonaws/auth/AWSCredentials;)V

@Configuration
public class AWSConfig 
    @Value("$amazon.dynamodb.endpoint")
    private String amazonDynamoDBEndpoint;

    @Value("$amazon.aws.accesskey")
    private String amazonAWSAccessKey;

    @Value("$amazon.aws.secretkey")
    private String amazonAWSSecretKey;

    @Value("$amazon.sqs.endpoint")
    private String amazonSqsEndpoint;
    @Bean
    @Primary
    public AmazonSQSAsyncClient amazonSQSAsyncClient() 

        AmazonSQSAsyncClient amazonSQSAsyncClient = new AmazonSQSAsyncClient(amazonAWSCredentials());
        if (!StringUtils.isEmpty(amazonSqsEndpoint)) 
            amazonSQSAsyncClient.setEndpoint(amazonSqsEndpoint);
        

        return amazonSQSAsyncClient;

    

    @Bean
    public AWSCredentials amazonAWSCredentials() 
        return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
    

我可以使用 dynamodb,但无法连接到 SQS。 我在 application.properties 文件中给出了正确的访问密钥、秘密访问密钥和端点。

@Component
    @EnableSqs
    public class SQSDao 
        private static final Logger logger = LoggerFactory.getLogger(SQSDao.class);

        private  QueueMessagingTemplate queueMessagingTemplate;

        @Autowired
        public SQSDao(AmazonSQSAsync amazonSqs) 
            this.queueMessagingTemplate = new QueueMessagingTemplate(amazonSqs);
        

        public void send(String message) 
            System.out.println(queueMessagingTemplate.getDefaultDestination());
            queueMessagingTemplate.convertAndSend("test-queue",  MessageBuilder.withPayload(message).build());
        

        @SqsListener(value = "test-queue", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
        public void receive(String message)
        
            System.out.println("message: " + message);
        

    

【问题讨论】:

【参考方案1】:

我遇到了与描述相同的问题。我的解决方案要求为 Config 类实现一些额外的方法:

imports [...]

@Configuration
@RefreshScope
public class SpringCloudSQSConfig 

@Value("$cloud.aws.credentials.accessKeyId:default")
private String accessKeyId;

@Value("$cloud.aws.credentials.secretKey:default")
private String secretKey;

@Value("$cloud.aws.region.static:default")
private String region;

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Bean
public QueueMessagingTemplate queueMessagingTemplate() 
    return new QueueMessagingTemplate(amazonSQSAsync());


public AmazonSQSAsync amazonSQSAsync() 
    return AmazonSQSAsyncClientBuilder.standard().withRegion(Regions.US_EAST_2)
            .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKeyId, secretKey)))
            .build();


@Bean
public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory() 
    SimpleMessageListenerContainerFactory msgListenerContainerFactory = new SimpleMessageListenerContainerFactory();
    msgListenerContainerFactory.setAmazonSqs(amazonSQSAsync());
    return msgListenerContainerFactory;


@Bean
public QueueMessageHandler queueMessageHandler() 
    QueueMessageHandlerFactory queueMsgHandlerFactory = new QueueMessageHandlerFactory();
    queueMsgHandlerFactory.setAmazonSqs(amazonSQSAsync());
    QueueMessageHandler queueMessageHandler = queueMsgHandlerFactory.createQueueMessageHandler();
    List<HandlerMethodArgumentResolver> list = new ArrayList<>();
    HandlerMethodArgumentResolver resolver = new PayloadArgumentResolver(new MappingJackson2MessageConverter());
    list.add(resolver);
    queueMessageHandler.setArgumentResolvers(list);
    return queueMessageHandler;


对于实现的依赖项:

        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-aws</artifactId>
        <version>2.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-aws-messaging</artifactId>
        <version>2.2.1.RELEASE</version>
    </dependency>

并在属性文件中添加下一个属性:

spring.main.allow-bean-definition-overriding=true

【讨论】:

【参考方案2】:

我通过删除重复的依赖项解决了它:

aws-xray-recorder-sdk-aws-sdk aws-xray-recorder-sdk-aws-sdk-v2
aws-xray-recorder-sdk-aws-sdk-instrumentor aws-xray-recorder-sdk-aws-sdk-v2-instrumentor

之前:

<!-- AWS X-Ray -->
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-core</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-apache-http</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-v2</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-spring</artifactId>
</dependency>

之后:

<!-- AWS X-Ray -->
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-core</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-apache-http</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-v2</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-spring</artifactId>
</dependency>

【讨论】:

【参考方案3】:

我能够通过在本地测试期间将显示的最后一行添加到我的 application.yml 来解决此问题

spring:
  autoconfigure:
    exclude:
      - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration
      - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration

【讨论】:

【参考方案4】:

已修复,显然问题与 here 提到的依赖混合有关

【讨论】:

你能提供更多细节吗?我有同样的问题 请发布一个合法的答案

以上是关于从 Spring Boot 连接到 AWS SQS 时出错的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot、Spring Cloud AWS 和 AWS SQS 未从队列中读取

当我将 Spring Boot 应用程序部署到 AWS Elastic Beanstalk 并且无法从本地 Spring Boot 连接到 RDS 时出现 502 错误网关

AWS Elastic Beanstalk Worker 无法连接到 SQS

Spring Boot 连接到 AWS RDS MySQL - SSLHandshakeException:收到致命警报:unknown_ca

无法使用测试容器的 localstack 模块连接到 Aws SQS

如何将 AWS Elasticache Redis 集群连接到 Spring Boot 应用程序?