我已经看了几个演示,包括Chirper演示应用: https://github.com/lagom/lagom-java-sbt-chirper-example
添加啁啾并检索实时啁啾流将添加到同一服务中。这似乎是常见的做法:
public interface ChirpService extends Service {
ServiceCall<Chirp, NotUsed> addChirp(String userId);
ServiceCall<LiveChirpsRequest, Source<Chirp, ?>> getLiveChirps();
ServiceCall<HistoricalChirpsRequest, Source<Chirp, ?>> getHistoricalChirps();
@Override
default Descriptor descriptor() {
// @formatter:off
return named("chirpservice").withCalls(
pathCall("/api/chirps/live/:userId", this::addChirp),
namedCall("/api/chirps/live", this::getLiveChirps),
namedCall("/api/chirps/history", this::getHistoricalChirps)
).withAutoAcl(true);
// @formatter:on
}
}
我的问题围绕着这样的想法:您可以将addChirp
消息提交给消息代理(Kafka进程)的主题,目的是将读取与写入分离。也就是说,即使读取端(消费者)暂时不可用(即,啁啾由Kafka临时存储到磁盘,一旦再次可用,由读取端处理),写入将返回成功。
将写入端与读取端分离为单独的服务并将它们完全在不同的端口上运行是不合逻辑的?或者这种方法有共同的陷阱吗?
答案 0 :(得分:1)
在Lagom中撰写read-side
时,您有两种选择:
effectively-once
语义。服务内部读取方面的另一个优点是,只要公共REST端点提供相同的API,建模就会停留在门后,您可以自由地重构表。at-least-once
(你通常想要的)或at-most-once
所以端到端保证不再是effectively-once
,(3)其他服务可以访问该主题(这不是坏事,它只是一个额外的考虑),(4)写入端和读取端存在于不同的服务中,这有点不自然。在online-auction-java
演示应用程序中有一个远程读取端的演示:search-service
是一个远程读取端,它使用来自许多主题的事件,将信息整合到一个弹性搜索索引中。在这种情况下,使用远程读取方面很有意义,因为:(a)我们使用特定的存储技术(弹性搜索)和(b)我们合并来自两个不同的流上游服务。
HTH,