Java 如何强制AmazonSQSBufferedAsyncClient刷新消息?
我使用AWS SDK for Java,并使用缓冲异步sqs客户端来批处理请求,以降低成本 当我的应用程序关闭时,我希望确保缓冲区中没有消息等待,但在客户端上看不到Java 如何强制AmazonSQSBufferedAsyncClient刷新消息?,java,amazon-web-services,amazon-sqs,Java,Amazon Web Services,Amazon Sqs,我使用AWS SDK for Java,并使用缓冲异步sqs客户端来批处理请求,以降低成本 当我的应用程序关闭时,我希望确保缓冲区中没有消息等待,但在客户端上看不到.flush()方法。 调用AmazonSQSBufferedAsyncClient.shutdown()时是否刷新我的消息?我看了看照片,不清楚。该方法对它拥有的每个QueueBuffer调用shutdown(),但在QueueBuffer.shutdown()中它说 public void shutdown() { //sen
.flush()
方法。
调用AmazonSQSBufferedAsyncClient.shutdown()时是否刷新我的消息?我看了看照片,不清楚。该方法对它拥有的每个QueueBuffer
调用shutdown()
,但在QueueBuffer.shutdown()中它说
public void shutdown() {
//send buffer does not require shutdown, only
//shut down receive buffer
receiveBuffer.shutdown();
}
此外,.shutdown()
的文档说明:
关闭此客户端对象,释放所有可能需要的资源
保持开放这是一个可选方法,不需要调用方
称之为,但如果他们想明确释放任何打开的
资源。客户端关闭后,不应使用它来
再提出任何要求
对于这个应用程序,我需要确保在缓冲时不会丢失任何消息。我是否需要使用普通的AmazonSQSClient
而不是缓冲/异步客户端手动处理此问题?有一种方法可以显式调用flush,但它不可访问,实际上我在amazon代码中找不到对该方法的任何调用。好像少了什么东西
在异步客户端上调用shutdown时,它将执行以下代码:
public void shutdown() {
for( QueueBuffer buffer : buffers.values() ) {
buffer.shutdown();
}
realSQS.shutdown();
}
QueueBuffer#shutdown()如下所示:
/**
* Shuts down the queue buffer. Once this method has been called, the
* queue buffer is not operational and all subsequent calls to it may fail
* */
public void shutdown() {
//send buffer does not require shutdown, only
//shut down receive buffer
receiveBuffer.shutdown();
}
因此,他们似乎有意不调用sendBuffer.shutdown(),该方法将刷新缓冲区中尚未发送的所有消息
当您关闭SQS客户端并丢失消息时,您是否发现了一个案例?看起来他们已经意识到了这一点,这种情况不应该发生,但是如果你想确定你可以用反射调用这个方法,这真的很糟糕,但是它会满足你的需要
AmazonSQSBufferedAsyncClient asyncSqsClient = <your initialization code of the client>;
Field buffersField = ReflectionUtils.findField(AmazonSQSBufferedAsyncClient.class, "buffers");
ReflectionUtils.makeAccessible(buffersField);
LinkedHashMap<String, Object> buffers = (LinkedHashMap<String, Object>) ReflectionUtils.getField(buffersField, asyncSqsClient);
for (Object buffer : buffers.values()) {
Class<?> clazz = Class.forName("com.amazonaws.services.sqs.buffered.QueueBuffer");
SendQueueBuffer sendQueueBuffer = (SendQueueBuffer) ReflectionUtils.getField(ReflectionUtils.findField(clazz, "sendBuffer"), buffer);
sendQueueBuffer.flush();//finally
}
AmazonSQSBufferedAsyncClient AsyncSQSCClient=;
Field buffersField=ReflectionUtils.findField(AmazonSQSBufferedAsyncClient.class,“缓冲区”);
ReflectionUtils.makeAccessible(buffersField);
LinkedHashMap buffers=(LinkedHashMap)ReflectionUtils.getField(buffersField,asyncSqsClient);
for(对象缓冲区:buffers.values()){
Class clazz=Class.forName(“com.amazonaws.services.sqs.buffered.QueueBuffer”);
SendQueueBuffer SendQueueBuffer=(SendQueueBuffer)ReflectionUtils.getField(ReflectionUtils.findField(clazz,“sendBuffer”),buffer);
sendQueueBuffer.flush();//最后
}
我想这样应该行得通。让我知道 对于SDK的1.11.37版本,在QueueBufferConfig
中有一个用于此目的的配置参数
AmazonSQSBufferedAsyncClient bufClient =
new AmazonSQSBufferedAsyncClient(
realAsyncClient,
new QueueBufferConfig( )
.withFlushOnShutdown(true)
);
我发现了这一点,这似乎是同一个问题,目前还没有答案:我认为它会起作用,但我不建议任何人使用反射。当你开始走这条路时,会有很多问题。