DefaultMQProducer.send(message, timeout)的消息发送状态sendResult.getSendStatus()不可用性
来源:互联网 发布:手机usb共享网络打不开 编辑:程序博客网 时间:2024/05/21 22:28
使用DefaultMQProducer.send(message,timeout);可以通过sendResult.getSendStatus()查看发送到RocketMQ的信息是否发送成功,在使用如下代码进行发送信息,并对信息发送是否确认成功,如果不成功进行重新发送时,出现bug:
public class MQProductor { private static final Logger logger = LoggerFactory.getLogger(MQProductor.class); private static DefaultMQProducer producer = null; private static MQProductor instance = null; private MQProductor(){} public static MQProductor getInstance(){ if(instance == null || producer == null){ synchronized (MQProductor.class){ if(instance == null){ instance = new MQProductor(); } if(producer == null){ initProducer(); } } } return instance; } private static void initProducer(){ /** * 一个应用创建一个Producer,由应用来维护此对象,可以设置为全局对象或者单例<br> * 注意:ProducerGroupName需要由应用来保证唯一<br> * ProducerGroup这个概念发送普通的消息时,作用不大,但是发送分布式事务消息时,比较关键, * 因为服务器会回查这个Group下的任意一个Producer */ String groupName = ConnServerConfig.getPropValue("MQ_PRODUCER_GROUP_NAME", "liveConnMPhone"); String addr = ConnServerConfig.getPropValue("MQ_NAMESERVER_ADDR"); String producerName = ConnServerConfig.getPropValue("MQ_PRODUCTER_NAME"); producer = new DefaultMQProducer(groupName); producer.setNamesrvAddr(addr); producer.setInstanceName(producerName); /** * Producer对象在使用之前必须要调用start初始化,初始化一次即可<br> * 注意:切记不可以在每次发送消息时,都调用start方法 */ try { producer.start(); } catch (MQClientException e) { logger.error("初始化RocketMQ异常,将推出程序" + e.getMessage(), e); SystemResourcesClean.closeAllResources(); System.exit(-1); } } public static void closeProducer(){ if(producer != null){ producer.shutdown(); producer = null; } } public boolean sendMsg(@NotNull String topic, @NotNull String tags, @NotNull String keys, @NotNull String msg) throws UnsupportedEncodingException { int count = 0; boolean status = false; long timeout = Long.parseLong(ConnServerConfig.getPropValue("MQ_SENT_TIMEOUT", "4000")); Message message = new Message(topic, tags, keys, msg.getBytes("UTF-8")); logger.debug("count:" + count); while(count <= 3){ logger.debug("进入循环"); try { SendResult sendResult = producer.send(message, timeout); logger.debug("发送MQ状态:" + sendResult.getSendStatus()); if(sendResult.getSendStatus() == SendStatus.SEND_OK){ status = true; break; } } catch (InterruptedException e) { logger.error("MQ发送消息:" + count + "次失败,请查看一次原因" + e.getMessage(), e); } catch (RemotingException e) { logger.error("MQ发送消息:" + count + "次失败,请查看一次原因" + e.getMessage(), e); } catch (MQClientException e) { logger.error("MQ发送消息:" + count + "次失败,请查看一次原因" + e.getMessage(), e); } catch (MQBrokerException e) { logger.error("MQ发送消息:" + count + "次失败,请查看一次原因" + e.getMessage(), e); }finally { count++; } } return status; }}
背景,connserver负责解释请求,将不同类型的请求数据发送到RocketMQ的不同队列中,roomserver负责从RocketMQ中获取数据,并根据数据类型进行对应的处理,将处理结果通过RPC回调给connserver。
这时会出现一个问题,在roomserver已经处理完connserver发送到RocketMQ中的数据并且通过RPC回调到connserver中,这时sendResult.getSendStatus()还未返回发送消息是否成功的状态,明明消息已经发送成功并且已经被roomserver消费了,状态还未返回,表明这个方法的不可用,状态返回严重滞后。
解决方案:sendResult.getSendStatus()这个方法返回的结果只用于判定是否需要对消息进行重新发送,不用其返回的结果作为逻辑流程的处理依据,消息发送并处理成功自然会经过RPC回调,消息未发送成功roomserver没有接受到消息也不会触发RPC回调。
0 0
- DefaultMQProducer.send(message, timeout)的消息发送状态sendResult.getSendStatus()不可用性
- LibRTMP源代码分析7:发送消息(Send Message)
- Objective-C编程之——发送消息Send Message
- erlang 怎么和 c/c++ 发送消息,交互,(send ,receive msg message)
- 消息发送(Message Routing)
- MESSAGE消息发送失败
- android发送模拟按键消息,出现死锁,timeout的解决方法
- android发送模拟按键消息,出现死锁,timeout的解决方法
- Windows Message 消息队列,消息循环,Post消息,Send消息
- 为什么python的yield第一次不能用send发送数据?
- 邮箱的代理发送Send as权限不生效
- 利用MSMQ发送消息(对象)到NServiceBus终结点(不采用Send-Only方式)
- 发送消息(Sending a Message)
- send的发送问题
- handle.sendEmptyMessageDelayed(message ,TIME_OUT) 发送延迟处理的消息
- PB发送和接收消息send SendMessage
- 构造SUN Message Queue集群,提供高可用性消息服务
- 构造SUN Message Queue集群,提供高可用性消息服务
- Hdu 2243 考研路茫茫——单词情结
- JSP中调用ajax执行post请求不成功
- android activty 伪弹框学习笔记
- 基于GIS的定位监控系统开发教程-关于本教程
- 通过非聚集索引让select count(*) from 的查询速度提高几十倍、甚至千倍
- DefaultMQProducer.send(message, timeout)的消息发送状态sendResult.getSendStatus()不可用性
- 全栈必备Linux 基础
- mybatis教程
- 跳转到应用本身的详情页,清除本应用缓存
- 有哪些老鸟程序员知道而新手不知道的小技巧?
- JS匿名自执行函数
- java泛型使用demo
- 并发容器之CopyOnWriteArrayList
- 一维非稳态导热通用程序(不变部分)