我的团队正在尝试为Amazon SQS Java Extended Client Library实现一个异步侦听器,因为正如this和this链接所指出的那样,很快就不会有任何支持。
最初的问题是我们需要通过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映射器。