Scaling Microservices Part 4 - Shared Library
Systems consisting of many services, with network calls in between, will ultimately experience performance and scaling issues because of chatty or slow service calls. Various methods and patterns can be used to solve these performance issues. In this part, we will explore how a shared library can help.
What Is a Shared Library?
A Shared library is a class library that exposes functionality and data through public classes, methods, and properties instead of a service like a REST API. Shared libraries give a significant performance benefit since the functionality is called in-process instead of an out-of-process network call.
How to Distribute a Shared Library
A shared library is usually packaged and distributed through a package manager. If .NET is used, it would be a NuGet package. If the code should be public and open source, it would be distributed through nuget.org. If it's closed source and only for internal use, it should be distributed through an internal package feed within your organization like Azure Artifacts.
What to Use It For
If you are having performance issues with any of the service types below:
- Services that have a chatty interface that requires multiple service calls.
- Services that require a large request payload or response payload.
- Services that offer static or computed dynamic data.
It might help to move this functionality to be exposed through a shared library instead.
A shared library can also provide cross-cutting concerns functionality across all the microservices, like logging, authentication, authorization, code infrastructure for internal- and external communication through messaging and APIs, etc. Though, the details of this are not the main focus of this article.
- Very fast, no network latency.
- The consumers don't have to manually generate service contracts or make the code API since the shared library provides these out of the box.
- When the logic in the library changes, the library must be updated, distributed, and all the components must be updated to use the new version of the library. This is time-consuming and can, at worst, lead to an extended service downtime. If a service were consumed instead, it would always use the latest version if it's backward compatible.
- Services like REST API-s are platform agnostics; shared libraries are not. A shared library must be made for the technology platforms in use. If .NET and Java are used, a shared library must be created and maintained for both platforms.
You can have a hybrid approach for a given microservice. Some operations can be exposed through services like REST, and some can be exposed as a shared library. Exposing it through a service should be preferred since it allows for easy rollout to all consumers.
It's critical to have a setup that allows for easy and fast rollout of new versions of the shared libraries to prevent extended service downtimes in case of critical bugs in the shared library. This can be solved in different ways:
- Automatically create new pull requests with the updated library references to the different microservice repositories.
- Define the build process to always get the latest minor version of the shared library packages.