
Introduction to Microservices - fixel
https://www.nginx.com/blog/introduction-to-microservices/
======
electrotype
What scares me about microservices is the case where some operations must be
transactional.

What if, in a given use case, multiple microservices are involved but the
operations must be transactional : if one of the services fails, all previous
operations must rollback. What are the recommended ways of implementing this
kind of transactional behavior in a modern HTTP/REST microservices
architecture?

I know the pattern is called "distributed transactions" and is often related
to two-phase commit protocol. But there doesn't seem to be a lot of practical
information available about this topic!

I found this recent presentation[1] that talks about it, but I'd like to learn
more on the subject. Also, I'm looking for _practical_ tutorials, not highly
academic ones! I'd really love to see code samples, for instance.

Any links, suggestions?

[1] [http://www.infoq.com/presentations/microservices-docker-
cqrs](http://www.infoq.com/presentations/microservices-docker-cqrs)

~~~
batou
We've moved down this path from a massively complicated distributed
transaction environment on top of MSMQ, SQL Server etc and you know what? With
some careful design and thought about ordering operations and atomic service
endpoints, we didn't need them at all after all.

Transactions can be cleanly replaced with reservations in most cases i.e.
"I'll reserve this stock for 10 minutes" after which point the reservation is
invalid. So a typical flow for a order pipeline payment failure would be:

1\. Client places order to order service.

2\. Order service calls ERP service and places reservation on stuff for 10
minutes.

3\. Order service calls payment service (which is sloooow and takes 2-3 mins
for a callback) and issues payment.

4\. Payment service fails or payment fails.

5\. Order service correlation times out.

6\. Order service calls notification service and tells buyer that their
transaction timed out and cancels the order.

7\. ERP service doesn't hear back from the order service and kills
reservation.

etc etc.

At step (4) you have an option to just chuck the message back on the bus to
try again after say 2 minutes. If everything times out, meh.

~~~
sanderjd
Thanks for this! It seems like a very interesting pattern and I was completely
unfamiliar with it prior to reading your comment. Looks like a search for
"reservation pattern" gives lots of good places to start digging, but I'm
wondering if you have any favorite resources on the subject. Is there a good
treatment of it in some particular book? Or maybe presentations you've found
particularly enlightening?

~~~
batou
It's an old SOA pattern. Most of those patterns are still valid if you take
away the WS-* cack and stuff.

------
programminggeek
The alternative to Microservices would be to get better at building boundaries
in your application before resorting to creating physical boundaries to
interact with code.

There are a lot of approaches to this. I've explored these ideas with Obvious
Architecture
([http://retromocha.com/obvious/](http://retromocha.com/obvious/)) and the
talk I gave at MWRC 2015 on Message Oriented Programming
([http://brianknapp.me/message-oriented-
programming/](http://brianknapp.me/message-oriented-programming/)).

I think the big lesson is that the Erlang stuff was WAY ahead of its time and
it already solved a lot of the problems of large networked systems decades
ago. Now that we are all building networked systems, we are relearning the
same lessons telcos did a long time ago.

~~~
MrBuddyCasino
This. I know that quote has been overused already, but:

"Almost all the successful microservice stories have started with a monolith
that got too big and was broken up.

Almost all the cases where I've heard of a system that was built as a
microservice system from scratch, it has ended up in serious trouble."

[http://martinfowler.com/bliki/MonolithFirst.html](http://martinfowler.com/bliki/MonolithFirst.html)

Also good: [https://rclayton.silvrback.com/failing-at-
microservices](https://rclayton.silvrback.com/failing-at-microservices)

~~~
malexw
It's a good quote, and a sentiment that I've seen echoed by CTOs and VP Engs
who actually are running or are currently migrating their companies to
microservices.

That said, I feel the quote should be: "As of 2015, almost all successful
microservice stories..."

As the tooling and knowledge around microservices builds up over the next few
years, I could imagine a world where starting with microservices makes sense.
For a new company, the flexibility you get with microservices to try new tech
and throw out failed experiments could result in much faster iterations,
helping to nail the product-market fit.

~~~
bradleybuda
Totally disagree. The advantage of monolith-first isn't that monoliths are
easier than microservices (though they might be). The advantage is that early
in a project's lifetime, you _don 't yet know_ the boundaries between
services. Worse, guessing those boundaries incorrectly is more expensive than
a monolith.

Breaking a monolith into services is difficult, but it's much hard to
"rebalance" microservices once your product grows and you realize you have
gotten the interface wrong. The monolith stage is important because it helps
you figure out what the hell you're building. Establishing service boundaries
overly early risks getting you "stuck" in the wrong architecture.

------
orthecreedence
After reading about microservices, I feel like it's a great idea if you have a
large team and a lot of resources, but that's not really explicitly stated
(although it's nice this article features drawbacks). I feel like there's a
ton of hype but nobody is saying "Don't do this if you don't have a 30-person
team!"

Separating everything out into little APIs all with their own datastores that
all talk to each other sounds great, but I would not to do this on a three
person team. Just give me an old fashioned monolithic API, a large database,
and then I can spend 80% of my time programming and 20% on maintenance. One
app is hard enough to run, why consciously choose to run 10 of them if you
don't have the capacity?

I don't think microservices are a bad idea at all...I love the architecture.
But the hype makes it hard to see that _this architecture probably isn 't for
you_ unless you have the capacity for it.

~~~
johns
If you're interested in our experience on starting on microservices from
scratch with only 2 people, I gave a talk on it:
[http://www.infoq.com/presentations/queues-proxy-
microservice...](http://www.infoq.com/presentations/queues-proxy-
microservices-automation)

I agree they're not for every team, but it definitely allowed us to move, grow
and scale faster than other dev environments I've worked in.

~~~
levelist_com
Great talk. This may be a silly question; however, how do you handle
authentication between the main app and the services? Im in the middle of
building a sizable application but have begun offloading some of the tasks to
microservices, for many of the same reasons you gave. I currently use OAuth2
to authenticate to the main API, but dont really want to add additional
overhead by having to authenticate to each service as its needed.

~~~
levelist_com
perhaps JSON Web tokens between main API and microservice where both have a
shared secret?

------
viksit
Microservices are great, but the underlying protocol they run on is important.

If you're building a REST interface to all your services, and something
consumes them - they might be slower than a monolithic app unless you have
something like a TCP or HTTP level keep-alive built in. Connections need to be
long standing - otherwise the overhead of creating a new connection is pretty
high.

Question here - what is a good way to make this long standing connection
happen? Eg, if you use python urllib3 and nginx - can you keep these
connections alive enough (with pings or whatever) that your latency is lower
than bundling that service within the code itself as a library?

~~~
usaar333
If you use keep alive and your server/load balancer doesn't have overly
aggressive connection termination policies, I doubt re-connections every 60 or
so s will be a major throughput hit. Regardless, you are always going to incur
latency overhead by sending data over TCP relative to just sharing memory.

What I am more worried about with microservices is the data serialization
overhead. Transforming data to some encoding that is robust against version
changes (say using protobuf) can be quite costly on both sender and receiver,
especially in languages with relatively slow object creation (e.g. python).
This is highly application specific, but I'd love to hear others' thoughts on
this trade-off.

~~~
viksit
Using a binary serialized format is actually pretty good that way. For a high
throughput API that I built, shifting to protobuf from json, and using binary
formats made a lot of difference. The packet size is lower, you can use JVM
based platforms to do analysis and analytics (esp when storing logs as proto)
- those benefits outweigh the slowness of the object creation (which isn't
THAT slow on cpython). Atleast on the proto 2.3.x versions that I use.

That said, to my point of keep alives - lets say you've got process A talking
to process B on localhost, which is making web service calls to the internet.
Every 5ms delay is hurting your total response time, especially when your
connection pool is waiting on a dropped connection to be reinstated.

------
sbilstein
I think this is the first time I've really understood the differences between
SOA and Microservices (and realized that my workplace's architecture is a
flavor of Microservice).

"On the surface, the Microservice architecture pattern is similar to SOA. With
both approaches, the architecture consists of a set of services. However, one
way to think about the Microservice architecture pattern is that it’s SOA
without the commercialization and perceived baggage of web service
specifications (WS- _) and an Enterprise Service Bus (ESB). Microservice-based
applications favor simpler, lightweight protocols such as REST, rather than
WS-_. They also very much avoid using ESBs and instead implement ESB-like
functionality in the microservices themselves. The Microservice architecture
pattern also rejects other parts of SOA, such as the concept of a canonical
schema."

So SOA implies the existence of some heavy enterprise tools like WSDL and SOAP
or other RPC type systems. Microservices favor RESTful interfaces.

~~~
dragonwriter
SOA predates the enterprise tooling, which followed on with the popularity of
SOA as an architectural style.

If microservices catch on, expect five years from now we'll be talking nano-
services, and how microservices imply a whole stack of enterprise services
that will have grown up around the microservices architecture.

------
markbnj
I guess I am in what the author termed the "naysayers" camp, in that I cannot
think of the "monolithic" variation they depicted as a "service-oriented
architecture" of any kind. A single chunk of stuff sporting a lot of different
APIs and interfaces can't be thought of as implementing services, imo, unless
"services" is synonymous with "API" and for my part that is too general a
definition to be of much use. If you agree with my view then services already
required a separately designed, implemented, and managed piece of code that
implements a single cohesive set of functions, and all that's left for
microservices to add is minimality, which, imo, should already be in the mix.

~~~
deathanatos
I feel that I'm a proponent of microservices that has only ever worked on
monolithic apps.

> I cannot think of the "monolithic" variation they depicted as a "service-
> oriented architecture" of any kind.

I think you're on the right track here. Note that the article uses "monolithic
application", not "monolithic services"; it really is the lack of services.

> unless "services" is synonymous with "API" and for my part that is too
> general a definition to be of much use

I agree that that is too general. To me, a microservice would of course expose
an API, but whereas a monolithic application exposes the entire application
(or, perhaps, the entire API for everything your company does…), a
microservice is exposing a small facet of the overall application, and is only
responsible for that facet.

I probably agree with you that "services" is probably what most of us are
after; I think the "micro" may just be an attempt to re-emphasize that it
shouldn't be one huge thing, and that perhaps you should split services off
sooner, rather than later, as it only ever gets harder.

Then again, I've never worked with in a microservices-oriented architecture.

------
matthewmacleod
This is a good read, but I'm wondering:

 _The Microservice architecture pattern significantly impacts the relationship
between the application and the database. Rather than sharing a single
database schema with other services, each service has its own database
schema._

Is this a necessary prerequisite? One of the problems I'm dealing with now
(and have been in the past) is the tyranny of multiple data stores. At any
reasonable scale, this quickly leads to a lack of consistency, no matter how
much you'd like to try.

It feels like most of the gain in a microservices architecture is from
functional decomposition of code, with limited benefit from discarding the
'Canonical Schema' of SOA. I'd be interested to hear others' experiences with
this, though.

~~~
outworlder
If you have multiple "microservices", all operating on the same data store, it
is difficult to guarantee the separation of concerns.

Conceptually, though, I don't think it is a requirement.

~~~
nlawalker
Separation of concerns or no, the problem with a single central datastore is
that it will eventually become the bottleneck as you scale. This is really
difficult to fix, not just technically but politically - as a central
datastore grows, everything and everyone starts taking dependencies on it:
reports, homegrown tools, documented troubleshooting strategies, etc. They
become sacred cows of an organization.

Not only will there be resistance to the idea of splitting out that datastore,
but major investment will be required to do it - implementing all of that
disconnected messaging stuff you're going to need, reworking
applications/services to communicate that way, and handling eventual
consistency - which is a tough sell when the app works "perfectly fine" except
for that scaling problem.

------
aikah
> The term microservice places excessive emphasis on service size. In fact,
> there are some developers who advocate for building extremely fine-grained
> 10-100 LOC services.

It's just a matter of time until someone writes a "nano-service" manifesto...

~~~
stevelosh
Let's go all out:

    
    
        Prefix      Symbol  Size                               Example
        yocto       y       1 bit                              Theoretical minimum
        zepto       z       1 byte (close enough to 10 bits)   Really small APL program
        atto        a       10 chars                           nc -l 8080
        femto       f       1 line (roughly 100 chars)         netcat piped into something else
        pico        p       10 lines                           tiny python service
        nano        n       100 lines                          small python service
        micro       μ       1000 lines                         typical "smallish" service
        milli       m       10,000 lines                       about as big as "microservices" would go these days, or a small monolithic app
        centi       c       100,000 lines                      decent-sized monolithic app
        deci        d       1 million lines                    large monolitihic app
        none        n/a     10 million lines                   roughly OS-level app
        deca        da      100 million lines                  god help you beyond here
        hecto       h       1 billion lines                    
        kilo        k       10 billion lines                   
        mega        M       100 billion lines                  
        giga        G       1 trillion lines                   
        tera        T       10 trillion lines                  
        peta        P       100 trillion lines                 
        exa         E       1 quadrillion lines                
        zetta       Z       10 quadrillion lines               
        yotta       Y       100 quadrillion lines

~~~
VikingCoder

        googol  NYSE:GOOG      ??? lines              Google

~~~
hspak
It's obviously Googol lines.

------
ed_blackburn
I think some teams are going to discover that RPC is a better fit for some
APIs. Will we see Thrift get more popular? A resurgence in WCF(!) or something
new and super light? For asynchronous are we going to see more pub / sub? Is
this a good fit for ZeroMQ? I think there's a lot more mileage in these
discussions...

~~~
jessaustin
ISTM RPC is eventually a too-leaky abstraction. That is, if used in
synchronous fashion, in the long run it will cause pain. If you use it
asynchronously (which seems to stretch the definition of RPC), why not just
use something that is naturally asynchronous?

~~~
tracker1
I don't think you need to be pure-rpc or pure-rest... I think the parent
really means to say that rpc-like calls are sometimes a better api than pure
rest... especially given some business and security rules that are in effect
regarding a given record.

I've considered using ZeroMQ Request/Response interfaces with a defined
JSON/UTF8->GZ instead of REST layer... My testing worked pretty well, and it
could even be used behind http requests (packaged).. with 0mq, you can setup
layers of distribution for service points.

At one level or another micro services architecture trades complexity of an
application as a whole for complexity in the system as a whole. In the end,
most of the services being used in practice could handle the few ms of
overhead that http/tcp rest services had over 0mq...

The hardest thing for me was simplifying things as much as possible, I worked
really hard to avoid SPOF, that many tened to go to. In the end, instead of
the likes of etcd, table storage with a caching client was sufficient...
instead of complicated distribution patterns, for a very small load, having a
couple instances of each service on each machine was easier.

It really comes down to what you _really_ need, vs. what's simple enough to
get the job done, and not lock you down. In then end, love docker (and dokku-
alt), but things like coreos, etcd, and fabric turned out to be overkill for
the needs.

------
sul4bh
The article mentions using a different database for each service. Which means,
you cannot join table between different databases and you lose the
'relational' aspect of RDBMS. How is this problem solved by people using
micro-services? For example, how do you related trip data and driver data for
reporting purpose?

~~~
Cieplak
One pattern I've seen is having an OLTP database per service and an ETL
process to stream each service's data to a central warehouse or OLAP database
that would satisfy reporting requirements.

------
sinzone
We're honored to be partner [1] of Nginx with the OSS Microservice Management
layer KONG [2]. Kong is built on top of Nginx and uses Cassandra for storing
the config.

[1] [https://www.nginx.com/blog/nginx-powers-kong-api-
management-...](https://www.nginx.com/blog/nginx-powers-kong-api-management-
solution/)

[2] [https://github.com/mashape/kong](https://github.com/mashape/kong)

------
myohan
I think architects have to be very careful in deciding which components would
qualify as a microservice and which ones should be lumped together. This
article sums up my thought. [http://www.infoq.com/news/2014/11/ucon-
microservices-enterpr...](http://www.infoq.com/news/2014/11/ucon-
microservices-enterprise)

------
tostitos1979
I've been hearing the Microservices buzz for a while. I recently tried to set
up a new project as an ensemble of microservices but got stuck. There is a
fair bit of "common" tooling like load balancers and events/log system. I'm
about to throw in the towel since it seems too complicated to get going for a
brand new project.

~~~
jedberg
I'm glad to see this because I cofounded a company to solve exactly this
problem. Link is in my profile if you're interested, we just launched.

~~~
tostitos1979
Thx .. I'll look into it. I recently ran into this talk which confused the
heck out of me: [https://yow.eventer.com/yow-2014-1222/implementation-of-
micr...](https://yow.eventer.com/yow-2014-1222/implementation-of-microservice-
architecture-by-fred-george-1692)

Notice his use of Kafka and 0mq to create an SOA for microservices. All of the
stuff I had seen previously had the services communicate with each other via
REST. So everything is synchronous. In the talk whose link I posted above,
communication is asynchronous via messages. Is it reasonable to do both?

Also, how the heck does one deal with transactions across services?

~~~
mountaineer
Sure, it's possible/reasonable to do both. I work with asynchronous
Microservices using RabbitMQ where PubSub shines in that many services can
respond when the application publishes a message (1 service for email, 1 for
push notifications, 1 for capturing data for analytics, etc). But it is fire
and forget as far as the application is concerned.

Compare that to synchronous services where the application has be aware of all
of them and coordinate calling them all. It is easier to use synchronous when
the application requires an output from the service to respond.

Transactions across services are certainly not easy:

"Distributed transactions are notoriously difficult to implement and and as a
consequence microservice architectures emphasize transactionless coordination
between services, with explicit recognition that consistency may only be
eventual consistency and problems are dealt with by compensating operations."
[1]

[1]
[http://martinfowler.com/articles/microservices.html](http://martinfowler.com/articles/microservices.html)

------
panamafrank
My main advice to anyone considering writing a microservice based architecture
from scratch is to keep a really tight handle on code duplication and testing.
Also take a deep look into Erlang, it's written with these types of systems in
mind.

------
HeroOfAges
I’m having a really hard time understanding the pushback against a
microservice architecture. Done properly, I can’t see the difference between
building an app using a microservices architecture and a mashup. Am I being
naive?

~~~
mountaineer
I think the pushback can be summarized by the fact that there are more moving
parts with a microservice architecture. Harder to test, more things that can
break, more coordination for deployments.

Are you referring to mashups in that the application is using external APIs?
I'd say that's similar with the difference being you don't have to coordinate
the deployment part. With mashups you still have the testing challenge and
reliance on another system to be running that comes with a microservice
architecture.

~~~
HeroOfAges
I guess I'm confused about why you would need to coordinate deployments. In my
mind each microservice is completely decoupled from any other. There are a
large number of tools to automate the process of testing and deployment. I
think we as developers understand the need to code defensively and we
understand how to build applications that have large amounts of asynchronous
operations. I'm also not sure why people keep insisting on using messaging as
a way to allow one microservice to communicate to another. Wouldn't exposing a
RESTful interface over HTTP work well enough? The concept seems so simple and
refreshing. What am I missing?

~~~
mountaineer
Interesting, I feel like I've seen much more literature about RESTful
microservices than message oriented approaches. I've done it both ways and I'm
of the opinion that RESTful services are more complicated for a couple
reasons:

* All RESTful services must be up and running for application to be fully up and running * application must have all knowledge of RESTful services it calls

With messaging (and PubSub), services don't need to be running at all times
and you can add as many services you'd like without the application needing to
know. Applications just says "hey, something happened" and services go to
work.

I agree with you, in either case, it is important to code defensively and be
aware of possible request version mismatches. Deployment coordination is
probably awash between the 2 approaches. I think testing is more of a
challenge with message oriented too, as most integration testing tools are
geared towards HTTP interactions.

