Apache storm 风暴SQS消息未得到确认

Apache storm 风暴SQS消息未得到确认,apache-storm,amazon-sqs,Apache Storm,Amazon Sqs,我有一个拓扑结构,1个喷口读取2个SQS队列和5个螺栓。处理后,当我尝试从第二个螺栓确认时,它没有得到确认 我在可靠模式下运行它,并试图在最后一个螺栓中确认。我收到这条消息,就好像这些消息正在被确认一样。但它不会从队列中删除,也不会调用覆盖的ack()方法。它似乎调用了backtype.storm.task.OutputCollector中的默认ack方法,而不是my spout中的重写方法 8240 [Thread-24-conversionBolt] INFO backtype.storm

我有一个拓扑结构,1个喷口读取2个SQS队列和5个螺栓。处理后,当我尝试从第二个螺栓确认时,它没有得到确认

我在可靠模式下运行它,并试图在最后一个螺栓中确认。我收到这条消息,就好像这些消息正在被确认一样。但它不会从队列中删除,也不会调用覆盖的
ack()
方法。它似乎调用了
backtype.storm.task.OutputCollector
中的默认ack方法,而不是my spout中的重写方法

8240 [Thread-24-conversionBolt] INFO  backtype.storm.daemon.task - Emitting: conversionBolt__ack_ack [-7578372739434961741 -8189877254603774958]
我已将消息ID锚定到SQS队列喷口中的元组,并发送到第一个螺栓

collector.emit(getStreamId(message), new Values(jsonObj.toString()), message.getReceiptHandle());
我在队列
spout中重写了ack()和fail()方法。默认可见性超时已设置为30秒

“我的拓扑”中的代码段:

TopologyBuilder=new TopologyBuilder();
建筑商设置排水口(“第一个排水口”,
新的SqsQueueSpout(StormConfigurations.getQueueURL()
+StormConfigurations.getFirstQueueName(),true),
getawsquespoutthreads());
建筑商设置排水口(“第二个排水口”,
新的SqsQueueSpout(StormConfigurations.getQueueURL()
+StormConfiguration.getSecondQueueName(),
true),StormConfigurations.getawsquespoutthreads();
builder.setBolt(“transformerBolt”,新transformerBolt(),
StormConfigurations.getTranformerBoltThreads())
.shuffleGrouping(“firstQueueSpout”)
.shuffleGrouping(“第二排队口”);
builder.setBolt(“转换螺栓”,新转换螺栓(),
StormConfigurations.getTranformerBoltThreads())
.随机组合(“变压器螺栓”);
//根据数据包类型将其发送到相应的螺栓
builder.setBolt(“调度螺栓”,新调度螺栓(),
StormConfigurations.getDispatcherBoltThreads())
.重组(“转换螺栓”);
来自SQSqueueSpoot(扩展BaseRichSpoot)的代码片段:

@覆盖
public void nextTuple()
{
if(queue.isEmpty()){
ReceiveMessageResult ReceiveMessageResult=sqs.receiveMessage(
新的ReceiveMessageRequest(queueUrl).withMaxNumberOfMessages(10));
queue.addAll(receiveMessageResult.getMessages());
}       
Message=queue.poll();
如果(消息!=null)
{
尝试
{
JSONParser=新的JSONParser();
JSONObject jsonObj=(JSONObject)parser.parse(message.getBody());
//ack(message.getReceiptHandle());
如果(可靠){
emit(getStreamId(message)、新值(jsonObj.toString()、message.getReceiptHandle());
}否则{
//立即删除它
sqs.deleteMessageAsync(新的DeleteMessageRequest(queueUrl,message.getReceiptHandle());
emit(getStreamId(message),新值(jsonObj.toString());
}
}
捕获(解析异常)
{
LOG.error(“sqqueuespout.nextTuple()中的sqqueuespoutsqlexception:”,e);
}
}否则{
//还是空的,去睡觉吧。
睡眠(睡眠时间);
}
}
公共字符串getStreamId(消息){
返回Utils.DEFAULT\u STREAM\u ID;
}
public int getSleepTime(){
返回睡眠时间;
}
公共无效设置睡眠时间(int睡眠时间)
{
this.sleepTime=睡眠时间;
}
@凌驾
公共无效确认(对象msgId){
System.out.println(“……在SqSqueueSpoot中的ack内…………”+msgId);
//仅在可靠模式下调用。
试一试{
deleteMessageAsync(新的DeleteMessageRequest(queueUrl,(字符串)msgId));
}catch(AmazonClientException ace){}
}
@凌驾
公共无效失败(对象msgId){
//仅在可靠模式下调用。
试一试{
sqs.changeMessageVisibilityAsync(
新的ChangeMessageVisibilityRequest(queueUrl,(字符串)msgId,0);
}catch(AmazonClientException ace){}
}
@凌驾
公众假期结束(){
sqs.shutdown();
((AmazonSQSAsyncClient)sqs).getExecutorService().shutdownNow();
}
公共无效申报输出字段(OutputFields申报器申报器){
declarer.declare(新字段(“消息”));
}
从我的第一个螺栓(扩展BaseRichBolt)上剪下的代码:

公共类TransformerBolt扩展了BaseRichBolt
{
私有静态最终长serialVersionUID=1L;
公共静态最终记录器LOG=LoggerFactory.getLogger(TransformerBolt.class);
专用输出采集器;
@凌驾
公共空间准备(地图风暴形态、地形上下文、,
输出采集器(采集器){
this.collector=收集器;
}
@凌驾
公共void执行(元组输入){
String eventStr=input.getString(0);
//这里有一些将json字符串转换为映射的代码
//映射数据映射,长packetId被发送到下一个螺栓
emit(输入,新值(dataMap,packetId));
} 
捕获(例外e){
warn(“将AWS SQS转换为HashMap:{}时出现异常”,e);
}    
}
@凌驾
公共无效申报输出字段(OutputFields申报器申报器){
declarer.declare(新字段(“dataMap”、“packetId”);
}
}
第二个螺栓的代码段:

公共类转换螺栓扩展了BaseRichBolt
{
私有静态最终长serialVersionUID=1L;
专用输出采集器;
@凌驾
公共空间准备(地图风暴形态、地形上下文、,
输出采集器列