Evolution strategies
This chapter discusses microservices as an evolutionary architecture and introduces popular patterns to be considered when building a microservices strategy. It also briefly describes how the strategies are implemented in the case study.
This chapter includes the following sections:
2.1 Microservices: An evolutionary architecture by nature
Architectures are usually created by following the predefined principles that help to reflect the strategic business goals of an organization. Business models tend to changed little, but in today’s environment, organizations want to enable a highly scalable business to serve a greater number of transactions and customers. They need to have flexible operational processes to reach new markets quickly and to be more innovative in existing markets. The common steady set of goals leads to a set of architectural principles that drive the way IT systems are evolutionarily architected, designed, implemented, and operated. One of the most important principles of an evolutionary architecture is the ability to support continual and incremental changes along multiple dimensions in both the technical and business domain spheres.
Traditional architectural elements of software tend to be difficult to change. This means that after decisions are made and components are designed and implemented, making changes to the architecture of the system is not easy. Some evolution has occurred in the way systems are architected with the introduction of more layered architectures and patterns to put those architectures in practice. Figure 2-1 shows an example of a typical layered architecture that enables system evolution.
Figure 2-1 An example of a layered architecture
With layered architectures, implementing changes at each layer without impacts on other parts of the system is easy. For example, if you want to change a component in the persistence layer, this change theoretically has little effect on the business and database layers and no effect on the presentation layer. This represents some level of evolution where the system has four opportunities to be evolved over time; each of the four separated layers can evolve. The evolution, however, is only enabled on one dimension: the technical aspect of the architecture.
When the business domain perspective is added into the architecture, there is no dimension for evolution for that perspective. Implementing changes in business domain can be difficult depending on the change requirement; changes in the business domain usually require touching on different modules or layers of the system. For example, making a change to the customer of the service that the system is serving, including related information and flow, is usually difficult. The difficulty arises because some parts of the customer are in the business layer, and other parts are scattered across the data layer, presentation layer, and other layers.
Microservices architecture is an evolutionary architecture by nature. One of its defining characteristics is that each service forms its own bounded context and is operationally distinct from all other services in the system. The technical aspect of the architecture is, for the most part, encapsulated entirely inside each service in the system. You can easily take one of the services out of the system and put another one into its place without impacting the other services. That is because of the highly decoupling principle that is part of the architectural style. Hence, there is more flexibility with microservices architecture. This flexibility supports an ability to evolve every service in the system.
Figure 2-2 shows an example architecture overview diagram of a typical microservices architecture. Note that API Gateway is not a mandatory requirement for a microservices architecture. It is beneficial, however, to have API Gateway to handle different API requests by routing them to appropriate microservices. If you do use API Gateway, design and implement it carefully to avoid coupling between services. Each microservice can have multiple micro components that might be separated into different layers. Figure 2-1 shows this type of microservice.
Figure 2-2 More evolvability dimensions in microservices architecture
2.2 Evolutionary practices and patterns
Having an evolutionary architecture is important in building a more flexible business model. This section discusses practices and patterns that can be used as enablers of evolutionary architecture.
2.2.1 Continuous integration, continuous delivery
Continuous integration (CI) is a software development practice in which developers of the software frequently integrate their work, usually daily, resulting in multiple integration times per day. The idea behind this preferred practice is to insulate potential integration problems as early as possible to solve problems that might occur. CI is backed by an automated process that includes building and testing activities to verify every build and detect integration errors quickly. Because potential issues can be isolated and caught earlier, CI helps to significantly reduce integration problems during development cycles and eventually helps to deliver products quickly.
CI is usually accompanied by continuous delivery (CD), which refers to continuously releasing every good build that passes tests into production. By adopting CI and CD, developers can reduce the time spent to fix bugs and increase the effort spent on developing new features or enhancing the existing ones. The adoption of CI and CD creates a higher business value impact.
CI and CD are powered by leveraging automation in every step of the development cycle, including creation of the infrastructure. Automation has evolved due to the availability and maturity of cloud technologies and CI and CD tools. Both CI and CD play a crucial role in the evolution of an architecture.
2.2.2 Strangler application
Martin Fowler introduced the term strangler application in his seminal article Strangler Application in 2004. In this pattern, a new system captures and intercepts calls to mature applications, routes them to other handlers, and gradually replaces them altogether. Rewriting the whole existing system from the first step is risky; the strangler application method reduces risks more than the cut-over rewrite approach. In moving from monolithic to microservices architecture, you can incrementally refactor your monolithic application. You gradually build a new application that consists of microservices; you then run this application together with the monolithic application. Over time, the amount of functionality handled by the monolithic application is incrementally decreased until either it disappears entirely or becomes part of the new microservices. Figure 2-3 on page 31 describes the transformation using the strangler application pattern.
Figure 2-3 Incrementally strangling an application
Using the strangler application pattern, the resulting architecture has both the earlier monolithic application and the new services. The architecture also has two other major components:
Dispatcher: This component works as a requests router that handles incoming requests by routing the requests corresponding to new functionality to new services. It routs previous requests to the existing monolithic application.
IC: These components reside in either the new services, the monolithic application, or both. They are responsible for integrating the monolithic application with the newly created services. You might not totally replace portions of the monolithic application; you might wrap them as a system of records that resides as a set of application programming interfaces (APIs).
One principle in an evolutionary architecture is to be well prepared for the unknown, that is, to be proactive rather than predictive about the movement in the future. Because of the natural evolution, what you build today becomes old and strangled in the future. Therefore, design the new application in such a way that a graceful fading away of the mature application occurs.
2.2.3 Evolutionary database refactoring and deployment
Often, a database (more specifically, data in the database) is the most important asset in an IT system. When your application is evolving, that asset must also be changed to be aligned with the application code changes. The database changes here include both database structural changes and data migration from the old structure to the new one. You might even have to consider moving between different types of databases. For example, moving some parts or the whole database from a relational database management system (RDBMS) to a NoSQL style. The refactoring and migration of data in that situation is even more challenging. Unfortunately, the traditional tools and processes for updating the database are not innovated and mature enough to keep up with the fast evolving pace in application development methodologies. This situation can be an obstacle for releasing the application rapidly.
A new approach to database change management and deployment that is powered by automation is required to make continual and incremental changes in an evolutionary architecture like microservices architecture. This section discusses several techniques as suggested practices to make database changes more evolved and aligned with application code changes. In their book Refactoring databases: Evolutionary database design, Scott Ambler and Promod Sadalage describe 13 lessons that might be used as guidance when building your database refactoring strategy. Those lessons provide the foundation for three steps of data refactoring: Decomposing big change into small changes, version controlling the changes, and automating database deployment.
Decompose big change into small changes
If you have a big database change to be applied, divide it into a smaller changes; make them small, individually testable changes. Each change is usually a combination of database structural change, data migration, and associated access code. In this way, you can quickly isolate any possible failure that the changes might produce in those small chunks and subsequently react and correct them. The purpose of this decomposition is also to map the database changes into application features that use the changes. This allows the modifications to be incrementally and continuously deployed altogether in the same agile process.
Version control the changes
Version control starts with organizing your database change scripts as necessary. Ensure that the change scripts are stored in the same repository as the application source code. Also ensure that you have the same directory structure and naming convention with the code. In this way, you can align the database changes with a particular application modification in a particular release that requires the changes. After the alignment is structurally in place, apply version control on the database change scripts. This process helps to facilitate the deployment of database changes and provides common ground for the database team as they coordinate and collaborate with other teams.
Automate database deployment
Automation is the key to managing and deploying evolutionary database changes. Ensure the alignment between the application code changes and the database changes are in place. Do this by applying the decomposition at the appropriate granularity, reorganizing the database changes script, and applying version control. When this is done, you are ready for a more evolutionary-enabled database deployment approach that is powered by automation. You then can adopt database deployment automation in a similar way with application code deployment by using agile CI and CD practices.
2.3 Evolutionary architecture in practice
This section describes how to apply an evolutionary approach to building a more flexible architecture that enables changes over time. The approach is demonstrated with a case study example application for Fictional Company A. Technical architectures are usually driven by strategic business needs. Chapter 1, “Overview of microservices” on page 15 describes the business requirements to help you start building an evolution strategy for the monolithic application.
The following basic steps serve as a guideline for the transformation:
1. Start the evolution strategy with product data: Customers are having trouble finding product data on their site. The goal is to make the data available and present it in a more interactive way. Moving data into an Elasticsearch database might provide customers the ability to do more powerful searches. This can be the starting point to build a new microservice on the cloud, so consider moving and migrating data to a NoSQL model, establishing new indexing, and deploying to a cloud environment. 
2. Continue with an account service by getting more information about the customer to personalize the content that is provided for them. This personalization can improve the customer experience. You can achieve this requirement by combining the existing customer data with social data, resulting in a potential new JSON-based data model.
3. Move part of the customer data to the cloud. Consider a hybrid cloud integration pattern to address the data synchronization issue between the earlier data source and the newly created data source.
4. Optimize the user interface (UI) layer to better serve users. Start with the supporting mobile platforms, then incrementally update the UI by using the microservices approach based on the new data model. 
5. Ordering is the last part to transform and move. You can start the transformation to microservices by putting a set of APIs around the current ordering component to add more flexibility and decoupling. This allows you to be ready for future steps.
2.3.1 Gradually transforming to a catalog service
Information about products that Company A provides is the core data set of the company’s business. Making the data reachable in the easiest and most interactive way possible to the customers is a critical factor in architecture success. Product-related components are good candidates to start the evolution strategy. Resulting artifacts might be a new microservice running in a cloud environment for resiliency and scalability. In this example, Catalog service is the name of the new service. Because the products logics are moved completely to the new microservice, data must also be gradually migrated to the same cloud platform. This eliminates any potential latency when the new service needs to make calls to the database for populating data.
Technologies for implementing the new catalog are numerous. However, in considering an evolutionary approach, also consider keeping the same technology stack that is used in the monolithic application, which is Java based, to avoid carrying big changes at the same time. The technology stack can be changed later in further steps based on business needs and the availability and maturity of a particular technology available in the market at the time that the architectural decisions are made. A cloud platform such as IBM Bluemix offers various options to quickly deploy the service code into a runtime instance. Data for the newly created Catalog service can also be kept in a relational database management model at first to avoid any big changes.
The next step is to migrate the data to a more modern lightweight NoSQL and JSON model to improve the search experience. Chapter 4, “Enterprise data access patterns” on page 51 describes data migration strategy and implementation.
2.3.2 Strangling the customer and order components
Business continuity is important to Company A, therefore, the transformation must be implemented carefully so that no interruption of services occurs during the transform process. To mitigate the risks of system down time, use a strangler application technique. Customer-related business components and data are decomposed and transformed into a more evolutionary new model, but the old components continue to be operated in parallel at the same time. The traffic to old customer and order components are incrementally moved to newly created services.
2.3.3 Evolutionarily transforming the user interface to a UI microservice
One of the business requirements of Company A is to expand the system to reach out to customers who use mobile devices. The customers in this context include existing and potential new customers. To fulfill the requirement, the following major steps are conducted as a guideline to transform the user interface to the microservices architecture:
Change the CustomerServiceDojo module to support mobile users and set a step toward a responsive design approach.
Use responsive design-enabled client-side libraries (for example, Bootstrap and Angular) to improve the user experience and make the UI more modular and easier to change.
Start moving the UI layer into the cloud environment for more rapid development, deployment, and adaptability to change.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.127.68