繁体   English   中英

如何将缓存无效消息广播到所有运行 Web 应用程序的服务器?

[英]How to broadcast cache invalidate messages to all servers running a web app?

我有一个基于 Java 的 Web 应用程序托管在 AWS 上。 它以读取为主,因此缓存从数据库中检索的对象以提高性能非常有意义。

当我更新一个对象时,我希望能够向所有服务器广播该对象已保存并且应该从所有本地缓存中使其无效。

不需要是实时的。 陈旧的对象很烦人,需要在大约 20 秒内刷新。 用户会注意到他们是否停留了几分钟。 缓存失效不必在对象保存的毫秒内发生。


我想到了什么

  • 我研究过像 jGroups 一样的广播技术,但 AWS 不支持 jGroups。
  • 我不认为亚马逊的 SQS 消息服务可以做成广播服务。
  • 我正在考虑为此目的使用数据库:我将事件写入数据库表并让每个服务器每隔几秒轮询一次该表以获取新的列表项。

我想到了两种选择。 第一种是使用Amazon SNS ,它可以使用SQS作为交付后端。 然而,这可能是过度的,因为它被设计为许多交付类型的前端,包括电子邮件和SMS。

我尝试的方法与Comet风格的推送通知类似。 让每台带有缓存的计算机打开与负责处理更新的服务器的长期TCP连接,并将该服务器的紧凑“无效”消息发送给正在收听的每个人。 作为一种特殊用途的协议,这可以通过最小的开销来完成,也许只需要发送对象ID(如果需要的话,可以发送类)。

Redis是一个方便的解决方案,用于向所有订阅者广播一个主题的消息。 它很方便,因为它可以用作快速原型制作的 docker 容器,但也由 AWS 作为多节点集群的托管服务提供。

设置ReactiveRedisOperations bean:

@Bean
public ReactiveRedisOperations<String, Notification> notificationTemplate(LettuceConnectionFactory lettuceConnectionFactory){
    RedisSerializer<Notification> valueSerializer = new Jackson2JsonRedisSerializer<>(Notification.class);
    RedisSerializationContext<String, Notification> serializationContext = RedisSerializationContext.<String, Notification>newSerializationContext(RedisSerializer.string())
            .value(valueSerializer)
            .build();
    return new ReactiveRedisTemplate<>(lettuceConnectionFactory, serializationContext);
}

订阅主题:

@Autowired
private ReactiveRedisOperations<String, Notification> reactiveRedisTemplate;

@Value("${example.topic}")
private String topic;

@PostConstruct
private void init() {
    this.reactiveRedisTemplate
            .listenTo(ChannelTopic.of(topic))
            .map(ReactiveSubscription.Message::getMessage)
            .subscribe(this::processNotification);
}

发布关于某个主题的消息:

@Autowired
private ReactiveRedisOperations<String, Notification> redisTemplate;

@Value("${example.topic}")
private String topic;

public void publish(Notification notification) {
    this.redisTemplate.convertAndSend(topic, notification).subscribe();
}

RedisInsight是一个可用于与 Redis 交互的 GUI。

是使用 spring-data-redis 的完整示例实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM