9 comments

[ 4.3 ms ] story [ 48.0 ms ] thread
SOA is nice but it also has some drawbacks. While the OP argues that it brings simplicity, SOA also makes the design process more complex.

Like functional programming, you have to think more carefully about what each service will do, and how it will implement that functionality. Just deploying a service doesn't give you free scalability, you have to design the service to scale. You have to think about shared state, and stuff like that.

I think that maybe monolithic applications are more popular than SOA apps, because it is faster to create one (even though it is harder to extend afterwards).

TL;DR: Build an API for every component that's hard to scale, to maintain, or needs dedicated resources. This is the definition of distributed architectures.

HTTP is not necessarily the best protocol to use. It's easy to use, but sometimes TCP or other protocols are a better fit.

SOA is less obvious up front, as most good architecture tends to be, but the benefits are there over time for sure.

Also, SOA is not always brilliant on day one, but you can give your small app a head start by writing a web api first, then build your app on top of it by making HTTP requests to itself basically or by writing your app as a service layer but not as a separate set of HTTP calls.

The point is you don't have to have a monolithic architecture to start with SOA, you can use a simple RPC or RESTful pattern and evolve it over time as your needs grow.

I'm a total contrarian to the HN conventional wisdom on this, IMHO SOA has the opposite affect on all three bullet points here:

Effect 1: Maintainability - when you have N (say 3 - 5ish) environments to maintain you have more to maintain than when you have 1. Its literally that simple. Also, the example of knowing the account code is over in the account service is just absurd, choosing to pollute or not pollute your namespace with interdependent code doesn't require separate server clusters, it just requires you not do it.

Effect 2: Scalability - what is the problem at all with "scaling your entire application" when one subset of functionality needs to scale? None of you are writing in languages or at a level where you're worried about whats in L2 CPU cache, so who cares if the same cpus are switching back and forth between all your different features? I don't understand why that's a problem that needs solving. Nothing is cheaper or more scalable than cpu cores, its not a boundary that makes any sense to shard on.

Effect 3: Simplicity - this just on its face doesn't make any sense. N interconnected parts are more complex than A part. I mean you can say you believe its worth it, but you can't say its simpler.

I agree with you on 1 and 3. I have developed and deployed several web apps as a single WAR file dropped on Tomcat. A servlet init method can start up one or more background work threads, and everything lives in one JVM. Tidy.

I disagree on 2.

In my practical experience with SOA, at it's core what it really means is discrete codebases for discrete functionality within your application. So while you CAN operate in separated environments, you don't necessarily have to. Although the article seems to approach SOA only via web services, that's not the only way to do it and there's no reason why the service can't be consumed as a library. When it comes time to scale, it's trivial to prop that API up behind a web service interface.

There is nothing wrong with scaling the entire application to meet the demands of one specific module / bottleneck, however, this isn't always a cost effective option. I've found that scaling entire monolithic applications often means throwing more hardware at the problem whereas scaling a service may mean only configuring your server environment to better meet the technical problems of that specific service (example: picking a data store that matches the storage, reliability, and I/O requirements of the specific service which may vastly differ from other components in the application).

I agree with your third point. Having many small parts makes the individual modules and functions simpler to understand, but it does not make your system easier to understand as a whole.

SOA is a great approach when you have a defined set of requirements that you know will not be changing significantly so you can create interfaces that can remain as concrete as possible over time. This is why SOA is a great solution for the enterprise. The advantage of a monolithic application allows for rapid prototyping because the individual components can be built quicker -- it's much easier to test if a component is a benefit to the actual business objective that it's serving.

In the handful of applications I've been in charge of developing that have matured and grown over the years, they've all started as a monolithic application that slowly grow into a SOA-type approach. As specific components run into problems, they get refactored into their own independent services that the "monolithic" app either calls via a web service or as a library API. Eventually the "monolithic" app exists only as the web frontend with all the heavy lifting being done by services.

I couldn't agree more. There are also many practical issues that I rarely see touched on in these yay SOA articles, like:

Scaling down for development. If you need to start N separate services and work in three projects to get work done, things get tedious fast. Also diffs start to cross projects if you split things too granularly.

Monitoring and management in production. Every process is a liability and requires work to monitor and manage. A single set of homogenous processes is much easier to deal with than many sets of different types of processes.

There's a line where you can be too monolithic. There's also many cases where breaking out services is necessary for isolation and distribution - actual architectural properties that are useful. But I don't get this tendency to break things down for the sake of breaking them down. It seems to come from a very high level architectural view of the problem domain with little concern for practical issues in developing, deploying, monitoring, and managing systems over time.

I think it's possible to get many of the benefits by decomposing your back end into logical subsystems (still running in the same process, etc.) or vertical slices from the get go, rather than starting out with some fixed number of layers that horizontally span your app. I'm building a JSON API right now this way. My take is that Dividing first by subsystems and then by layers prevents the growth of monolithic layers and lets each subsystem evolve independently. If you have contracts between the systems, you can later split them out onto separate boxes. So far, it feels reasonable. You do give up querying across all your tables. We're trialing Mongo (jury still out on that choice) which means we don't have the option to join anyway. The bet is that we'll need other data systems for reporting style queries or other data processing, but that's not the major concern of the JSON API.

I believe that breaking up the code this way makes it easier to reason about the app (isolate probs, etc.) and provides more modularity and flexibility then when your primary division is layers. Not sure why, though, you'd want to go the extra step of physical isolation from the beginning. Why? Unless, perhaps, you feel it is the only way to enforce the separation of systems.

SOA is actually good for political reasons in a large organisation more than anything else. If your webapp has multiple application groups then its a definite must.

Ie, one group is independent of another even if the systems are pretty coupled.

Amazon, Bloomberg are all SOA now.

For a web app - I think you can get a few million customers before having to worry about SOA.