I think Martin's post does the best job currently of defining what microservices are, and there is a good degree of consensus in the core definition from those of us who work with them and talk about them.
My own take on this, which avoids talking about technical implementation detail too much (because that will vary from platform to platform) is:
"Independently deployable autonomous services that work together".
IMHO, the single most important characteristic is that a single microservice can be changed, and deployed into production, independently of any other service. If you can do that reliably, it follows that you are probably doing many of the other things I recommend, either in my book or talks (sidebar - my Principles Of Microservices
talk might be a good place for more background on this stuff).
Going over the points/questions raised in this thread
Claude Moore wrote:
> However, if I build an application as a composition of microservices, I think I will quickly need some medium to orchestrate, manage, let them work together. Isn't this what an appserver already does ?
The job of the appserver, in a Java
context, is manifold, but does little to help microservice architectures IMHO. It allows you to run multiple 'separate' services in one JVM, allowing for optimisation of resources. It may provide tools to help deployment and lifecycle management of a single service, and may also provide clustering support. When you start looking at the larger problems of service discovery, configuration, monitoring etc., an appserver only solves these problems if you buy into the appserver wholesale - which means you need it across your whole ecosystem. That means locking yourself into a tech choice that is going to be very hard to change. I'd also say that the tooling provided in the Java space has been lacking - JNDI, questionable cluster management technology etc., and given that the state of the art in this space is changing a lot, I'd want some flexibility here personally.
One other thing to consider. AppServers are great for managing multiple services with a single JVM. They try and provide isolation between services, but can't always do this effectively. I've had numerous problems with services causing deadlocks in the appserver itself, single services using up all the resources and taking down all other things on the same machine etc. In practice, most of the microservice shops I see deploy single services as separate processes (so in java-land probably using an embedded container). Containers then let you put these separate services on to their own isolated OSes more cost effectively than normal virtualisation, thereby providing an additional level of isolation to make systems easier to manage, more robust etc. If they need distributed configuration management or service discovery, they use a dedicated tool for this (Eureka, Ribbon, etcd, consul), connection management (hystrix, polly), load balancing (mod_proxy) etc.
Claude Moore wrote:
A key factor to communication seems to be adoption of JSON as lingua franca, with basically REST calls. That's ok, but what about network overhead and latency ? For years we have been told to avoid as much as possible remoting (speaking about EJBs for example), and now we're going to build an architecture which relies heavily on socket based interoperability. That's a bit weird.
Although JSON over HTTP is commonly used, it isn’t the only mechanism. The use of binary protocols such as Thrift and Protobuffs are widespread - these provide some of the benefits of client/server stub generation along with lean payloads, and are much better at handling changes than Java RMI for example. Also many services communicate via messaging protocols, which can be a mix of binary or textual.
I cover this a lot in chapter 4 of the book
- there I focus firstly on the importance of finding the right collaboration style for you (event-based, request/response) then picking a tech that fits that. Binary protocols can be more lean, but can increase coupling. Text-based protocols are great for interoperability and HTTP can scale very well, but won’t be great for low latency.
What is key is that whatever protocol/collaboration style you pick, then pick the tech that best delivers on that given the constraints you have.
Remoting causes problems in a number of ways. Increased latency is one. But you also have to consider many other factors - CAP Theory comes into play much more, meaning you may have to let go of things like transactions, and it can increase your surface area of failure too, as you have to plan for each and every network call failing. The fallacies of distributed programming
apply in the context of microservices just as they do with any other distributed system!