【问题标题】:Distributed Cache Across Microservice Domains跨微服务域的分布式缓存
【发布时间】:2021-12-05 21:43:57
【问题描述】:

在与分布式缓存环境中的 @Cacheable 不同的微服务中管理 @CachePut 是一种反模式吗?

我正在开发 Spring Boot 微服务,这些微服务分为两个领域类别:数据摄取和 UI。摄取与 UI 服务分离,因此数据突发不会影响响应时间。一旦数据被摄取,我们会在 kafka 上将其扇出到用于存储的持久性服务和用于实时确定(例如用户通知)的会话服务。

为确保我能够跟上摄取率,我想在初始 REST 查找后将用户通知配置缓存在我的摄取管道中。但是,如果用户在 UI 中更新他们的配置(例如,增加/减少警告阈值、关闭警告、更改为摘要),我希望使用该更新刷新缓存。因为我将自动扩展这些服务以满足需求,所以我计划使用分布式缓存。

在分布式缓存配置中跨两个不同的微服务拆分 @CachePut 和 @Cacheable 是否构成反模式?通过 kafka 发送对象会是更好的选择吗?

我的直觉告诉我要避免像这样在微服务之间拆分缓存管理,因为我可以想象有人在一个服务中更改了缓存键而忘记在第二个服务中更改它们。另一方面,通过 kafka 将它们发送给会话服务中的消费者会看起来很丑陋,如下所示:

@CachePut(value = "config", key = "new SimpleKey(#config.userId, #config.applicationId)")
public UserApplicationConfig fakeSave(UserApplicationConfig config) {
  // not actually saving anything, just need somewhere to put my CachePut annotation
  return config;
}

【问题讨论】:

  • 为什么要将项目放入缓存中,如果您要扇出到 Kafka 队列,有什么特定的用例吗?
  • 摄取根据用户配置维护业务决策的会话状态。用户配置通过 REST 接口进行维护。我不想为每条摄取的消息执行 REST 调用。仅当用户/应用程序键不存在缓存值时才会调用 REST 接口。但是用户可以在会话中更改配置,我需要使用该值更新缓存。

标签: java spring-boot caching hazelcast spring-cache


【解决方案1】:

当然这是一种反模式,因为它打破了服务边界,尤其是数据隐藏。

更新用户数据时,您希望更新具有用户数据缓存版本的服务客户端。更好的设计会发送一个事件“用户数据更改”并让服务客户端订阅它。

使用分布式缓存,您可以引入可能的故障点、延迟和一致性配置选项,这并不简单。

【讨论】:

  • 这就是我所倾向的,使用 Hazelcast 的嵌入式分布式配置。就像您说的那样,保留了服务边界,还允许我仅在摄取会话正在进行时才对缓存对象进行更改(用户可以在不在会话中时简单地使用设置)并为未来的开发人员简化维护和调试。
【解决方案2】:

@CachePut 总是让方法执行。如果您希望使用方法执行的结果更新缓存,则通常使用它。 示例:当您要更新已缓存的陈旧数据时,而不是完全耗尽缓存。

@Cacheable 对于给定的缓存键只会执行一次,后续请求不会执行该方法,直到缓存过期或被刷新。

这取决于您的设计决定。它不是反模式。 Spring Data JPA 还使用带有 Annotations 的接口存储库,这并不意味着,甚至不需要创建“Fake”接口。

它是一种捕获注解的方式(注解处理)。

【讨论】:

  • 对。但我有两个服务:用户应用程序配置服务 (REST) 和会话服务(流式摄取管道)。是不是分布式缓存反模式在第一个服务中维护CachePut来更新第二个服务中的Cacheable值?
猜你喜欢
  • 1970-01-01
  • 2017-07-12
  • 2019-01-02
  • 1970-01-01
  • 2015-07-22
  • 2019-04-14
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
相关资源
最近更新 更多