Microservice communication patterns
There are many ways for your microservices to communicate. One of the biggest problems of deciding how they should communicate is weeding out the good information from the bad or the new from the old. Another thing to consider is your systems needs. How large is the system, how many services will it consist of?
Should your microservices communicate by making Asynchronous REST calls to each others API’s? Should you you RPC ( remote procedural calls)? Should you use an ESB (Enterprise Service Bus)? What about a Message Broker like Kafka? Or you could even use a single database to link all the services with all the services reading and writing to their own tables. You also have Actor Frameworks like AKKA that use the actor model and pass messages to each other. And that isn’t even an exhaustive list.
Microservices = SOA
Microservices are just an evolution of the Service Oriented Architecture pattern of the previous years. It took quite a bit of reading and googling to figure that simple fact out. Microservices are just another tech industry buzzword, now lets all make money with it.
Microservices are a culmination of “better practices” that were born out of the struggles to get away from giant monolithic, hard to change code bases. In the end Microservices are SOA wired together and built slightly differently. That is a bit of an over simplification, but this article covers Microservices vs SOA so I won’t rewrite it.
The easiest and first way most people think of communicating between microservices is with REST over HTTP. Which means each of your microservices has an API and they communicate by sending HTTP requests and responses to each other. Each service has a router that routes the request to the proper request handler.
REST can work well for communication between the users browser and the websites API Gateway interface, but it should not be used for inter-service communication. The reason you should not use REST between services is because with Microservices each service is distributed and has it’s own URI or IP address. This means that Requests can fail and if they fail you need a system to monitor and try again until the request succeeds. What if there is a network problem? Also you will need Service Location and Discovery, load balancing and much more. In a microservice world you should build everything to fail because it is going to fail eventually, don’t fight reality.
The following video does an excellent job of explaining REST as it relates to Microservices.
RPC or Remote Procedural Calls is another way to communicate between services. RPC is a bit more complex and requires. RPC makes it feel like you are calling local classes and methods, however in reality you are still using HTTP to communicate between services via a network, a network that can fail meaning the request is lost into thin air. Or the server that hosts the service may be down, you still have many of the problems of REST, but with some added disadvantages. Chapter 4 page 134 of Designing Data-Intensive Applications by Martin Kleppmann gives a long complete list of all of the downsides of RPC which I will not duplicate here. If you are doing microservices you need to own that book anyways so buy it.
One reason I don’t like RPC is because it looks like you are using local method calls. The problem this creates is when you go to change a name of a method or the RPC software you are using, refactoring is much harder. Back when investigating RPC on my own I created my own super simple RPC system because I wanted to know what was going on. There is a bit more to it than what I describe here but basically you create a class with methods and call those methods in your code. Those methods translate your method parameters into a JSON for example, then send them over HTTP to the other microservice for translation. You other microservice receives the HTTP request, then separates the parameters out( the same ones you called the method with). It then compares the parameters to a list of methods it has, when it finds the correct method it invokes it, and builds a response in the same fashion as the method invokation that started the process in the other microservice. One the initial microservice gets the response it too has to translate it again. You do the HTTP Communication via CURL which is listed in the Networking Resources links.
As I said there software libraries for RPC, multiple for each language actually. RPC is an old technology, I wouldn’t use it much in Microservices. The main problem with microservices is the separation via the network, everything is distributed, failure is everywhere. Also with RPC and REST you have a very chatty network, it is very inefficient to build microservices this way. While both seem simple at first, it as after the initial ease that major pain sets in.
The one place I see use for RPC or REST in Microservices is between the users client and the Applications API Gateway interface. This is because the users browser is their client and it has the technology built in to retry failed requests etc. But for microservice to microservice communication RPC and REST are a bad idea, we need something different for this type of communication.
For service to service communication we need a way to asynchronously pass messages. Which leads to the next section.
Event Sourcing and CQRS
Event sourcing and CQRS are better ways for microservices to communicate.