Pregunta

My scenario is this:

I have multiple webservers that:

  1. need to communicate with the backend (IBus.Publish/IBus.Subscribe)
  2. need to communicate with each-other (IBus.Publish/IBus.Subscribe)

Aside from the webservers, I have a number of windows services that consume the same messages.

In order to make this work, I have the webservers send messages to a central hub, which sole responsebility it is to wrap the message in a new message type and publish it to all subscribers.

Can I somehow avoid this, so I can publish the messages directly from the webservers?

EDIT (Added some code) - Current situation:

... WebServer
_bus.Send(new Message{Body="SomethingChanged"});

... Hub
public void Handle(Message message){
    _bus.Publish(new WrappedMessage{Message = message})
}

... Handlers (WebServers, WindowsServices etc)
public void Handle(WrappedMessage message){
    //Actually do important stuff
}

Wanted situation:

... WebServer
_bus.Publish(new Message{Body="SomethingChanged"};

... Handlers (WebServers, WindowsServices etc)
public void Handle(Message message){
    //Do important stuff
}
¿Fue útil?

Solución

Well, there isn't anything that technically prevents you from publishing messages inside your web application, and likewise there's nothing that prevents you from subscribing to those messages in all instances of the same web application. The question is whether you should :)

Without knowing the details of your problem, my immediate feeling is that you would be better off using some kind of shared persistent storage for whatever it is that you're trying to synchronize (a cache?), possibly using some kind of read replication if you'd like to scale out and make reads really fast.

Again, without knowing the details of your problem, I'll try and suggest something, and then you can see if that could inspire you into an even better solution... here goes:

  • Use MongoDB (possible as a replica set if you want to scale out your read operations) as the persistent storage of the thing you're caching
  • Whenever something happens in the web application, bus.Send a message to your backend
  • In your backend message handler, you update Mongo (which automatically will replicate to read slaves)
  • Whenever you need to query your data, you just query your Mongo set (using slaveOk=true whenever you can accept slightly stale values)

The reason I'm suggesting this alternative solution, is that web applications (at least in .NET land) have this funny transient nature where the IIS will dictate its lifecycle, and at any given time you can have n instances of it. This complicates matters if you keep state in it. This makes me think of the web application as a client, not a publisher.

A simpler solution is to keep state in something that does not come & go, e.g. a database. And the reason I'm suggesting Mongo is that my guess is that you're worried about being able to serve web requests fast, but since MongoDB is fairly easy to install as a replica set where read operations will be pretty fast (and, more importantly: horisontally scaleable), my guess is that this setup would make everything much simpler.

How does that sound?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top