In this article, I am going to summarize my learning while working at Uber and building Uber's software foundation for micro-services.
The software evolution from monolithic architecture to microservices reflects a paradigm shift in development strategies. Initially, a monolith encapsulates the entire application, limiting scalability and flexibility. Developers then modularize components to ease management, marking the transition to a service-oriented architecture (SOA). The subsequent move to microservices involves breaking down the application into independent, deployable units, enhancing scalability, and enabling agile development.
Certain organizations adopted a foundation of microservice architecture from the outset, while others made the transition from a monolithic structure. In rapid development scenarios, developers frequently neglect the fundamental layer of these microservices and construct them using the language, framework, or libraries they are most accustomed to. This tendency leads to fragmentation in the foundational layer and poses challenges for the organization as it progresses and matures.
During my time at Uber, I had the opportunity to design the foundational layer for the Java backend software.
Goals
Improve developer productivity Assign the responsibility of managing the infrastructure aspect of backend software to a specialized team, freeing up engineers working on product-focused software from this concern. Eliminate redundant tasks to save development hours, offer straightforward scaffolding, and furnish developers with a standard toolkit for seamless software debugging. Establish a dedicated team to concentrate on these efforts.
Improve code quality Establish guardrails within the foundational framework to guide developers toward adhering to best practices in software development. As the infrastructure team, define opinions on how certain common tasks should be executed; for instance, establish guidelines on the specific metrics that backend software should emit when handling RPC requests.
Standardization Every Java backend software seamlessly interfaces with various infrastructure components, including metrics, logging, tracing, service discovery, databases, and messaging, in a standardized and efficient manner.
Centralized levers For example, Enable the infrastructure team to centrally update shared components, such as the HTTP server and serde libraries.
I had the distinct privilege of spearheading the formation and leadership of the team for this initiative at Uber. This strategic investment, generously funded by Uber, yielded remarkable returns. Leveraging open-source Java Dependency Injection, we meticulously crafted the bedrock of this foundational software, significantly accelerating our development endeavors.
Learnings.
Not every engineer possesses familiarity with the infrastructure aspects of the software. As an illustration, consider tasks like configuring my server's thread pool or setting up the logging library to produce structured logs.
Clean Dependency Injection (DI) saves lots of work in large scale software. In a componentized infrastructure, streamlining the interconnection of components through Dependency Injection(DI) saves considerable time and effort.
Centralized infrastructure control is helpful - In the event that I need to identify all the services employing version X of component Y.
Developer productivity is important - Empowering developers to concentrate solely on business logic, ensuring a consistent appearance for your backend software, and simplifying integration with in-house services accelerates development and yields significant returns.
Being opinionated as infrastructure team is important - As the infrastructure team, our responsibility is to advocate for and enforce best practices that align with the organization's interests. Adopting a firm stance on how certain aspects should be implemented in software is crucial, ensuring that our recommendations prioritize what is best for the overall organization.
Results
We received an abundance of positive feedback from developers, including emails, one-on-one messages, and survey results, regarding this foundational software.
Lots of money saved- "Clearly evident is the substantial conservation of CPU and memory through optimized resource utilization, translating into significant financial gains for the organization. A considerable amount of developer hours has been preserved through the centralization of common layers, increased dev-productivity.
Implementing cross-cutting changes are exceptionally straight forward—such as upgrading the version of the gRPC library.
Gradually, all software, including those developed before the introduction of this foundation, embraced the new platform and expressed satisfaction.
The successful design and swift implementation of this project proved to be a significant triumph for both the Uber infrastructure team and my own team.
Top comments (1)
Well written and obviously a good decision to choose micro-services. I should also think about micro-services in some of my projects. Thanks for the inspiration.