纪事世界中的微服务–第2部分

在这一部分中,我们着眼于将组件变成服务。

第1部分中 ,我们研究了如何轻松创建和测试期望异步消息进入并产生异步消息的组件。 但是,我们如何将其转变为服务

将我们的组件变成服务。

我们的组件缺少的关键是运输 。 缺乏传输方式简化了测试,配置和调试,但是我们需要分发组件,为此,我们需要传输方式。

有多种可能的运输方式:

这是我们将在帖子中查看的编年史队列。

在单元测试中使用队列

编年史队列已保留,但是在单元测试中,您通常希望重新开始并随后删除队列。 您可以使用的成语如下:

创建一个临时队列

File queuePath = new File(OS.TARGET, "testName-" + System.nanoTime());
try {
    try (SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(queuePath).build()) {
        // use the queue
    }

} finally {
    IOTools.shallowDeleteDirWithFiles(queuePath);
}

这将创建一个存储在单个文件中的队列。 默认情况下,该文件每天滚动,并将当前日期包括在路径中。

写作活动

如果我们像以前一样重复测试,则可以使用侦听器,而不是使用模拟侦听器 ,该侦听器会将调用的每个方法写入队列:

将调用方法写入任一接口的队列

OrderIdeaListener orderManager = queue.createAppender()
                                      .methodWriter(OrderIdeaListener.class, MarketDataListener.class);

我们的组合器将写入此队列,就像我们的测试一样:

SidedPrice组合器

SidedMarketDataCombiner combiner = new SidedMarketDataCombiner((MarketDataListener) orderManager);

我们还可以重复入站事件。 将所有这些放在一起,我们得到:

try (SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(queuePath).build()) {
    OrderIdeaListener orderManager = queue.createAppender().methodWriter(OrderIdeaListener.class, MarketDataListener.class);
    SidedMarketDataCombiner combiner = new SidedMarketDataCombiner((MarketDataListener) orderManager);

    // events in
    orderManager.onOrderIdea(new OrderIdea("EURUSD", Side.Buy, 1.1180, 2e6)); // not expected to trigger

    combiner.onSidedPrice(new SidedPrice("EURUSD", 123456789000L, Side.Sell, 1.1172, 2e6));
    combiner.onSidedPrice(new SidedPrice("EURUSD", 123456789100L, Side.Buy, 1.1160, 2e6));

    combiner.onSidedPrice(new SidedPrice("EURUSD", 123456789100L, Side.Buy, 1.1167, 2e6));

    orderManager.onOrderIdea(new OrderIdea("EURUSD", Side.Buy, 1.1165, 1e6)); // expected to trigger
}

将所有事件写入队列后,就可以在测试中处理队列。 一个更现实的示例是在不同的线程,进程或不同的机器上运行这两个组件,但这只会使测试复杂化,并且如果传输能够发挥作用,结果应该是相同的。

阅读事件。

读取事件时,我们需要一个实现上述方法的组件和一个模拟侦听器,以确保触发正确的事件。

阅读所有事件并检查正确的输出

// what we expect to happen
OrderListener listener = createMock(OrderListener.class);
listener.onOrder(new Order("EURUSD", Side.Buy, 1.1167, 1_000_000));
replay(listener);

try (SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(queuePath).build()) {
    // build our scenario
    OrderManager orderManager = new OrderManager(listener); (1)
    MethodReader reader = queue.createTailer().methodReader(orderManager); (2)
    for (int i = 0; i < 5; i++)
        assertTrue(reader.readOne()); (3)

    assertFalse(reader.readOne()); (4)
    System.out.println(queue.dump()); (5)
}

verify(listener);
小费
我们要测试的组件
我们的队列读取器将调用方法 循环一次读取/处理一种方法。 我们没有更多消息 转储队列内容,以便我们可以看到输入内容。

最后,测试转储队列的原始内容。 这将读取队列使用的文件中存储的数据。 此转储仅对具有少量MB数据的较小队列有用。 如果您有几个GB,它将无法存储在字符串中。 您可以使用DumpQueueMain

dump()的输出

--- !!meta-data #binary
header: !SCQStore {
  wireType: !WireType BINARY,
  writePosition: 777,
  roll: !SCQSRoll {
    length: 86400000,
    format: yyyyMMdd,
    epoch: 0
    },
  indexing: !SCQSIndexing {
    indexCount: !int 8192,
    indexSpacing: 64,
    index2Index: 0,
    lastIndex: 0
    }
}
# position: 227
--- !!data #binary
onOrderIdea: {
  symbol: EURUSD,
  side: Buy,
  limitPrice: 1.118,
  quantity: 2000000.0
}
# position: 306
--- !!data #binary
onTopOfBookPrice: {
  symbol: EURUSD,
  timestamp: 123456789000,
  buyPrice: NaN,
  buyQuantity: 0,
  sellPrice: 1.1172,
  sellQuantity: 2000000.0
}
# position: 434
--- !!data #binary
onTopOfBookPrice: {
  symbol: EURUSD,
  timestamp: 123456789100,
  buyPrice: 1.116,
  buyQuantity: 2000000.0,
  sellPrice: 1.1172,
  sellQuantity: 2000000.0
}
# position: 566
--- !!data #binary
onTopOfBookPrice: {
  symbol: EURUSD,
  timestamp: 123456789100,
  buyPrice: 1.1167,
  buyQuantity: 2000000.0,
  sellPrice: 1.1172,
  sellQuantity: 2000000.0
}
# position: 698
--- !!data #binary
onOrderIdea: {
  symbol: EURUSD,
  side: Buy,
  limitPrice: 1.1165,
  quantity: 1000000.0
}
...
# 83885299 bytes remaining

要运行测试并在我的IDE中转储队列需要233毫秒。

结论

我们可以通过使用更多的队列来测试组件是否与队列独立或成链地运行。 更重要的是,我们可以在不使基础架构使调试过程复杂化的情况下测试我们的组件。 当我们的组件在没有运输工具的情况下工作时,我们可以证明它们在运输工具的作用相同。

在我们的下一部分

在第3部分中,我们将研究Queue的基准测试和性能分析 。 尽管Queue被设计为简单透明,但即使没有调整,它也被设计为比其他持久传输更快。

翻译自: https://www.javacodegeeks.com/2017/02/microservices-chronicle-world-part-2.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值