What is Decoupling
There exists confusion what encompasses decoupling, but the definition is very straight forward: Decoupling is taking a functionality or set of functionalities out of an existing application, and making it completely independent that it can act and be developed on its own.
Decoupling is Evolution in System Design
Why is decoupling that popular now has a lot to do with how systems were designed and for what purpose. In the old days, systems were designed as large monolithic boxes where all functionalities, services and data were part of the same system. These mainframes were robust and rock-solid as the system foundations were optimized for that specific purpose to operate 24x7 and auto recover in case of failures.
The second generation of software design is where the focus was on efficiency and re-usability. Applications were developed in layers separating presentation, functionalities, integrations and data. Each layer has its own autonomy in its overall design and construction.
The advantage with these types of solutions is that common functionalities and data could be designed and developed separately with re-use in mind. But the disadvantage is that if one would change a small component, it still needs to test the dependencies in its layers above and below. For instance, one would like to update an integration component, this specific component is still dependent on data in the data layer and might affect how logic in the layer above works. So, for any small change, the architecture is still not agile as it needs to be tested and deployed as a larger unit still.
Still, this environment needs extra development and involves a careful review of data replication, synchronization and integration, but as the data is centralized, it is easier as it needs to synchronize only between the new and original database if necessary.
This pattern is the best recommendation when applications need to decouple large set of functionalities that are either complex and/or dependent on each other.
Example: Query product catalog, Sales quote, Product payment
With mainly the rise of the new internet platforms, it was shown that agility could still be part of large systems. The focus is to identify components that need agility or autonomy and isolate that specific component. This new component needs to be designed so that it has its own data and logic and in that way is independent of its mother application. With that, the Core still continues to work, and the new smaller functionality can be changed without relying on the larger system platform.
How to Decouple
To decouple functionalities out of an existing system, there are multiple patterns that can be used and the best way to explain decoupling is with number of examples. We take in this case an application that has a problem with 2 of in total 6 functionalities. The problem could be because of various reasons:
- low agility or flexibility (large system cannot be changed in production rapidly as system releases are large and cumbersome),
- bad robustness (component failure),
- low performance (slow response),
- low scalability (not able to handle more users or transactions),
- etc.
There are four main patterns to decouple as the diagram above shows:
1. Duplicate application
In this case, the original system is copied and duplicated completely, but only for the specific troublesome functionalities. Therefore, it can be changed rapidly without dependency on its main application. The functionalities are separated and no new development build is required.
However, as now we have 2 applications in place, this solution may be more costly due to dual licensing and additional required infrastructure. Also, it needs to consider and review data replication and synchronization and integration between the new copied application and its original system that could be more challenging in complexity and effort.
This scenario is recommended when cost is not an issue and the logic of the specific functionalities are very difficult to separate.
2. Isolate with Microservices
Another way to decouple is to isolate the services through microservices. One could separate the functionalities in autonomous services and provide independence and agility through this pattern with a much more cost-efficient solution that application duplication due to its small footprint of these services.
However, this scenario needs additional development to build the services. It also needs to have a careful review of the data replication, synchronization and integration as the new functionalities have its own data and may connect with data of its "mother" application. So, if a customer for instance changes her or his address in a newly built microservice, how can we ensure that the new address is updated in its original system. And for 2 components, it is already challenging the design, but with larger number of autonomous microservices, complexity will grow exponentially.
This pattern is recommended if only few functionalities are involved that are not too complex. If large number needs to be separated, it is better to use the next pattern.
Example: Show bank account balance, Login
3. Build Application
This scenario allows to build a small new application to isolate the badly performing services. This could still be achieved by using microservices, but within an application environment so that data is centralized and not stored within each microservice. Once a service needs to update data, it would write to the newly created application database. This guarantees that the specific functionalities are separated from its original system, and provides a more coherent and consistent architecture.
This pattern is the best recommendation when applications need to decouple large set of functionalities that are either complex and/or dependent on each other.
Example: Query product catalog, Sales quote, Product payment
4. Traffic Decoupling
The three patterns above are good alternatives to resolve problems. In all cases it is assumed that the traffic for the specific functionality goes to either the new or original system.
A sub pattern however, could be that to apply traffic decoupling. In this scenario, one would have a duplicated functionality (with either of the three mentioned patterns), but instead of directing functionality traffic to a specific system, it would direct specific volume or conditional traffic to one system and the remaining volume to the other system.
This could be for instance that a company knows that 90% of traffic is looking for the flight price between London and New York, and remaining traffic to query other flight prices. So the 90% traffic could be directed to the newly created system and be built very robust and scalable, while the remaining volume is handled by its original system. In this scenario, we can have the new system be optimized and tuned for performance and the original system can be alleviated due to less heavier traffic.
The disadvantages are that there needs to be built an hand-over once transaction is required in the new system as transactions may happen in both the new and old system. Once could limit this scenario that only queries are handled by new system.
And it is still more costly than original solution due to potential additional licensing and additional required infrastructure. It as in the other cases, it needs a careful review of data replication, synchronization and integration.
Best use for this pattern is when to alleviate heavy traffic volumes that affect the original system's performance.
Example: Query Flight price of most popular specific segments
Decoupling for BiModal IT
So decoupling can be used for various uses cases. It can be used for improving performance, robustness and scalability. But another important use is to provide higher agility of application platforms that are typically large and slow in deploying functionalities in production.
The case where we have slower large and complex systems and on the other side smaller and more agile applications is called BiModal IT. And decoupling facilitates the dual speed development of systems as it provides an interim layer that gives large applications an agility scale.
In Bimodal IT architectures, the first focus is where backend systems are maintained by large development teams that develop and release in large releases (that take several months if not years) once properly tested and proven. It leverages:
- waterfall methodology, and
- involves large development efforts. And there is
- high risk exposure and disruption to the company in case of system failures in these systems.
The second mode is centered on smaller teams that each have their own control of functionalities and components that can be released to production with rapid speed within days. It is focused on differentiating companies how it interacts with its customers to provide differentiating services from its competitors. And to do that, it needs to have extremely high agility that can translate business ideas into real working systems. It is based on:
- Agile Methodology,
- Frequent Smaller Releases,
- Small Effort,
- Less Risk exposure and little disruption to company in case of failure.
To ensure that both worlds can interconnect, it needs to decouple the required functionalities between both world from its original systems. It is an interaction layer that ensures that the agile world can change (decoupled) functionalities rapidly without being dependent on the larger company legacy system releases before.
Decoupling is always good?
So, once reading all this, one could discuss why not decouple my complete system landscape and convert all applications to decoupled smaller services. I have had that discussion with many company CIO and CTOs and the answer lies in taking a careful balance of optimizing your enterprise application landcape and complexity.
Benefits
The benefits of decoupling is that as it is completely autonomous, it has its own lifecycle. You can develop, test and deploy the decoupled component without any dependency on a larger application which is very beneficial for:
- Agility
As the microservice can be developed and deployed separately, it has its own speed and agility. One can quickly develop or change it and deploy it to production.
- Isolation of functionalities
Problematic parts of the application can be isolated and can be fixed and maintained while the larger application can continue without any change.
- Scalability and Performance
One can add more infrastructure resources to the specific microservice so it can act with better performance, without adding servers to the whole application
- Availability
The specific microservice can be implemented with higher availability than the other components, for instance 24 hours x 7 days, while the remaining part of the application has a lower availability to save on resources. As it can run autonomously it can be architected to have its own
- Agile methodology and team
Microservices is ideal for working with an agile cell as it acts on its own and canbe developed “independently” from other components.
Drawbacks
However, there are drawbacks as well as the use of microservices will help make the architecture more agile, it also becomes more complex due to:
- Architectural complexity
Each microservice is an autonomous component on its own and therefore the architecture relationship needs to be designed well to ensure it fits well with the other components. As the system becomes more distributed with microservices, it introduces an extra level of complexity due to more complex error handling, latency and network quality dependency, version control among other things.
- Lifecycle of microservices
As each microservice will have its own lifecycle, the versions need to be maintained well and a strong architectural governance structure is required to ensure that different versions of microservices will continue working correctly together as a whole.
- DevSecOps
As each service has its own autonomy in development and deployment, it needs a high quality DevSecOps implementation that supports the deployment, monitoring, operations, maintenance of each of these services.
- Data complexity
As data is spread over multiple microservices, data needs to be interconnected through relations, and overall data architecture and governance needs to be strengthened.
- Interoperability
Microservices are built by different teams and depend on interactions between them. Therefore it implies that there needs to be a very close engagement between teams to ensure specs are properly designed and built, not just during design, but also when changes are done later to avoid interoperability issues.
For only few newly added decoupled components, the system landscape can still be overseen. But for higher number of decoupling components, the complexity grows exponentially for its overall architecture, data quality integration and maintainability. In case of 2 newly created services, the potential number of replications and integrations between them and the original system is 3, but with 10 new services, this number could grows to 55 new integrations (see section about point-to-point integrations).
So, it is apparent that the decoupling strategy needs to be carefully decided to apply only where needed.
Therefore, a good architect needs to find the right balance how and how many microservices to use. The recommendation is to use a minimum of microservices and apply only where required.
For less complex applications, designs without decoupling is are always better in both the long and short-run. And for complex apps, decoupling may pay off over-time but it takes a long time to offset the additional integration and governance investment required to do it.
Key is to design a well-defined decoupled architecture rather than to decouple all components to avoid high complexity and maintenance problems in the future.
Read also more about decoupling in digital architectures.
No comments:
Post a Comment