跨微服务域的分布式缓存

Distributed Cache Across Microservice Domains

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

我正在研究 spring 启动微服务,这些微服务分为两个领域类别:数据摄取和 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;
}

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

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

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

这是一种捕获注解(Annotation Processing)的方法。

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

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

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