tags:

views:

162

answers:

4

I am working on a system that splits users by organization. Each user belongs to an organization. Each organization stores its data in its own database which resides on a database server machine. A db server may manage databases for 1 or more organizations.

The existing (legacy) system assumes there is only one organization, however I want to 'scale' the application by running an 'instance' of it (tied to one organization), and run several instances on the server machine (i.e. run multiple instances of the 'single organization' application - one instance for each organization).

I will provide a RESTful API for each instance that is running on the server, so that a thin client can be used to access the services provided by the instance running on the server machine.

Here is a simple schematic that demonstrates the relationships:

Server 1 -> N database (each organization has one database)

organization 1 -> N users

My question relates to how to 'direct' RESTful requests from a client, to the appropriate instance that is handling requests from users for that organization.

More specifically, when I receive a RESTful request, it will be from a user (who belongs to an organization), how (or indeed, what is the best way) to 'route' the request to the appropriate application instance running on the server?

A: 

That is a very tough question indeed; simply because there are many possible answers, and which one is the best can only be determined by you and your environment.

I would write an apache module in C++ to do that. Using this book, I managed to start writing very efficient modules.

To be able to give you more solutions (maybe just setting up a Squid proxy?), you'll need to specify how you will be able to determine to which server you need to redirect the client. If you can do it by IPs, though a GET param, though a POST XML param (like SOAP). Etc.

Gianni
I must admit, I was seduced by the idea of writing an apache module - but the point Ahmed made brought me back to reality :)
morpheous
@morpheous I did it already, and it wasn't that bad. Using a tutorial as a basis for my app, I was up and running in half-a-day. From then on, I never really had to go back and touch any apache specific stuff.
Gianni
A: 

As the other answer says there are many ways to approach this issue. Lets assume that you DON'T have access to legacy software source code, which means you cannot modify it to listen on different ports for different instances.

Writing Apache module seems VERY extreme to solve this issue (and as someone who actually just finished writing a production apache module, I suggest avoiding it unless you are making serious money).

The approach can be as esoteric as you like. For instance if your legacy software runs on normal Intel architecture and you have the hardware capacity there are VM solutions, where you should be able to create a thin virtual machine, one running a single instance of the software and a multiplexer to tie them all.

If on the other hand you are running something like HPUX well :-) there are other approaches. How about you give a bit more detail?

Ahmed.

Elf King
+1  A: 

From what I can gather, this is essentially a sharding problem. Regardless of how you split the instances at a hardware level (using VMs, multiple servers, all on one powerful server, etc), you need a central registry and brokering layer in your overall architecture that maps given users to the correct destination instance per request.

There are many ways to implement this of course, so just choose one that you know and is fast, and will scale, as all requests will come through it. I would suggest a lightweight stateless web application backed by a simple read only database that does the appropriate client identifier -> instance mapping, which you would load into memory/cache. To add flexibility on hardware and instance location, use (assuming Java) JNDI to store the hardware/port/etc information for each instance, and in your identifier mapping map the client identifier to the appropriate JNDI lookup key.

Pete
most pragmatic answer, I suppose :)
morpheous
+1  A: 

Letting the public API only specify the user sounds a little fragile to me. I would change the public API so that requests specify organization as well as user, and then have something trivial server-side that maps organizations to instances (eg. organization foo -> instance listening on port 7331).

mirzapirza
True, but changing the API is a trivially simple problem to solve though.
morpheous