What are the are most important things for developers to know when it comes to microservices application development? Many organizations migrate to microservices for one reason: Agility. The ability to quickly create and modify components in a way that offers bottom-line business value is mission critical in a world where your competitors are a click away and time to market is everything. However, you, a developer in your organization, also know that performance of your operational systems matters and no matter how agile microservices allow your team to be you are tasked with both delivering quickly AND ensuring the operational system can perform under peak load. To achieve both agility and performance many development teams are embracing the use of event-driven microservices. So, what do you need to know to be successful?
In a nutshell, you need to know:
*Note: This blog post was recently updated on July 7, 2020*
Capitalizing on the benefits of microservices application development within your enterprise requires a broader understanding of messaging patterns for event-driven microservices and when to use them.
Using messaging to communicate between microservices allows you to realize these benefits:
To learn more details about these benefits, I suggest you read this blog post.
It has been more than 20 years since Peter Deutsch and James Gosling developed the 8 fallacies of distributed computing, but these eight false assumptions are still made today by developers new to distributed applications.
All eight fallacies are relevant, but I’ve bolded the ones that are especially important in the world of microservices application development, because the smaller you make each microservice, the larger your service count, and the larger the service count, the more these fallacies will impact your stability and user experience/system performance.
The challenge is that microservices require connectivity/data in order to perform their roles and provide business value, and data acquisition/communication has been largely ignored, so much so that the tooling has severely lagged behind. For example, API management/gateway products only support synchronous, request/reply exchange patterns, which when coupled with the fallacies noted above, exacerbates the challenges of distributed computing. Many of these challenges can be minimized by properly implementing event-driven architecture.
Unlike service-oriented design, which are synchronous and blocking, event-driven design is non-blocking and uses lots of callbacks. Event-driven design is not a new concept, and you may even be familiar with it from using programming patterns such as the reactor pattern or the observer pattern. The concepts used by these programming patterns can be applied to event-driven microservice architectures using architectural patterns, such as publish-subscribe, to achieve service decoupling, independent scalability, and one-to-many bi-directional communications.
The first step towards adopting the event-driven mindset is to change the way you think about designing and architecting solutions. Initially the tendency is to think about all interactions between services as a series in a sequence of request/reply service calls. In fact, if you or your team uses the terminology of “invoking,” “requesting,” or “calling” then it is a sure sign you are still thinking in the request/reply paradigm.
Instead, try these: “What events should my service process?” and “What events will my service emit?”
Once you adopt event-driven thinking, you need to make the shift from orchestration to choreography. It is common for developers to think in terms of “service A will call service B which will call service C” and then implement that model through a chain of invocations (a->b> c) or by creating an orchestrator service such that x->a, then x->b, then x->c. Both approaches will cause chaos when the realities of distributed computing kick in, especially when you start to scale.
The alternative is to follow the philosophy of choreography. Services should react to changes in their environment and the benefits are immense:
This list of benefits doesn’t come for free; there is no silver bullet…
Consistency of state then becomes an area of focus, because a service, being temporarily down, means that the event state changes may not be processed immediately. Fundamentally, how do we deal with this negative side effect?
Eventual consistency is the idea that consistency will occur in the future, and it means accepting that things may be out of sync for some time. It’s a pattern and concept that lets developers avoid using nasty XA transactions. It’s the job of the eventing/messaging platform to ensure that these domain change events are never lost before being appropriately handled by a service and acknowledged.
Some think the only benefit of eventual consistency is performance, but the real advantage is the decoupling of the microservices since individual services are merely acting upon events that they are interested in.
As a developer, you want the ability to easily write clean code which enables you to deliver functionality quicker. Thus, the development language and associated tooling becomes important. While event-driven architectures allow us to decouple our microservices and choose different technologies to implement each one it is recommended to choose a standard language/framework that best fits your team’s skill sets and deviate only when necessary.
For many development team, their skill set usually includes experience using the Spring framework with Java (and other Spring-supported, JVM-based languages). This experience has led to Spring Boot becoming the most popular framework for microservices application development in organizations. Its adoption continues to grow and best of all, it has built in support for event-driven microservices through Spring Cloud Stream.
Spring Cloud Stream is a framework for building highly scalable, event-driven microservices connected using shared event brokers (a Solace binder is available here). On top of providing an implementation framework, Spring Cloud Stream also defines vendor agnostic terminology for the event-driven community, including defining source and sink applications that send or receive events over channels.
As discussed earlier, one of the benefits of choreographing your microservices using an event-driven architecture is to achieve less service coupling. But this benefit introduces some challenges of its own. Specifically, when your producers and consumers don’t care about the existence of each other it can make it challenging to model your architecture at design time and even harder to understand what events are flowing where at run-time.
Attempts to solve this challenge have been made in many different ways by many different organizations, but until recently there hasn’t been an all-encompassing solution available to the masses. The introduction of the Solace PubSub+ Event Portal solves these challenges by allowing you to visualize, manage, and choreograph your microservices at design time and providing features that allow you to discover, audit and secure your run-time environments.
Read more about Why Developers Need an Event Portal, where I walk through the steps I took to create consistent and scalable microservices within minutes.
While event-driven microservices may seem difficult initially, they are the future of most microservices and IT strategies. Become a ninja at their development by following these steps and make your life easier and simpler!