代码之家  ›  专栏  ›  技术社区  ›  Trace

将lagom的读/写端分离成单独的服务?

  •  0
  • Trace  · 技术社区  · 6 年前

    我已经看了一些演示,包括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临时将啁啾存储到磁盘上,一旦再次可用,读取端将对其进行处理),写入也将返回成功。

    将写端和读端分离成单独的服务,并在不同的端口上运行它们,难道不合乎逻辑吗?或者这种方法有共同的缺陷吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   ignasi35    6 年前

    写作时 read-side 在拉各姆,你有两个选择:

    • 内部服务读取端:使用akka持久性查询直接从写入端的日志中读取并构建一个读取端。获取新事件、跟踪偏移量(了解已经读取了哪些事件)和创建读取端表的操作发生在进程中,最相关的是,偏移量跟踪和用户表更新发生在事务提供中。 effectively-once 语义。服务内读取端的另一个优点是建模停留在门后,只要公共REST端点提供相同的API,就可以自由地重构表。
    • 服务间读取端:(又称远程读取端)替代方案意味着创建远程服务并将事件从源服务发布到代理中,以便远程服务可以使用它们。这有一些警告:(1)事件现在是公共的,因此公共API不容易重构,(2)发布不是事务性的,使用可能是 at-least-once (你通常想要的)或 at-most-once 因此,端到端的保证不再是 有效一次 ,(3)主题可以被其他服务访问(这还不错,只是一个额外的考虑),(4)写端和读端生活在不同的服务中,这有点不自然。

    有一个远程读取端的演示 online-auction-java 演示应用程序: search-service 是一个远程读取端,它使用来自多个主题的事件,将信息合并到单个ElasticSearch索引中。在这种情况下,使用远程读取端很有意义,因为:(a)我们正在使用特定的存储技术(弹性搜索),以及(b)我们正在合并来自两个不同上游服务的流。

    小精灵,

    推荐文章