A Perspective on SOA

Tweet

no_soaAfter two decades as a developer, I would like to summarize my thoughts about a topic that crossed my path multiple times: SOA. A high-level definition of SOA is developing and combining services into something greater. Hopefully, this combination is useful as a product, whereas each service should be independent and reusable on its own.

SOA, as a buzzword, has been heavily used in tech articles and many developers probably thought “hey this would look nice on my CV/resume.” In other cases, it has been a management decision to introduce SOA since it seems easy to throw these 3 letters against any problem. After all, we’ve all been taught “Divide and conquer” right?

Before you continue reading, I probably should warn you: I think in many cases SOA is the wrong approach. I have worked for many companies that use SOA and have seen many projects fail or struggle. I had a minor epiphany recently and must say: I really like the idea of having monolithic web applications. I should probably explain…

Development

Normally, a developer works on and starts his application on his local machine. For a Rails developer, basically all you have to do is run rails server in your project directory. When you slice one service out of your app, you will have to start this service separately before you can begin your work. When something does not work, you will have to grep through the logs of your application AND your service.

Of course, this will work and does not sound like a major overhead, but think of having five or maybe even 10 services involved. Now, you have to start all of them, find the logs if something went wrong and so on. Later you will try to automate things, maybe use some configuration management tools to install all the services automatically and even introduce some centralized log management tool. The bottom line is: You will need more time to do the same thing compared to a monolithic app.

Testing

Let’s discuss testing for a second. You want to test your application with automated integration tests, right?. One option would be to use an existing service running on an integration system and test against that. We have done it this way many times and often we forgot to check what version of the service was running there. I can assure you this is a great way to kill a few hours.

However,you could mock everything. This basically doubles your testing work because when changing a service’s behavior, you now have to change your mocks too. Maybe you decide to start new instances of each service when running your integration tests. This is probably the safest way but takes time to implement and time during each test too.

Deployment

You have to deploy these services and your web application. Some management effort is needed to know what to deploy and what side effects are possible. If you do continuous deployment and every commit with green tests could go live, well, you could be all right most of the time. However, if you deploy once a week it will definitely get harder. Many people think deploying a service is easier than deploying the whole app.

I don’t get that. When you have a cluster of Rails web servers behind a load balancer you can deploy one after another without any user impact. Generally speaking: The deployment of a service in production usually also means having a cluster of this very service to ensure a deployment without user impact. Therefore you will probably need a load balancer for every single service configured. This can get ugly in a hurry.

Scaling

In a monolithic application scaling is quite easy. If your application runs slow, you will add some servers to scale out or buy some larger machines. Perhaps you split the db and have more db servers (sharding). Having a couple of services means you will have to scale each of these services. What if one service is quite busy? Now this service nees another machine and you will have to monitor which services are getting slow individually.

Operations

In operations you want some monitoring of the systems health. You could use Munin to graph response times or Nagios to see all servers are up and running. With SOA you usually have a dozen services to monitor.

Performance and Reliability

Making an HTTP connection to your service is a lot slower than just calling a library/gem or some code inside your application. You have to keep in mind how your service calls are designed. The interface has to be quite complex, since the target should be to call the service only once per user request to keep latency low. Remember, every call to your service will take a couple of milliseconds. That is quite acceptable if you call it once, but if you call it a hundred times to serve a single user- request, you are in deep trouble.

If you think your socket connection to the service is as reliable as a method call inside your app, you will be surprised. A socket connection is handled like an open file in Linux. If one of your services is getting slow, (maybe an index is missing) each service call is running into a timeout. Since your customers are still sending requests, the amount of sockets increase. Eventually, you will run into the socket limit have to figure out which service is responsible for the disaster. In the meantime, your application is down and you enjoy the relaxing melodies of all the sirens and flashing red lights.

Options

That all being said… what are your options?

One option could be to slice your system vertically instead of horizontally. Meaning instead of putting your low level stuff into services, try to slice your app into different domains, maybe one Rails application for managing user profiles, one for doing some interaction with others and so on. These applications could share the database or have different databases and communicate, if necessary, via REST services.

When are services adequate?

In large companies every department has its own set of applications. They maybe even have several programming languages or frameworks in use. If they need to communicate with a service that many applications need, perhaps something like fraud prevention, I don’t beleive there is any way around SOA.

Summary

In my opinion the important point for every developer and architect alike is to think about the consequences of having services. We should not do it because it is cool nor merely because other companies do it, as it could lead to future trouble. Keep in mind that, when extracting code to a service, we have yet another application to deploy, maintain, and monitor. Furthermore, we have additional network communication that could fail and will be significantly slower than calling functions or libraries on the same machine.

Simply put: If things are getting too big and ugly, we have other techniques, such as splitting our app horizontally or creating libraries/gems.

What are your opinions or experiences regarding SOA?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • hao

    SOA is an architecture pattern, while rails is a web framework. To make the comparison of the two are kind of irrelevant.
    SOA usually is used for integrating heterogeneous systems written in different languages, running on different platforms. Rails can easily fit into the SOA architectures, since it’s implemented in RESTful pattern.

  • Marcus Lankenau

    The point it is neither about comparing SOA and Rails nor how to fit Rails into SOA. SOA has nothing to do with RESTfull patterns but with services communicating over wire and having different parts of the software on different machines. If there are existing service you need to use, there is no debate, your already hava a SOA. The point is when to split your software into services and when not. I know many people thinking SOA is the way to go and they start splitting monolythic (Rails) apps vertically. That is just a bad idea.

  • Schmulik Raskin

    Two issues with your conclusions:

    1. From my experience with SOA, what you describe as possible options is actually what SOA is really all about; what you describe up till that point is a multi-tier application, where is tier is a separate process.
    SOA is about vertically partitioning an application, such that each service supplies functionally, encapsulating all the logic required to fulfill the request: Business Logic & Validation, data access (databases, other services – internal or external), etc.

    2. More importantly, in my opinion, is that almost all the issues you describe a) can exist in vertically partitioned applications, and b) describe the issues with the available tools, such as deployment, configuration and testing, rather than what is wrong with SOA itself. Your real options should be which tools you use to manage the Ops side of SOA.
    Don’t throw out a perfectly good architecture because it is a pain to configure the web server; we need to figure out how such an architecture should be configured easily, and find or create the tools to match.

    All that being said, I agree that for some applications, it doesn’t make sense to use SOA. For example, end-user applications such as mobile or desktop apps really don’t need that overhead.

    Schmulik Raskin.

    P.s. I once heard Juval Lowey, who is an Architect in the .NET/WCF world, say that if an application correctly follows and implements the principles of SOA, the latency between services will be so negligible as to not affect performance almost at all.