7.producer
来源:互联网 发布:网页电子书制作软件 编辑:程序博客网 时间:2024/05/16 07:57
- 消息生产者,消息的种类:
普通消息
import com.alibaba.rocketmq.client.exception.MQClientException;import com.alibaba.rocketmq.client.producer.DefaultMQProducer;import com.alibaba.rocketmq.client.producer.SendResult;import com.alibaba.rocketmq.common.message.Message;public class ProducerTest {//nameserver地址private String namesrvAddr = "127.0.0.1:9876";//producer实例private DefaultMQProducer producer;public ProducerTest(String group) throws MQClientException {//初始化producer并启动producer = new DefaultMQProducer(group); producer.setNamesrvAddr(namesrvAddr); producer.start();}/** * 发送普通消息 * @param topic * @param msg */public void send(String topic, Object msg) {byte[] bytes = null;//convert msg to byteSendResult sendResult = null;try {sendResult = producer.send(new Message(topic, bytes));//发送消息成功,但是需要检测状态switch(sendResult.getSendStatus()) {case SEND_OK:break;case FLUSH_DISK_TIMEOUT://刷盘超时,服务器宕机消息可能丢失break;case FLUSH_SLAVE_TIMEOUT://同步到slave超时,Master宕机消息可能丢失break;case SLAVE_NOT_AVAILABLE://slave此时不可用break;}} catch (Exception e) {e.printStackTrace();//发送异常,记录发送的结果,业务方需要判断是否重新发送该消息System.out.println(sendResult);}}}
延时消息
msg.setDelayTimeLevel();
顺序消息
/** * 发送有序消息 * * @param msg 消息数据 * @param selector 队列选择器,发送时会回调 * @param order 回调队列选择器时,此参数会传入队列选择方法,提供配需规则 * @return 发送结果 */public Result<SendResult> send(Message msg, MessageQueueSelector selector, Object arg) class IDHashMessageQueueSelector implements MessageQueueSelector{ public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) { int id = Integer.parseInt(arg.toString()); int size = mqs.size(); int index = id%size; return mqs.get(index); }}
- 普通消息
- 默认发送超时时间为3秒
- 默认发送的数据传输方式为同步,即等待数据的返回
- 默认消息发送失败重试次数为3次
- 在3+1秒内,重试3次,如果还不成功将会抛出异常,但是因为一次发送的超时时间为3秒,如果超时可能只能重试2次
- 发送的流程如下:
rocketmq会存储一个topic+brokername+queueid的列表,举个具体的例子,如下:
那么这个列表是topic-a+broker-a+queue-0,topic-a+broker-a+queue-1,topic-a+broker-b+queue-0,topic-a+broker-b+queue-1
发送时会轮询这个列表(即使并发请求),选择一个broker进行发送。
如果第一次发送失败,会按顺序选择选择下一个非失败的broker,例如:
第一次发送选择的是:topic-a+broker-a+queue-0,如果失败了,那么第二次发送选的将是:topic-a+broker-b+queue-0 - 上面的列表默认每30秒更新一次
- 高可用:
- 各个producer直接无通信
- producer发送失败会按顺序选择下一个broker进行重试
- 最终还是存在发送失败的情况,需要调用者处理
- 延时消息
- 延时消息需要延时消费,比如通信软件中的通知,离线状态是不能收到的,上线后发送通知。
- 延时消息的实现:
- 高可用
- ScheduleMessageService读取消息后,再次保存,出错则保留当前offset,等待下一次任务执行
- offset会每隔10s定时持久化到硬盘
- broker重启会从持久化的数据中加载offset
- slave同样会和master一样,构建延时队列,并定时解析到commitLog中
- messageDelayLevel 定时消息级别,默认为1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h分别对应1~18级
- 顺序消息
- 这里的顺序,主要是指局部顺序,即生产者通过将某一类消息发送至同一个队列来实现
例如:某个微信用户发了一条消息(A),然后撤回(B)
如何保持顺序:- 对于业务端来说,这两个消息需要顺序发送,即A的消息发送成功,才能发送B
- 对于生产者来说,只要是单线程的,将A,B发往同一个队列即可保证顺序
- 如何将不同的消息发往同一个队列呢?通过id取模定位:
此时需要这两个消息有共同的元素,比如uid,在发送消息时可以通过uid%queueNum来获取发往那个queue,即同一个uid的消息都发往同一个queue
- 普通顺序消息
- 正常情况下,保证消息的顺序性
- 异常情况下,例如broker宕机或重启,那么由于队列总数发生变化,id取模定位后队列发生变化(定时从nameserver更新topic路由),会产生短暂的消息顺序不一致,如下图:
假设broker-c宕机,那么queue-2不可用,那么100的会发往queue-0,由于queue-1此时也有100的消息,故不能做到顺序消费。
另外,101会发往queue-1,而此时broker-c如果起来了,也不能做到顺序消费。
- 严格顺序消息
- 无论正常异常情况,都需要保证消息的顺序性
- 对于rocketmq来说,严格顺序消息是如何实现的呢,如下图:
这里,跟普通顺序消息唯一不一样的地方就是多了一个topic的kv配置,即topic的路由信息是死的,即使某个broker挂了,路由信息也不变
这样就能保证发往其他的queue的消息顺序不变,但是发往挂了的broker的消息会失败,此时需要客户端来处理。
- 这里的顺序,主要是指局部顺序,即生产者通过将某一类消息发送至同一个队列来实现
- nameserver挂了的影响
- 由于producer会从nameserver列表中顺序选一个进行连接,并定时查询topic的路由信息,如果正在连接的nameserver挂了,会选择下一个nameserver进行连接
所以nameserver挂了并不会影响producer
- 由于producer会从nameserver列表中顺序选一个进行连接,并定时查询topic的路由信息,如果正在连接的nameserver挂了,会选择下一个nameserver进行连接
- 关于消息重复
- 由于发送消息时会发送失败,失败的情况有多种:
- 网络异常
- 消息数据问题
- broker挂了
- 超时
- 数据写入问题等等
- 由于各种复杂的情况会导致消息发送失败,此时需要业务端根据自身需要再次发送该消息
- 所以有可能会存在同一条消息被发送了两次,但是消息的msgid是不同的
- 由于发送消息时会发送失败,失败的情况有多种:
0 0
- 7.producer
- Producer
- producer consumer
- producer & consumer
- Producer Example
- Kafka Producer
- rocketmq Producer
- kafka producer
- kafka--producer
- The Producer-Consumer Problem
- compile producer-consumer
- ProtoThreads - Producer&Consumer
- ACE_Task Consumer-Producer
- Producer-consumer problem
- Producer Flow Control
- Producer Consumer 模式
- Producer-Consumer Pattern
- 多线程producer&customer
- tomcat设置直接通过域名访问项目(不需要接 /项目名)
- VS2010 LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 的解决方法
- IDEAL Ultimate 的SVN导入
- 根据Url 获取图片尺寸 iOS
- opencv 距离变换的GPU并行化计算
- 7.producer
- 集群的简单理解
- c++枚举和搜索注册表
- UICollectionViewLayout
- Android开发之解决APP启动白屏或者黑屏闪现的问题
- LeetCode----17. Letter Combinations of a Phone Number(遍历树+多重循环)
- java实现文件复制
- session防止表单重复提交
- Android launcher相关的一些知识