PubSub - How to add subscriber for each ElasticBea

2019-08-17 08:05发布

问题:

I have a simple key-value pair collection in my mongo database, it holds configuration details for my web-app and it's read by each EC2 instance started by the ElasticBeanstalk autoscaling (1-10 instances).

Almost every JAXRS service endpoint causes a read from the mongo config collection and I want to stop reading values directly from the DB to lighten the load on the database.

My plan is to read the value once, store it in an in-memory dictionary then use the value from the dictionary thereafter. Once the configuration is changed from an admin web page, then I will clear the value from the dictionary so that it is re-read from the database.

The problem is, only the single EC2 instance will clear its cache, so I need to use some sort of pub/sub to let all the other EC2 instances know.

Do I need a SNS topic, or is there an SQS queue with a pub-sub channel (as eluded to here, but I can't find any examples)?

In either case, it would seem I can only subscribe with a HTTP or HTTPs listener, or poll in a loop with a timeout.

I want this to also work on my dev machine (no public IP) and I'm not sure whether Java will return my EC2 instances private or public IP address. Because private IP's could be an issue then I have concluded that each EC2 instance should poll for messages with a long timeout (20s).

What's the best way to achieve the following

  • Any EC2 instance can publish 'config X has changed'
  • Each EC2 instance will receive the 'config X has changed' message
  • Clean way to unsubscribe EC2 instances when
    • an EC2 instance is cleanly stopped (e.g. ServletListener to detect app is shutting down)
    • an EC2 instance is abruptly stopped/terminated
  • No repeated messages
  • Detect any dead subscribers (e.g no messages collected for 15 minutes) then terminate that subscriber (e.g. terminated EC2 instance)
  • Work from all EC2 instances in a beanstalk environment
  • Also work from remote development machine

What would be really nice is if you could get the Elastic Beanstalk load-balancer to forward SNS messages to each EC2 instance