Background
The concept of microservices has gained significant traction in the information technology sector over the past few years. Following a thorough evaluation, we have decided to adopt a microservices architecture. Our upcoming presentation will provide an overview of our decision-making process, implementation roadmap, and valuable lessons we’ve learned along the way.
Initially, the software architecture of Works was “monolithic” and comprised a small number of web applications, each with its own database, and dedicated to specific business functionalities. For instance, we built a set of online applications that enabled streamlined processes for recruiting highly skilled software engineers, which included candidate identification, evaluation, and hiring.
As we expanded our application portfolio, we encountered three major challenges:
- Several applications shared similar core functionalities.
- Connecting data across different programs was challenging.
- Releasing new software versions took longer as the monolithic codebases continued to grow.
Instead of building a cohesive network of data-driven applications that align with our company’s operational model, we were developing disconnected, purpose-specific applications to fulfil distinct business requirements. To ensure scalability, we recognized the need to re-evaluate our current software infrastructure. After researching various design approaches, we came across an nginx blog article that convinced us to move towards a microservices architecture. We developed a compelling business case for this transition and initiated the migration process.
Execution
Before commencing the migration, we conducted a comprehensive evaluation of microservices. This entailed scrutinizing their benefits, drawbacks, and potential implications on our existing team culture and agile methodologies. Ikem Okonkwo was tasked with leading this investigation, and a core group of five developers was assembled to assist him. In this post, he outlines the conclusions of our research and the design decisions we made. Once we arrived at a consensus, we promptly formulated a plan and began executing it.
To ensure the successful launch of our new platform, our team initiated the process by creating microservices templates in various programming languages, shifting our hosting from Heroku to Google Cloud, configuring Kafka (a distributed streaming platform), establishing Kubernetes (a tool for managing servers and clusters), and setting up continuous integration (ConcourseCI). You can read more about the initial steps we took here.
Once we met our minimum infrastructure requirements, all of our feature teams started the process of migrating our products to microservices.
Outcome
Within a six-month timeframe, our team of fifteen diligent developers worked tirelessly to decompose five monolithic systems into thirty-five microservices. These microservices interface with our front-end applications through a central API Gateway, which has resulted in significant enhancements to the efficiency of our platform.
Key Learnings
Although the relocation process was challenging, we’re delighted to report that it went smoothly in the end. We’ve gained valuable insights that have helped us to continue expanding. Looking back, we’ve listed some of the things we should have considered prior to initiating the transition.
Learning Curve:
Developing distributed systems can have a major impact on team structures, as well as communication and collaboration practices. As a result, it’s crucial to shift our focus from building applications as a single cohesive unit to creating applications using modular, decentralized components.UUIDs:
Auto-incrementing integer identifiers may be simple to manage for a single entity, but they can present obstacles in a distributed environment. Therefore, we opted to use Universally Unique Identifiers (UUIDs), which have allowed us to efficiently track various business processes and establish relationships between them within our ecosystem.Starter Kits:
We have significantly accelerated the development process and streamlined the onboarding of new developers by employing starter kits. These kits feature boilerplate code that includes all of the necessary components for creating and deploying a new microservice.Automation:
By establishing a continuous delivery pipeline and automating the environment setup process, we have empowered our team to work with a high degree of autonomy in regards to developing, testing, and deploying code. This has allowed them to operate with greater efficiency and independence.Prioritize Speed:
As we moved our system to a new platform and continued to introduce new features, our organization engaged in a competitive process of constantly updating our existing codebase. To ensure a successful transition, it was crucial to complete the migration quickly. As a result, we enlisted a team of highly skilled engineers to expedite the relocation.
Despite encountering various obstacles, we firmly believe that our decision to migrate was the correct one. The insights we have gained from this process will continue to benefit our platform and software development practices. We are now better equipped than ever to quickly and efficiently make enhancements to our products, while continuing to provide constant value to the company.