使用Spring JmsListener的扩展客户端库的Amazon SQS异步监听器

时间:2018-12-12 21:09:40

标签: java asynchronous listener amazon-sqs spring-jms

我的团队正在尝试为Amazon SQS Java Extended Client Library实现一个异步侦听器,因为正如thisthis链接所指出的那样,很快就不会有任何支持。

最初的问题是我们需要通过SQS发送非常大的有效负载。因此,为了解决此问题,我们使用了上述的Amazon SQS Java扩展客户端库功能。它会自动将较大的有效负载上传到S3,随后再将它们作为消息检索,而用户不必担心如何从S3检索它们。可悲的是,这只能同步进行。

因此,要使其异步工作,我们使用JmsListener提出了以下代码。它起作用了,我们获得了String格式的序列化对象。

  

AWS / SQS Bean

import com.amazon.sqs.javamessaging.AmazonSQSExtendedClient;
import com.amazon.sqs.javamessaging.ExtendedClientConfiguration;
import com.amazon.sqs.javamessaging.ProviderConfiguration;
import com.amazon.sqs.javamessaging.SQSConnectionFactory;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;

@Configuration
public class AWSConfig {

    @Bean
    public AWSCredentialsProvider awsCredentialsProvider() {
        return new DefaultAWSCredentialsProviderChain();
    }

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
        final DefaultJmsListenerContainerFactory jmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
        jmsListenerContainerFactory.setConnectionFactory(connectionFactory);

        return jmsListenerContainerFactory;
    }

    @Bean
    public ConnectionFactory connectionFactory(final AmazonS3Client amazonS3Client, final AmazonSQSAsync amazonSqs) {
        final ExtendedClientConfiguration extendedClientConfig = new ExtendedClientConfiguration()
                .withLargePayloadSupportEnabled(amazonS3Client, "my-bucket-name");

        final ProviderConfiguration providerConfiguration = new ProviderConfiguration();
        providerConfiguration.setNumberOfMessagesToPrefetch(10);

        final SQSConnectionFactory sqsConnectionFactory = new SQSConnectionFactory(providerConfiguration,
                new AmazonSQSExtendedClient(amazonSqs, extendedClientConfig));

        return sqsConnectionFactory
    }
}
  

使用@JmsListener批注的侦听器:

@Component
public class QueueListener {

    ...

    @JmsListener(destination = "my-queue-name", containerFactory = "jmsListenerContainerFactory")
    public void consumeMessage(String queueMessage) {
        System.out.println(queueMessage);
    }
}

这里的问题是尽管有效,但是从S3读取的大消息却以String的形式出现。我们会真的真的真的想把消息自动解析为一个特定的对象(例如@SqsListener已经允许我们不必自己解析字符串),就像这样:

@JmsListener(destination = "my-queue-name", containerFactory = "jmsListenerContainerFactory")
public void consumeMessage(SomeObject queueMessage) ...

已经有一个similar question,但是答案的链接已失效,该描述对我们没有任何帮助。 this JMS messaging guide不能与SQS扩展库配合使用。为了使事情变得更困难,将转换器设置为org.springframework.jms.support.converter时,我们只能使用jmsListenerContainerFactory类,因此我们不能使用AWS使用的相同Jackson映射器。

0 个答案:

没有答案