This week, we discovered a great deal about a new method of structuring services in software architecture. Before week 6, the project that we had been working on had a monolithic architecture—i.e., the backend was one app where all the services (such as the registrar, gradebook, and any future features) were bundled together and run inside the same server.
On the other hand, this week we studied microservices architecture, where each service is developed and deployed independently, typically on its own server or container. Each microservice typically has its own database, but some services will have additional tables specific to the function of their purpose. There are several reasons why one would want to use a microservices approach, including increased scalability—because each service can be scaled independently as necessary—and fault isolation, in that if one microservice fails, it does not necessarily bring down the whole system.
Another basic concept of microservices architecture is inter-service communication. Since each microservice is a separate application and often on different servers or containers, it is not possible to use direct function calls or shared memory (as in monolithic applications). Microservices communicate over a network instead, using protocols like HTTP or gRPC. This is called inter-service communication. Services normally expose APIs—typically RESTful endpoints—other services invoke to pass or receive data. In more complex systems, communication is asynchronous and through message brokers like RabbitMQ or Apache Kafka, where services subscribe and publish events. Asynchronous messaging further decouples and allows services to continue working even when a part of the system is behind or temporarily unavailable. The decision between synchronous and asynchronous styles is use-case dependent, trading performance, reliability, and complexity. Funny enough, we got to work with RabbitMQ in our own assignment, and it was an absolute blast to directly program an implementation of service oriented architecture using our pre-existing monolithic project.
Another advantage of microservices is that they are technology-agnostic. Because each service is decoupled, developers can choose the most suitable programming language, framework, or database for the problem that service is trying to solve. This can lead to better productivity and performance, as teams are not forced into a single tech stack. For example, one can construct a Python-based machine learning microservice using TensorFlow in one instance, and a high-performance user authentication service in Go. Provided that services adhere to pre-defined communication protocols—e.g., REST or gRPC—they can coexist beautifully in the overall system. This autonomy also enables parallel development across teams along with simpler integration of future technologies down the line.
A real world example of microservice oriented software is Netflix, which was originally a monolithic app, just like our own project. Netflix runs hundreds of microservices today that do everything from video encoding, user recommendations, and billing. Each microservice is deployed separately, communicates with APIs, and can be scaled based on usage patterns. This allows Netflix to achieve high availability, deploy highly frequently without downtime, and continue innovating at high velocity. Their use of asynchronous messaging and advanced DevOps tools also solves the complexity involved in such a large microservices ecosystem.
No comments:
Post a Comment