23

I've recently been taking a course on Software design and there was a recent discussion/recommendation about using a 'microservices' model where components of a service are separated into microservice sub-components that are as independent as possible.

One part that was mentioned was instead of following the very often seen model of having a single database that all the microservices talk to, you would have a separate database running for each of the microservices.

A better worded and more detailed explanation of this can be found here: http://martinfowler.com/articles/microservices.html under the section Decentralized Data Management

the most salient part saying this:

Microservices prefer letting each service manage its own database, either different instances of the same database technology, or entirely different database systems - an approach called Polyglot Persistence. You can use polyglot persistence in a monolith, but it appears more frequently with microservices.

Figure 4enter image description here

I like this concept and, among many other things, see that as a strong improvement on maintenance and having projects with multiple people working on them. That said, I am by no means an experience software architect. Has anyone ever tried to implement it? What benefits and hurdles did you run into?

closed as too broad by user40980, GlenH7, Ampt, Kilian Foth, Tulains Córdova Dec 11 '14 at 21:21

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 6
    I'm not sure how this question is out of scope for programmers.stackexchange. It's a question on a specific technique and its pros and cons to determine when usage of the technique merited. I've looked at the tour and the meta site (meta.stackexchange.com/questions/68384/…). Could you please clarify how I should improve the question? – ThinkBonobo Dec 21 '14 at 0:03
35

Let's talk positives and negatives of the microservice approach.

First negatives. When you create microservices, you're adding inherent complexity in your code. You're adding overhead. You're making it harder to replicate the environment (eg for developers). You're making debugging intermittent problems harder.

Let me illustrate a real downside. Consider hypothetically the case where you have 100 microservices called while generating a page, each of which does the right thing 99.9% of the time. But 0.05% of the time they produce wrong results. And 0.05% of the time there is a slow connection request where, say, a TCP/IP timeout is needed to connect and that takes 5 seconds. About 90.5% of the time your request works perfectly. But around 5% of the time you have wrong results and about 5% of time your page is slow. And every non-reproducible failure has a different cause.

Unless you put a lot of thought around tooling for monitoring, reproducing, and so on, this is going to turn into a mess. Particularly when one microservice calls another that calls another a few layers deep. And once you have problems, it will only get worse over time.

OK, this sounds like a nightmare (and more than one company has created huge problems for themselves by going down this path). Success is only possible you are clearly aware of the potential downside and consistently work to address it.

So what about that monolithic approach?

It turns out that a monolithic application is just as easy to modularize as microservices. And a function call is both cheaper and more reliable in practice than an RPC call. So you can develop the same thing except that it is more reliable, runs faster, and involves less code.

OK, then why do companies go to the microservices approach?

The answer is because as you scale, there is a limit to what you can do with a monolithic application. After so many users, so many requests, and so on, you reach a point where databases do not scale, webservers can't keep your code in memory, and so on. Furthermore microservice approaches allow for independent and incremental upgrades of your application. Therefore a microservice architecture is a solution to scaling your application.

My personal rule of thumb is that going from code in a scripting language (eg Python) to optimized C++ generally can improve 1-2 orders of magnitude on both performance and memory usage. Going the other way to a distributed architecture adds a magnitude to resource requirements but lets you scale indefinitely. You can make a distributed architecture work, but doing so is harder.

Therefore I would say that if you are starting a personal project, go monolithic. Learn how to do that well. Don't be distributed because (Google|eBay|Amazon|etc) are. If you land in a large company that is distributed, pay close attention to how they make it work and don't screw it up. And if you wind up having to do the transition, be very, very careful because you're doing something hard that is easy to get very, very wrong.

Disclosure, I have close to 20 years of experience in companies of all sizes. And yes, I've seen both monolithic and distributed architectures up close and personal. It is based on that experience that I am telling you that a distributed microservice architecture really is something that you do because you need to, and not because it is somehow cleaner and better.

  • 3
    An extremely insightful answer. Thank you for imparting this wisdom. – ThinkBonobo Dec 8 '14 at 3:58
  • Here's a recent talk from Martin Fowler (the 3rd one) that touches on a few of these points. – Whymarrh Dec 13 '14 at 0:32
  • Is there a way between monolith and microservices? I have a multitenant monolith application. After some time I see that I should divide per tenant. Each tenant should have own instance of application but they are must share some data and it must be a single/central place. So, I can create separated service especially for that. It looks like I will have couple (not so micro) of app/services. Is it sounds reasonable to do this that way? – dariol Jul 3 '15 at 17:27
  • @dariol There is no good upgrade path from monolithic to full microservices through a middle ground of "we load a large common code base everywhere, then use what we need from it". However it is reasonable to do this as a temporary patch to get through an immediate need. And then begin splitting off real microservices, until the core can be replaced. The reason why that is hard has to do with dependency management. You will keep on hitting, "I just need this, but this depends on that, depends on that...and now I have the entire ball of spaghetti." – btilly Jul 6 '15 at 22:03
  • Another link from Martin Fowler, on this topic: Monolith First – hangtwenty Sep 23 '16 at 17:30
5

I wholeheartedly agree with btilly's answer, but just wanted to add another positive for Microservices, that I think is an original inspiration behind it.

In a Microservices world, services are aligned to domains, and are managed by separate teams (one team may manage multiple services). This means that each team can release services entirely separately and independently of any other services (assuming correct versioning etc).

While that may seem like a trivial benefit, consider the opposite in a Monolithic world. Here, where one part of the application needs to be updated frequently, it will impact the entire project, and any other teams working on it. You will then need to introduce scheduling, reviews etc etc, and the whole process slows down.

So as to your choice, as well as considering your scaling requirements, also consider any team structures required. I would agree with btilly's recommendation that you start Monolithic and then identify later where Microservices might become beneficial, but be aware that scalability is not the only benefit.

  • That is true. The rest of the article goes into particularly how it encourages segmentation by 'business capabilities'. This is definitely a key advantage. – ThinkBonobo Dec 20 '14 at 23:59
2

I worked at a place that had a fair amount of independent data sources. They did put them all into a single database, but into different schemas that were accessed by webservices. The idea was that each service could only access the minimum amount of data they required to perform their work.

It wasn't much overhead compared to a monolithic database, but I guess this was mostly due to the nature of the data that was already in isolated groups.

The webservices were called from the web server code that generated a page, so this is a lot like your microservices architecture, though possibly not as micro as the word suggests and not distributed, though they could have been (note that one WS did call out to obtain data from a 3rd party service, so there was 1 instance of a distributed data service there). The company that did this was more interested in security than scale however, these services and the data services provided a more secure attack surface in that an exploitable flaw in one would not give full access to the entire system.

Roger Sessions in his excellent Objectwatch newsletters described something similar with his Software Fortresses concept (unfortunately the newsletters are no longer online, but you can buy his book).

Not the answer you're looking for? Browse other questions tagged or ask your own question.