qunarcorp / qmq

QMQ是去哪儿网内部广泛使用的消息中间件,自2012年诞生以来在去哪儿网所有业务场景中广泛的应用,包括跟交易息息相关的订单场景; 也包括报价搜索等高吞吐量场景。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

请教问题

majiabaomajiabao opened this issue · comments

问题描述
你好,请教一个问题,看描述pullLog对应到consumerGroup每台机器拉取时生成的,那如果有一台机器拉取后,宕机了(没有ack),然后一直没起来,那其他机器还能拉取到这批消息吗?

环境配置

复现步骤
1.
2.
3.

实际输出结果

期望输出结果

commented

broker 上有后台线程专门处理这种情况,会把宕机的 consumer 拉取到的消息转移到重发队列里,然后这批消息会被其他消费者消费到。

好的,多谢,我再看一下

你好,请教一个问题
broker的messagelog为了性能,默认是异步刷盘?那理论上会存在丢失消息的风险是吗?

你好,请教一个问题
broker的messagelog为了性能,默认是异步刷盘?那理论上会存在丢失消息的风险是吗?

broker是异步落盘,不过主从同步是同步等待,只有slave收到并write成功后才会返回,依赖这种机制保证可靠性

嗯嗯,找到代码了,多谢

你好,请问一下qunar.tc.qmq.store.MessageStoreWrapper#findNewExistMessages,同一个topic,同一个consumerGroup下不同的机器,是会拉到相同数据的吗?看代码是这样的

commented

不会,每个拉取请求都是从 nextSequence 开始拉取,每次拉取都会更新 nextSequence,所以一个消费组下的每个消费者都会拉取到不同的消息。

嗯嗯,没表述清楚,是并发的时候,看nextSequence的更新,没有限制

commented

同一个消费组的拉取是不会并发处理的,所以 nextSequence 是不会并发更新的。

get,同一个消费组的拉取是不会并发处理的 ,这个是ActorSystem做的吗?看下来这个地方是同一个subject和consumerGroup是顺序跑的

commented

是的

好的,多谢

你好,请问一下qunar.tc.qmq.processor.SendMessageWorker#receive, 会有并发写入吗?那messagelog的偏移会乱吗?

commented

偏移不会乱的,写入的消息都会进入到 Receiver 的队列里顺序处理。

找了一下,是这个地方的单线程控制的吗?
this.sendMessageExecutorService = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("send-message-processor"));

commented

是的

好的,多谢

关于延迟消息,请教一下,schedule log 按照投递时间组织,每个小时一个。该log是回放message log后根据延时时间放置对应的log上,这是上面描述的两层hash wheel的第一层,位于磁盘上,文档上的描述,应该是说,每个延迟消息根据scheduleTime会append到指定时间的schedulelog中,是吗?我看replay的代码,一直没看到这段逻辑,感觉schedulelog没有区分时间和messagelog差不多,麻烦问一下schedulelog指定时间的这段逻辑是在哪个方法呢?

commented

public RecordResult<T> append(LogRecord record) {
long scheduleTime = record.getScheduleTime();
DelaySegment<T> segment = locateSegment(scheduleTime);
if (null == segment) {
segment = allocNewSegment(scheduleTime);
}
if (null == segment) {
return new NopeRecordResult(PutMessageStatus.CREATE_MAPPED_FILE_FAILED);
}
return retResult(segment.append(record, appender));
}

写入会走到这里。

哦哦,多谢,跟错子类了

请问一下,看代码有个地方不太确定,Slave每次启动时都是全量拉取Master的MessageLog和ActionLog,这样的话,Salve的启动耗时会有点久,Master也会有磁盘的抖动,会有增量拉取吗?

commented

不是全量的,每次 slave 都是从自己没有的那部分开始拉取。
参考

public SyncRequest getRequest() {
final long messageLogMaxOffset = storage.getMaxMessageOffset();
return new SyncRequest(SyncType.message.getCode(), messageLogMaxOffset, 0L);

嗯嗯,看到了,多谢

你好,关于clientId:NetworkUtils.getLocalHostname() + "@@" + defaultUniqueId(),想问一下,如果是在k8s中,每次启动后,是不是会生成一个新的,那这样之前的pullLog就找不到了

commented

是的,k8s 就相当于你做了扩容缩容,扩容了新机器,老机器全部回收了。

那这样的话,在发布的时候,有可能旧的还没处理完,然后被杀死了,这段消息是不是就丢失了呢?

commented

不会丢失,一个消费者没有 ack 的消息都会在这个消费者离线后自动重发给这个消费组里的其他消费者。

方便给一下这个功能的代码路径吗?是在watchdog里面吗?看qmq-server好像没找到这段逻辑

ok,多谢多谢