简体   繁体   English

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

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

I have a Java based web app hosted on AWS.我有一个基于 Java 的 Web 应用程序托管在 AWS 上。 It is read-mostly so it makes a lot of sense to cache objects retrieved from the database for performance.它以读取为主,因此缓存从数据库中检索的对象以提高性能非常有意义。

When I do update an object, I would like to be able to broadcast to all the servers that the object was saved and it should be invalidated from all local caches.当我更新一个对象时,我希望能够向所有服务器广播该对象已保存并且应该从所有本地缓存中使其无效。

The does not need to be real time.不需要是实时的。 Stale objects are annoying and need to be flushed within about 20 seconds.陈旧的对象很烦人,需要在大约 20 秒内刷新。 Users notice if they stick around for minutes.用户会注意到他们是否停留了几分钟。 Cache invalidation does not have to happen the millisecond that objects get saved.缓存失效不必在对象保存的毫秒内发生。


What I've thought about我想到了什么

  • I've looked into broadcast technologies just as jGroups, but jGroups isn't supported on AWS.我研究过像 jGroups 一样的广播技术,但 AWS 不支持 jGroups。
  • I don't think that Amazon's SQS messaging service can be made into a broadcast service.我不认为亚马逊的 SQS 消息服务可以做成广播服务。
  • I'm considering using the database for this purpose: I'd write events to a database table and have each server poll this table every few seconds to get a new list items.我正在考虑为此目的使用数据库:我将事件写入数据库表并让每个服务器每隔几秒轮询一次该表以获取新的列表项。

Two options come to mind. 我想到了两种选择。 The first is to use Amazon SNS , which can use SQS as a delivery backend. 第一种是使用Amazon SNS ,它可以使用SQS作为交付后端。 This might be overkill, though, since it's designed as a frontend to lots of delivery types, including e-mail and SMS. 然而,这可能是过度的,因为它被设计为许多交付类型的前端,包括电子邮件和SMS。

The approach I'd try is something along the lines of Comet-style push notifications. 我尝试的方法与Comet风格的推送通知类似。 Have each machine with a cache open a long-lived TCP connection to the server who's responsible for handling updates, and send a compact "invalidate" message from that server to everyone who's listening. 让每台带有缓存的计算机打开与负责处理更新的服务器的长期TCP连接,并将该服务器的紧凑“无效”消息发送给正在收听的每个人。 As a special-purpose protocol, this could be done with minimal overhead, perhaps just by sending the object ID (and class if necessary). 作为一种特殊用途的协议,这可以通过最小的开销来完成,也许只需要发送对象ID(如果需要的话,可以发送类)。

Redis is handy solution for broadcasting a message to all subscribers on a topic. Redis是一个方便的解决方案,用于向所有订阅者广播一个主题的消息。 It is convenient because it can be used as a docker container for rapid prototyping, but is also offered by AWS as a managed service for multi-node clusters.它很方便,因为它可以用作快速原型制作的 docker 容器,但也由 AWS 作为多节点集群的托管服务提供。

Setting up a ReactiveRedisOperations bean:设置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);
}

Subscribing on a topic:订阅主题:

@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);
}

Publishing a message on a topic:发布关于某个主题的消息:

@Autowired
private ReactiveRedisOperations<String, Notification> redisTemplate;

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

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

RedisInsight is a GUI that can be used for interacting with redis. RedisInsight是一个可用于与 Redis 交互的 GUI。

Here is a complete sample implementation using spring-data-redis. 是使用 spring-data-redis 的完整示例实现。

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

相关问题 我怎样才能得到谷歌云cdn无效的缓存结果 - How can I get google cloud cdn Invalidate cache result Firebase 托管 Flutter Web App 未清除首次部署的缓存 - Firebase Hosting Flutter Web App not clearing Cache of first deploy 如何使我的快速服务器的 Google Cloud CDN 缓存失效? - How can I invalidate Google Cloud CDN cache from my express server? 如何检查我的 Flutter Web 应用程序当前是否正在运行? - How to check if my Flutter Web app is currently running? 当 twilio function 在后台运行时,如何继续使用我的 web 应用程序? - How to continue using my web app as twilio function is running in the background? AWS:为在多个实例上运行的多个工作进程广播通知 - AWS: Broadcast notifications for multiple worker processes running on multiple instances 如何在运行测试之前自动清理 Visual Code 中的 go 缓存? - How do I automatically clean the go cache in Visual Code before running tests? 如何在 Web 应用程序的 FireStore 中传递 Auth 令牌 - How to pass Auth token in FireStore in Web app 如何从 web 向应用程序发送 FCM 通知 - How to send FCM notification to app from web 缓存不适用于所有跑步者和分支 - cache is not working on all runners and branches
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM