What is a microservice? Simply put, microservices are a way of designing and building an application as a collection of small, independently running services. A single, monolithic application is much like a solitary animal in the wild—say, a polar bear—in that it needs all of its body parts to work exactly right, and to work exactly right as a single entity, in order to thrive. Microservices, by comparison, are like a beehive; each microservice has its own API and can be accessed and tested independently, and like the bees, having many small workers performing the same few simple interconnected tasks can be more productive than one powerhouse individual performing more complex tasks.
A traditional application may have been designed as a large codebase consisting of modules. A microservice takes those modules and separates them into individual microservices that each represents an area of responsibility—for example, login, search, ordering, and shipping. Each of those microservices communicates to another microservice via their APIs. Each service operates in a narrowly scoped domain and is designed to perform that one task very well.
Why would this be important?
If your application is built with microservice components, you don’t have a single point of failure—your entire application won’t crash because say, your login microservice isn’t working. When there is a problem, your developer can go in quickly, identify the issue, fix the problem, and get your application up and running. Additionally, microservices can be updated and deployed with minimal risk.
Horizontal scaling is an increase in the number of service instances to accommodate a larger number of users/transactions. For example, let’s say we have three instances of a login service running, but we experience spikes in usage on holidays like Black Friday and Cyber Monday. In preparation for the spikes, we might pre-scale up to 12 instances, and set it to auto-scale to up to 24 instances as needed. Now the login service can handle the increase in transactions without crashing and the business and customers are happy during those peak purchasing times. We can do this with microservices.
Loose coupling allows services to be less dependent on another service, which allows a service to be updated or replaced without affecting the other services. For example, a service could be implemented in a different way, in a different language, or with different internal technology, but because the external API stays the same, the functionality between microservice does not break.
Should everything be a microservice?
Not necessarily. Microservices are typically designed to do a specific job, like a stand-alone function. Microservices still typically work with and have dependencies on other non-microservices, like web servers, queues, caches, databases, and notification services. Microservices are an excellent choice for when scaling for larger volumes of transactions is important for the business; industries like financial services organizations social media, and online retail were early adopters of microservices.
While we love using them here at PVM, microservices are decidedly not ideal for every situation. They do have drawbacks in their design, but there are solutions to those challenges. Let’s explore a few—traceability, testing, and updates.
Traceability is the ability to follow a transaction through the system from start to finish. Microservices typically aggregate their logs into one place—so how would you trace this transaction? One solution is to introduce a trace ID that can then follow the transaction through its entire lifecycle. Sometimes, the microservices log information can feel overwhelming. But if you just tag and organize your logs appropriately, this doesn’t have to be an issue.
Furthermore, testing can require some retooling of your microservices. Along with the standard unit tests, regression/integration/end-to-end tests, and smoke tests, microservices can now be tested individually. The API functionality can be tested with tools like PostMan, Insomnia, and non-functional (performance) testing with tools like Apache JMeter.
Lastly, updates that are applicable for multiple microservices can mean performing the same change many times. One way to work more efficiently is to refactor the microservices to use a common library that can be updated apart from the microservices.
An advantage of microservices over a traditional monolithic application is that when changes to a non-microservice are made, the whole application must be redeployed, which runs the risk of crashing, errors, and delays. Changes to one microservice potentially mean just a localized change to that service and a much smaller and less risky redeployment.
Microservices at PVM
As a Palantir Preferred Provider, PVM is authorized to operate, maintain, and develop with Palantir Gotham and Palantir Foundry, which are built on microservice principles. As an Amazon Partner, PVM holds certifications in Foundation and Technical levels and can help you develop, build, deploy, and run your application with microservices.
One important resource worth mentioning for microservices developers is the Twelve-Factor App manifesto, developed at Heroku, an early Software-as-a-Service (SaaS) provider. They distilled the lessons they learned deploying apps to their platform and developed the 12 factors as principles to guide the design of new services. Our engineers at PVM use this manifesto on some projects and we’ve highlighted two guiding principles we commonly use below:
Factor 3. Configs are important to the build process. The manifesto describes a config as anything that is different between deployments. The Config factor states that microservices require "strict separation of config from code." This separation helps clearly communicate what is configured and prevents configuration values from being hard-coded in the source code —essentially, separating out the components so they don’t corrupt the source code.
Factor 11. The manifesto notes that all logs should show the app’s outputs and errors no matter how big or small the microservices are scaled. This centralizes the information and aggregates the data to be able to monitor it in real-time. Developers can then quickly see errors and outputs in one central place instead of digging through different storage disks for each service.
Are microservices a good fit for your organization? Do you see how they can potentially be implemented in some of your systems or applications? We hope so. If you want more information from our engineering experts, like Brian Jester, reach out today. We’d love to talk!