Transition to microservices for a logistics company
Discover our approach to boosting the performance and scalability of software for a logistics company by shifting from a monolithic architecture to microservices.
About the client
Our client is a large US-based logistics company that handles transportation and warehousing management across the country.
Because of the company’s rapid expansion, their monolithic warehouse and transportation management software couldn’t correctly operate and scale in line with the company’s growth. However, the software was too large and complex to properly update it in a short period of time. To address this, Yalantis offered to shift from a monolithic architecture to microservices. These are some of the challenges we needed to solve through this transition:
- A huge amount of time was required to make changes to the product
- High software latency led to a loss of users
- Our client needed to manage an increasing number of microservices
- Memory leakage jeopardized the app’s proper functioning
Minimizing time spent on making changes to the product
Adding new features and making changes to the app required one to three months for testing and checks. We reduced the time required by:
- identifying logical parts of the system to turn into microservices
- separating microservices by technical characteristics
- deciding on the order in which to move parts to microservices
- adding WARs with microservices to Jetty, which is responsible for connecting servers to each microservice
Reducing software latency
To reduce the delay between an input and the desired output, our team replicated the entire database across multiple data centers. As a result, if one data center isn’t working properly, the system can switch to another and use its copy of the database.
Managing an increasing number of microservices
After implementing 20+ microservices, we faced the challenges with services data types compatibility and versioning. We also experienced difficulties deploying many WAR files in Jetty. It took us up to two hours to update all microservices, which was too long to meet our client’s requirements. To solve these issues, we:
- created client libraries (module APIs) for service controllers that helped to address data types compatibility and used the same call interface for client libraries and controllers
- shifted to a horizontal architecture, divided it across several data centers, and added a separate server for Elastic Stack with the Kibana user interface for collecting data by indexes and reducing demand for server resources
- deployed Redis as an intermediary between the database and server for events and user actions so that basic business features and their transactions don’t affect several servers simultaneously
- wrapped Kubernetes around the software to ensure easy scaling and the ability to shift from one cloud service provider to another if needed
- transformed the app to have a stateless architecture, enabling simple request sending and the creation of multiple database instances
Detecting and handling memory leaks
Our team faced a memory leak problem when subsystems took over and kept resources no longer used by the software. To avoid a fatal OutOfMemoryError, we:
- used native mechanisms of subsystems to avoid the out-of-memory condition
- ran the system using a custom JAR service with a scenario for detecting memory leaks
- handled memory leaks by using an out-of-memory killer, an established mechanism for recovering system memory
Our cooperation with the client resulted in the following:
Our client’s high-volume and fault-tolerant system has 40,000 registered users across various time zones and processes 200,000 transactions a day.
System updates take less than five minutes instead of two hours, and adding new services doesn’t affect other system modules.
The system allows developers to scale the app horizontally using different technologies, programming languages, frameworks, and libraries.
The microservices architecture within Docker allows for creating distributed development teams that can work independently on different parts of the software.
OPTIMIZE YOUR APP PERFORMANCE WITH A RELIABLE ARCHITECTURE
Yalantis will ensure high stability and fault-tolerance of your system with scalable and maintainable technology solutions