Microservices is an architectural style that gets a lot of attention nowadays. Most greenfield projects start with microservices. This article considers whether using microservices is always the right approach. In addition, this article describes how Axon’s evolutionary approach delays decisions and makes a solid platform for microservices.
What are Microservices?
Microservices is an architectural style that breaks a system’s logic into several (sometimes thousands) of small services. These services communicate with each other in order to achieve desired functionality. Defining the size of these services is usually a hard thing to do. A particularly bad practice is to decide the size based on the number of lines of code. Some define the ideal size as what you can (re)build in a single Sprint, but in our experience, a very effective way is to use a concept from DDD (Domain Driven Design) called Bounded Contexts. A Bounded Context is something that defines the boundary of certain subdomain within a domain. A single service should implement domain logic from within that subdomain. It bears resemblance to the Unix approach - do one thing and do it well.
Each service contains state which is stored in its own storage space. This way the service’s state is decoupled from other services. Services can be coupled through their interactions with other services. A consideration of how interaction works between services in the Communication Patterns chapter.
This chapter dives into some of the reasons why microservices are beneficial for building software systems.
Consider the UI layer from earlier chapters which communicates with server-side business logic that stores its state inside a database. This is relatively straight forward design. Some time passes and it’s discovered that the order functionality gets a lot of traffic and it needs to scale. The only way to do that is to spin up a new instance of the whole server-side component which contains a lot of other functionality that is not required to be scaled leading to resources not being used wisely. In general, scaling our services would mean that a lot of boilerplate code is required to plumb things together. Choosing the right infrastructural components would reduce the amount of boilerplate.
Changing shipment functionality requires a roll out the whole solution all over again.
Deployment cycle is slower because of this reason. In an agile environment, it is not desirable to hear the word slow.
The server-side component has one code base. Having a big team working on the same code base requires a lot of discipline and communication. Over time this will become such a substantial activity that you lose precious speed and agility. In microservices architectures, services have their own code base so they can scale work on several independent teams.
There are few extra bonuses to having a separate code base. It is possible to use different programming languages to program different services allowing the use the right tool for the job a.k.a polyglot programming. Storage technologies can be aligned with the type of data that the service is storing. This is called polyglot persistence.
Applying microservices architectural style from the beginning of the project may be a difficult thing to do. One of the main reasons for these difficulties is the separation of concerns - decoupling our domain into several smaller subdomains. If it is known how to do that from the beginning we can start right away with microservices. Usually, it is easier to start with a monolith and let the small services find their way out.
Axon helps us achieve exactly that - starting from the domain model and then implementing it in monolithic architecture. When one of the reasons mentioned in Why microservices chapter occurs, it is possible to decouple the subdomains in different services. You might think that this separation is hard, but Axon Framework is message-driven which enables loose coupling between subdomains. Having loose coupling and location transparency comes as a natural consequence and makes separation trivial. Axon Server gives an easy way to solve communication infrastructure between these microservices.
There are several different methods of communication between services in microservice architecture. Two important methods are: synchronous HTTP communication and asynchronous Message-Driven communication.
To achieve better location transparency and loose coupling, a desired approach is asynchronous Message-Driven communication between services. This approach requires an additional component, a Message Broker, which increases the system’s complexity. In large scale systems, message-driven communication is chosen more often than synchronous HTTP communication.
This article has considered what Microservices are and what benefits can be had by applying Microservices architecture style as well as discussing that starting right away with Microservices might be difficult. The evolutionary approach is something that we’ve seen from our experience as good practice. When it comes to communication, loose coupled message-driven systems work better in changing agile environments.
AxonIQ builds frameworks and tools to support the development of Microservices in an evolutionary way.
Sign up for email notifications
Sometimes we send information about new features in Axon, invitations to webinars or notifications about a new blog. Do you want to receive such an email form us?