Chronicle Queue命名Tailer获取最新滚动周期文件却返回最早文件问题
Chronicle Queue命名ExcerptTailer续读最新周期问题解决
问题分析
你遇到的核心问题:
- 第一个循环结束后,命名Tailer的位置被持久化到队列末尾(最新周期的末尾);
- 重新创建同名Tailer后,
tailer.cycle()返回最新周期,但moveToCycle(tailer.cycle())不会改变当前位置(已处于目标周期); approximateExcerptsInCycle()方法在Tailer处于周期末尾时,会回退到队列中最早存在的周期,导致后续读取错误。
修正方案
- 直接通过队列获取最新周期号,而非依赖Tailer的当前周期;
- 先将Tailer移动到最新周期的起始位置,再获取该周期的记录数;
- 避免在无数据时过早关闭Tailer(若需实时监听,可改用阻塞或轮询等待逻辑)。
修正后的代码
public static void main(String[] args) { ChronicleQueue QUEUE = SingleChronicleQueueBuilder.single("./chronicle/roll") .rollCycle(RollCycles.MINUTELY) .build(); ExcerptTailer TAILER = QUEUE.createTailer("a"); // 读取所有已有数据,直到队列末尾 while (TAILER.readDocument(w -> w.read("packet").marshallable( m -> System.out.println(m.read("moldUdpHeader").text()) ))) { System.out.println("当前读取周期: " + TAILER.cycle()); } // 重新创建命名Tailer,从之前持久化的断点位置启动 ExcerptTailer tailer = QUEUE.createTailer("a"); // 获取队列的最新周期号 long latestCycle = QUEUE.lastCycle(); // 强制移动到最新周期的起始位置 tailer.moveToCycle(latestCycle); System.out.println("当前定位到周期: " + tailer.cycle()); // 获取最新周期的记录数(方法会确保Tailer处于周期起始位置) long excerpts = tailer.approximateExcerptsInCycle(latestCycle); System.out.println("最新周期记录数: " + excerpts); // 遍历最新周期的所有记录 for (int i = 0; i < excerpts; i++) { System.out.println("当前读取周期: " + tailer.cycle()); tailer.readDocument(w -> w.read("packet").marshallable( m -> System.out.println(m.read("moldUdpHeader").text()) )); } tailer.close(); QUEUE.close(); }
关键说明
QUEUE.lastCycle():直接获取队列中最新的滚动周期号,避免依赖Tailer的当前位置偏差;tailer.moveToCycle(latestCycle):强制将Tailer定位到指定周期的起始位置,确保后续读取从该周期开头启动;approximateExcerptsInCycle(latestCycle):Tailer已处于目标周期起始位置时,会正确返回该周期的记录数,不会回退到更早周期。
依赖版本
<!-- Chronicle Queue 依赖 --> <dependency> <groupId>net.openhft</groupId> <artifactId>chronicle-queue</artifactId> <version>5.24ea7</version> </dependency>
内容的提问来源于stack exchange,提问作者pebble unit
相关产品推荐
相关产品推荐

