A loosely coupled architecture is a software application development model wherein multiple components are connected with one another but are not heavily dependent on each other. Together, these components create a general network or system, despite each service being an independent entity created to perform a single task. In this blog, you will also learn about the debate between loosely coupled vs tightly coupled architecture.
The primary purpose of a loosely coupled architecture is to create a system that doesn’t fail due to the failure of a single component. Service-oriented architectures (SOAs) normally comprise a loosely coupled architecture.
Table of contents
- Benefits of Using a Loosely Coupled Architecture
- Example of a Loosely Coupled Architecture
- Loosely Coupled vs Tightly Coupled Architecture
- The Importance of Microservices in a Loosely Coupled Architecture
- Which AWS Services can be used for Loosely Coupled Architectures?
- Loosely Coupled Architecture Scenarios
- AWS Serverless Scenario with Loosely Coupled Architecture
- Conclusion
- FAQs
Benefits of Using a Loosely Coupled Architecture
Some of the benefits of using a loosely coupled architecture include greater scalability, improved maintainability, and increased extensibility. It also allows for more efficient development as changes to one component do not necessarily have to be reflected in other components. Additionally, it can also reduce costs by allowing components to be reused or replaced more easily.
Example of a Loosely Coupled Architecture
Consider an instance wherein you have created two classes in a program: A and B. When a method of Class A calls the method of Class B or uses variable instances defined in Class B, both classes are tightly coupled. However, when Class A depends on the interface of Class B instead of the methods defined in Class B, both classes are loosely coupled.
Above is an example of a food ordering app that uses a loosely coupled system. The app contains different services such as order service, restaurant service, delivery service and customer service. When a customer orders a food item, the order service takes care of processing it. The restaurant service receives this data and prepares the food while the delivery service handles the delivery part. Customer service assists customers when need be. In this case, each individual service is not heavily dependent on any of the other services. All services communicate via APIs in order to send and receive the required information. Therefore, when one service crashes, it can be instantly replaced without disturbing the other components of the app. Similarly, the order service can be automatically scaled during peak hours or seasons.
Loosely Coupled Architecture vs Tightly Coupled Architecture
Loosely coupled vs tightly coupled architecture is an important point to ponder. In the software development world, coupling refers to the dependency of an object on another. The degree of knowledge an object has about another or the level of dependency of one object on another determines whether the system is loosely coupled or tightly coupled. When the dependency level is low, we say it’s loosely coupled. Basically, this means one object knows what the other objects expose through an API. Similarly, two systems are loosely coupled when changes to one system don’t force a change in the other.
Each service in a loosely coupled system is designed with a single purpose or responsibility and can be independently deployed, managed, scaled and removed. Each service contains an interface (REST API) for communication. Seeing as each service can use a different programming language, platform, technology and framework, it’s easy to make changes to individual services, perform tests, scale services and remove them without affecting the system. The loosely coupled architecture accommodates extensive APIs and interoperable resource schemas decoupled from the interface.
On the other hand, objects in a tightly coupled architecture heavily depend on the other components of the system. Each object must collaborate and coordinate with other objects or components in order to complete a function. In this case, the logic of one class is called by another. This means one object or class requires another object or class to complete a task. Therefore, each class takes on multiple responsibilities, a change made to one class also forces a change in one or more other classes.
The Importance of Microservices in a Loosely Coupled Architecture
Microservices is an architectural design that facilitates the development of an application as small and independent services that run their own processes and communicate using lightweight protocols and messaging systems, making them platform-agnostic and language-agnostic. Each service is independent, testable, highly maintainable, independently deployable and implements a business capability. Most importantly, each service is maintained, deployed, created and owned by a small team. Microservices is a notable variant of a service-oriented architecture that leverages the loosely coupled architecture approach. In fact, loose coupling is the key component of microservices architecture.
Microservices architecture is highly important to create a loosely coupled system, as the coupling is inevitable in a software system design. For instance, in an e-commerce portal, the order service should communicate with the customer service or delivery service using APIs. That said, microservices best practices allow you to keep this coupling as minimal as possible.
Microservices comprise a set of collaborating services that work together using different coupling methods.
- Runtime Coupling: The degree to which the availability of one service impacts the availability of another service.
- Design-time Coupling: The degree to which a change in a service triggers change in another service.
- Infrastructure Coupling: The degree to which one service’s resource consumption impacts another service’s resource consumption.
Each coupling method brings its own challenges to the table. For instance, runtime coupling reduces availability when a change occurs. As such, you’ll experience a long queue of calls in a microservices architecture.
When you implement design-time coupling, a small change in an API requires all the services that interact with that API to be changed. Therefore, all of the teams involved with those services must collaborate and discuss the change. As such, it’s important to keep design-time coupling as loose as possible, especially when different collaborating teams are involved.
Microservices benefits make it easy to implement loose coupling in a design-time coupling model while enabling you to efficiently handle coupling challenges using lean development and DevOps CI/CD best practices.
Which AWS Services can be used for Loosely Coupled Architectures?
Amazon Simple Queuing Service (SQS) and Simple Notification Service (SNS) are powerful mechanisms that can help you build highly scalable and loosely coupled architectures, with coupling at the platform, network and operation levels.
- Amazon Simple Queuing Service (SQS): When a client makes an order, the app that receives that order sends it as a message to the SQS. The message is queued and consumed by a function such as AWS Lambda. Once the message is processed, it’s automatically deleted.
- Amazon Simple Notification Service (SNS): Works as a “publish-subscribe” model wherein the application sends order messages to an SNS topic which is then replicated across various endpoints in order to run processes in parallel.
- AWS Lambda: Serverless compute engine.
- AWS Fargate: Container as a Service for serverless computing.
- AWS AutoScaling: Autoscaling service.
- Amazon S3: Storage service.
- Amazon API Gateway: API management service.
- AWS CloudWatch: Used to manage messages in SQS.
Loosely Coupled Architecture Scenarios
Unlike tightly coupled architecture which runs thousands of parallel processes or cores that are dependent on one another to perform a calculation, loosely coupled architecture runs smaller jobs in large numbers on a single node with parallelization occurring within the node. As processes are not highly dependent on each other, losing one node doesn’t affect overall functionality. The job is either processed later or deleted.
It’s important to consider the following aspects when choosing a loosely coupled architecture.
- Compute: The underlying EC2 instance type should be determined based on the memory-to-compute ratio of an application.
- Network: Bandwidth and latency issues are not a concern in a loosely coupled scenario, as processes that run in parallel don’t need to interact much.
- Storage: Each loosely coupled app comes with a different storage requirement. Therefore, consider the dataset size and data transfer requirements.
- Deployment: Seeing as loosely coupled apps run on cores installed in different availability zones, they can be efficiently deployed using AWS ParallelCluster or AWS Batch.
AWS Serverless Scenario with Loosely Coupled Architecture
Serverless computing is a cloud-native software development approach that helps organizations easily and seamlessly build and run applications without the burdens of provisioning and managing servers. Servers are still used but are managed by the cloud vendor. The catch here is that the charge is not based on the number of servers or the bandwidth but rather on usage. It enables organizations to purchase back-end servers on a pay-as-you-go basis and only pay for the services used.
Serverless computing comes in two models:
- Function as a Service: A service that allows you to run code based on events without the complexities of infrastructure management. Applications run in a stateless mode wherein the server and client are loosely coupled and hence are independent, flexible, scalable and fault-tolerant.
Regarding compute engines, AWS Lambda is a popular serverless FaaS tool from AWS. For container-based workloads, AWS Fargate is available. For event triggering, we recommend using Amazon SQS, AWS SNS and Eventbridge.
- Backend-as-a-Service: The task of running the server-side logic is outsourced to a cloud vendor. AWS BaaS tools include Amazon Elasticsearch Service for logging, AWS Kinesis for analytics and AWS Cognito for IAM.
There are three types of serverless invocation methods:
1) Synchronous Invocation: Used when a client request requires an immediate response.
2) Asynchronous Invocation: Used when you don’t want the client to wait for a response and instead alert the client through a notification once the process is completed.
3) Steaming Invocation: Used to upstream, process and downstream data at the same pace.
When it comes to serverless computing, loosely coupled architecture with an asynchronous method is a good choice. That said, don’t forget to ensure it is fail-fast and fans out properly.
This blog is also available on DZone
Conclusion
Software technologies rapidly change, forcing organizations to adapt to newer technologies and trends continually. When it comes to loosely coupled vs tightly coupled architecture, information flow and coordination between services are better in a tightly coupled architecture. However, they constrain you regarding flexibility when making changes to your apps on the go. A loosely coupled architecture is the need of the hour. Not only does it allow you to swap or scale components instantly, but it also helps you add new features without affecting the availability and performance of the existing system. With microservices, lean development and DevOps practices, a loosely coupled architecture allow you to stay in the competition or even ahead.
FAQs
Amazon SQS is the most important AWS service holding the key to managing a loosely coupled architecture. By decoupling cloud application components, SQS helps you facilitate seamless communication between services in the system.
Amazon SQS uses a standard queue by default, therefore, allowing unlimited transactions per second. This ensures that a message is delivered at least once.
First In First Out (FIFO) is the other queue type used by messaging systems in a loosely coupled system. The order in which the messages are sent is the same as the order in which the messages are delivered.