我正在使用AWS SDK for Java,而我正在使用缓冲异步sqs客户端来批量请求,以便降低成本。
当我的应用程序关闭时,我想确保缓冲区中没有消息等待,但我在客户端上看不到.flush()
方法。
调用时AmazonSQSBufferedAsyncClient.shutdown()
是否会刷新我的消息?我查看了source code,目前还不清楚。该方法会在shutdown()
上调用QueueBuffer
,但在QueueBuffer.shutdown()
内面会显示
public void shutdown() {
//send buffer does not require shutdown, only
//shut down receive buffer
receiveBuffer.shutdown();
}
此外,.shutdown()
的文档说:
关闭此客户端对象,释放可能的任何资源 保持开放。 这是一种可选方法,不需要调用方 称之为,但如果他们想明确释放任何开放的话 资源。客户端关闭后,不应该使用它 提出更多要求。
对于此应用程序,我需要确保在缓冲时不会丢失任何消息。我是否需要使用普通AmazonSQSClient
而不是缓冲/异步来手动处理?
答案 0 :(得分:2)
With 1.11.37 version of the SDK, there is a configuration parameter just for this purpose in QueueBufferConfig
.
AmazonSQSBufferedAsyncClient bufClient =
new AmazonSQSBufferedAsyncClient(
realAsyncClient,
new QueueBufferConfig( )
.withFlushOnShutdown(true)
);
答案 1 :(得分:0)
有一种方法可以显式调用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
}
我想这样的东西应该有效。让我知道!