tags:

views:

417

answers:

7

I am thinking about offering my product as a service-- delivered via online. Currently it's a shrink-wrapped software that users download to their servers and run on their servers-- like fogbugz.

In my new business model, I will offer two business mode, one is the traditional shrink-wrapped software that users install on their servers -- and do all the maintenance, upgrade stuff. Another is the Software as a Service(SaaS) type, where the hosting is done on my servers, and users are given a single URL to logon. Of course, each customer account will have a unique URL, such as companya.mysoft.com, companyb.mysoft.com.

The question now is since I already have an existing codebase, I want to do minimum modification to my code so that it supports two modes of business. For the SaaS mode, I want create multiple instances for the application-- one for each customer. So each customer will have their own databases, their own applications. All of the customer databases and apps are located on my server. The good thing is that I don't have to change my code at all. The bad thing is that there are a lot of redundancy, and may not be scalable.

What do you think about this multiple-instance-one-for-each-customer? Or I must modify my code so that both modes are supported ( easy to maintained and for upgrades)?

Edit: The download version is needed, there is no way to avoid this.

Edit 2: My App is a PHP app.

+1  A: 

Depends on the number of customers. At first you can probably get away with running one instance per VM, but it's not as scalable as handling multiple customers per instance.

If it becomes a staple source of income, you'll definitely want to move over to that model. Definitely worth testing if there's large demand for it before comitting to the work, though.

patros
+1  A: 

It's hard to answer this question without more information but with these kinds of branding/multi-homing issues, the one key question to ask is this:

Are these sites (for the different customers) more alike than different?

Now that's a subjective question. How much are two sites alike? Can you quantify that? Not really.

But if the answer is "they're almost totally the same" or even "they are the same" (branding issues notwithstanding) then do yourself a favour and host only one version of the code and have both sites point to it.

You can easily determine what server was called and change your logic accordingly.

Branding is the other issue but if you've done your application right this should be largely an issue of changing your CSS includes, possibly your Javascript includes (eg jQuery styling) and (hopefully worst case scenario) changing your headers and footers (you do have global headers and footers right?).

Basically if the sites are quite similar then share the code and just have exceptions for what's different. If they're totally different then do the opposite. Cater for the most common scenarios.

cletus
A: 

DRY says no. Better to add a role-based flavor to your app so you can more easily add in customers 2, 3, 4, etc.

I'd spend some time thinking about what changes for customers in your app and designing the app to be data or configuration driven.

duffymo
+3  A: 

Hi Ngu Soon Hui,

This is always a difficult decision, and you identified the major pit fall of installing a new instance on your server for each customer. It doesn't scale all that well and it is almost impossible to upgrade easily. Plus it is not very SaaS since you are basically just install the software N times.

However there is an alternative. Keep your database the same, and install a new instance of the database for each customer. But change your front end, so that it can handle multiple URL's. That way you only have to have one instance of the application running against multiple databases depending on the URL.

This also scales very well, and I think this is the FogBugz model? Then if your customers want to install it there really isn't any change, because they will only have one URL pointing to one database. And on your side you will have multiple URL's pointing to multiple databases, just the software will be running only once handling all these requests.

Also as a nice to have, you may want to consider custom domains. Instead of companya.mysoft.com allow companya.com. That won't require any real changes in your URL handling, the compoany will just have to setup a CNAME record and point it at your server.

Good Luck

Nick Berardi
+1  A: 

"The bad thing is that there are a lot of redundancy, and may not be scalable."

Really? Where is the redundancy?

If you've used a good set of tools, your SaaS installation can have one code base used by multiple client sites.

It works like this.

  • In some baseline directory (we use directories like /opt/theApp) you have the software.

  • In some working directory (we use directories example /var/www/cust1, /var/www/cust2) you have some configuration files that reference the code.

One code base, multiple installations. In Django (and many other web frameworks), this is relatively easy.

If you've chosen your tools poorly, then one site == one complete copy of the code and you have a potential problem. However, this is what links are for. You have have the customer-specific "copy" include soft links to the baseline copy.

After you go through the effort to disentangle "customer-specific features" from "web installation" and "baseline code", you'll find you can do QA nicely and provide customer-specific features and extensions.

Multiple instances is more scalable. You can, without much difficulty, have your SaaS environments spread among multiple concurrent processors. Each customer-specific instance serves the customer's data, keeping customers cleanly separated. They can (if you tackle this properly) all share a common code base, installed on one (and only one) server.

Separate installations per customer (with a common code base) is very pleasant for assuring the customers that their data isn't casually comingled with their competitor's data.

S.Lott
A: 

From the DB angle I'd definitely go with the one DB per customer model. The benefits of being able to manage each customers data in an independant way is a must. And that approach allows you to scale by placing different customers data onto different servers as the business grows.

Also your web/application server should be able handle multiple instances of your app running for different users and customers straight out of the box. It should sort out a single copy of the code and multiple data segments (assume that model still holds afetr 20 years?). Again that's scalable - move up to a web farm, and it all still works - assuming you can get your sessions sorted.

So you get a win/win, your code base stays pretty much the same, and you get scalability as provided by the environment you're using. You can also setup different versions, releases for customers to try - we'd often keep multiple versions of the same site running in parallel so we could rollback if a fatal bug hit us on a new version.

The key to getting this working nicely is to look at the HTTP headers and link the config ie - which DB, and software version to actually point to based on that.

MrTelly
+4  A: 

A complete instance per customer will create maintenance nightmares as your customer base grows. But it may work to get you started in the SaaS business. Be aware that success will likely mean some re-architecting of the application to scale better.

Important details to consider include:

Data segregation, is very important, maintaining and upgrading thousands of individual databases involves a lot of overhead. A common concern is that customers will worry that their data is mixed with someone else's and it is somehow less secure. I have worked for three different companies that offered a SaaS model and data mixing wasn't ever a customer concern. At the end of the day you will have all the data and it will or won't be secure, it doesn't really matter how many dbs you use. Unless you could never have more than a few dozen customers I highly recommend consolidating multiple customers into a single DB, and supporting multiple dbs, it makes managing the databases much easier. I have worked with a system with several PetaBytes of data for >80k customers spread across a couple dozen databases, and it was quite manageable. I have worked with a system with a few TeraBytes of data for several dozen customers each with their own DB and it worked pretty well. Then one day we got a big deal that added 300 customers all at once and managing the databases got awkward very fast.

Branding, is every customer a seperate brand, or will many customers share a brand, or is everyone happy to use your companies brand. Ideally you can locate brand resources (css/images/etc.) by URL or login, or probably both. If you will only ever need a handful of brands it may be reasonable to setup servers for each brand.

Versioning, is it reasonable to "force" all customers to upgrade at the same time. I highly advise you do everything in your power to keep all customers on the same release, supporting multiple releases will drive your support costs up substantially. Generally it is easy to spin the "you always have the latest and greatest" facet, but some customers are really adverse to change. Customers that may need to be left behind will need to be on seperate instances.

Customization, it doesn't sound like you have this problem, but if you are currently shipping custom builds to some customers, you will need separate instances for each build until you can create a universal build that works for everyone.

ScottS