• 阿里云MNS消息`The receipt handle you provided has expired`


    项目中做一个ES打标功能,当促销活动变动时(启用、禁用、审核通过等),通过阿里云MNS队列推送消息,消费方监听消息进行业务处理。
    因为活动分多钟类型,有的类型门店、商品数量较多,消费处理需要一定时间,基础组件封装了消息消费,在消费完成后会调用阿里云MNS的SDK删除消息,如下:

    this.mnsClient.getQueueRef(this.consumerQueue).deleteMessage(message.getReceiptHandle());
    

    日志中发现异常信息:

    com.aliyun.mns.common.ServiceException: The receipt handle you provided has expired.
            at com.aliyun.mns.common.http.ExceptionResultParser.parse(ExceptionResultParser.java:42)
            at com.aliyun.mns.common.http.ExceptionResultParser.parse(ExceptionResultParser.java:12)
            at com.aliyun.mns.common.http.HttpCallback.handleResult(HttpCallback.java:155)
            at com.aliyun.mns.common.http.HttpCallback.buildResponseMessage(HttpCallback.java:128)
            at com.aliyun.mns.common.http.HttpCallback.completed(HttpCallback.java:88)
            at com.aliyun.mns.common.http.HttpCallback.completed(HttpCallback.java:22)
            at shaded.org.apache.http.concurrent.BasicFuture.completed(BasicFuture.java:119)
            at shaded.org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseCompleted(DefaultClientExchangeHandlerImpl.java:177)
            at shaded.org.apache.http.nio.protocol.HttpAsyncRequestExecutor.processResponse(HttpAsyncRequestExecutor.java:412)
            at shaded.org.apache.http.nio.protocol.HttpAsyncRequestExecutor.inputReady(HttpAsyncRequestExecutor.java:305)
            at shaded.org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:267)
            at shaded.org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81)
            at shaded.org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39)
            at shaded.org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:116)
            at shaded.org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:164)
            at shaded.org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:339)
            at shaded.org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:317)
    

    同时观察日志发现消息有被重复消费。
    查询官方文档:

    队列消息消费有个到期时间VisibilityTimeout,默认为30s。
    消息被消费端接收,消息状态从active变为inactive,超过VisibilityTimeout后,又变为active,然后消息可继续被其他消费端消费,并且消息的ReceiptHandle失效。
    因为消息处理慢超过了30s,因此项目中消费方又接收到了消息,消息的ReceiptHandle失效因此删除消息报错。

    解决方法:

    • 方法1:
      监听者拿到消息,在记录日志后处理消息前删除消息
    • 方法2:
      在阿里云后台创建队列的界面中,修改VisibilityTimeout时间,默认30s调大点,比如改为600s;
      同时根据消息id,在消息日志表里判断是否已处理过该消息,避免重复消费
  • 相关阅读:
    MySQL的操作
    Centos7下MySQL的安装
    一键安装Tomcat
    Hola!
    eval
    初级版笔记(修改中)
    decode前先encode(python)
    不能scanf字符串
    第一次做题的一些问题c++
    DSY3163*Eden的新背包问题
  • 原文地址:https://www.cnblogs.com/cdfive2018/p/13895032.html
Copyright © 2020-2023  润新知