Pitfalls & Challenges Faced During A Microservices Architecture .

Transcription

Cognizant 20-20 InsightsCognizant Digital Systems & TechnologyPitfalls & Challenges FacedDuring a MicroservicesArchitecture ImplementationMicroservices are the de facto design approach for building digitalapplications. However, issues highlighted in this paper can and do lead toimplementation challenges and even failures. Here are a few strategiesto avoid and overcome them.Executive SummaryOrganizations across industries are at various stagesof their journey toward adopting a microservicesarchitecture style.1 Some have been successful indelivering real business benefits, while others arestill experimenting.While the benefits delivered by a microservicesarchitecture such as agility, selective scalability andavailability still hold true, we are dismayed by the variousFebruary 2020suboptimal implementations of microservicesarchitectures that have emerged since our initial takeon the topic.2This white paper provides readers with guidance onfundamental design decisions required to properlyimplement a microservices architecture to realize all thebenefits available to organizations willing to takethe plunge.

Some teams tend to think of the “micro” in microservices asa lever to design smaller-scoped systems, while others think ofmicro as the lever to deploy and operate manageable systems.Microservices architecture pitfallsA large number of the teams developing systemsbased on microservices architecture havesome form of experience in service-orientedarchitecture (SOA) that was heavily influencedby the middleware vendor products such asenterprise service buses (ESBs) or Web standardssuch as Simple Object Access Protocol (SOAP) andWeb Service.While SOA experience helps in developingservice-oriented thinking, we have found that thisbackground can also have a negative influence,resulting in pitfalls such as sub-optimal granularityof service, representational state transfer (REST)only mindset, excessive service calls (chattyservices) and database as shared resource mindset.Continuous technological improvements havecaused some teams to fall into a technology-onlythinking trap, causing even more complexity whenthese systems experience high-volume productiontraffic. These pitfalls manifest in multiple forms.(Read on to see what we have observed acrossprojects.)The “micro” in microservicesarchitectureApplication architects have struggled with thegranularity dilemma for a long time. What’s theright level of granularity for a system component2/to be scoped? How we can maximize reuse fora system component or service in its functionalform? Basically, identifying the right boundariesand granularity are two of the biggest challengesfor a solution designer, especially as the selectiondepends greatly on the domain and context of thesolution space.Application developers using microservices styleface similar challenges. Some teams tend to thinkof the “micro” in microservices as a lever to designsmaller-scoped systems, while others think of microas the lever to deploy and operate manageablesystems. We see three major variations of this issuein microservices scoping (see Figure 1, next page). Entity scope: Data entity-oriented designtends to cause inflexibility at the individualmicroservices layer and change complexity atthe overall system level. Process scope: Designing microservices at thislevel of granularity tends to result in fragile andvolatile services. Utility scope: The notion of utilities treatedas microservices causes the provisioning ofoperational sophistication without reapingadequate business benefits since suchutilities are often non-differentiating to mostenterprises.Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsMicroservices granularity tificationIssue policyUTILITYAddresschangeProcessclaimFigure 1While all granularity levels are expected to beserved in a system, the main benefits of sucharchitecture design can easily be missed; that is,balancing agility (speed of change) with resiliency(safety of change). Two issues are typicallyobserved:microservice designers must pay close attentionto the context-dependent interactions thatthe microservice needs to participate in. Thisrequires the designers to think in terms of looselycoupled, event-oriented boundaries and thecontext mapping. It’s difficult to get business buy-in to theprogram that’s delivering such services.The database monolith Operational complexity increases without realbenefits.Finally, as IT organizations embrace a systemparadigm across all non-trivial business domains,event-oriented collaboration patterns havebecome a mainstay of such microsystemarchitecture design. These pitfalls tend to become abig bottleneck that thwarts event-oriented thinkingon the journey toward evolutionary system design.To avoid these pitfalls, IT organizations must ensurethat no microservice is designed without an explicitalignment and traceability with business capabilityof the domain, as advocated by bounded contextstrategy of domain-driven design. 3 In addition, the3/Microservices adoption moved quickly from anemerging concept to the de facto design patternfor application architecture. However, as with anyover-hyped technology, the design patterns andbest practices were not very well established andunderstood, which led to poor implementations.Among the major obstacles are large databasesused as a persistent store for many -- or all -- of themicroservices. This database can lead to a monolithat the data persistence layer, resulting in severalchallenges such as: Performance bottlenecks. One of the keydrivers for microservices architecture is theability to scale horizontally and dynamically.Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsQuick TakeAdvancing Innovation & Timeto Market in Consumer LendingOne of our APAC clients in the consumer lending domain that wanted to enableinnovation and improve speed-to-market transformed a single monolithic application intomicroservices with little or no focus on the design aspect of microservices.The result was 500-plus microservices with extreme complexity leading to performancebottlenecks due to chatty inter-service communication.We have recommended a domain-driven rationalization to address this situation. This notonly helps address performance challenges, but also ensures evolution of the applicationin a completely autonomous manner.However, with a monolithic database, the scalingof microservices puts additional load on thedatabase, creating a performance bottleneck. Coupling between microservices.Microservices architectures offer agility in thatthey are loosely coupled and independentlydeployed. However, if multiple microservices aretied to the same tables in the database, then anychange in the schema will result in cascadingchanges in other microservices, which defeatsthe core purpose of microservices.There are many reasons we have seen that lead tothis anti-pattern; two key ones are risk aversenessto move away from the monolithic database anddatabase designers who are not fully skilled innewer patterns like microservices, leading totraditional database design.If multiple microservices are tied to the same tables inthe database, then any change in the schema will result incascading changes in other microservices, which defeats thecore purpose of microservices.4/Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsTo avoid these pitfalls, IT organizations mustensure that the database design complements themicroservices by following best practices: Database per service in a no-share model.Each microservice needs to have full ownershipof the data it requires. This does not mean aseparate physical database but ownership of thedata it masters. Polyglot persistence model. Making arelational database a default storage of all typesof data leads to poor results, hence all types ofdatabases (e.g., NoSQL, Graph, in-memory, etc.)must be used. Adopt CQRS pattern to use read replicas.Command query response segregation (CQRS)is an architecture pattern but it can be appliedto microservices database design to answer thebiggest question: Can data be shared betweenmicroservices? Break distributed transactions with a sagapattern.4 The division of database objects intogroups of logical schemas in bounded context ofthe wider transaction boundaries require multiphase commits. Avoid this with saga patternsthat keep intermediate states.Quick TakeOvercoming CentralizedDatabase ShortcomingsOne of the new cloud-native features of a consumer lending solution implemented in puremicroservices style was undermined by a single centralized relational database.This design led to the database becoming a performance bottleneck and hindrance tosystem scalability and resilience.We addressed this issue by refactoring the database into multiple domain-centric physicalinstances with microservices-based logical separations. This allowed domain-basedisolation, which enabled resiliency, scalability and performance improvements.5/Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsBreaking the data monolith through bounded context and polyglot designMS 2MS 1MS 1Full accessFull accessMS 2MS 3Read onlyShared tableNoSQLRDBMSGraphIn-memoryPOLYGLOT DESIGNMS1 bounded contextMS2 bounded contextFigure 2The REST compulsionThe microservices architecture grew during thedecline of traditional SOA. As most of the traditionalSOA was built on HTTP-based SOAP, the naturalevolution for microservices was to expose itsfunctionality through HTTP-based REST services.The pitfall here is that most developers considerHTTP REST as the default way to expose thefunctionality of a microservice rather thanconsidering asynchronous messaging alternatives.This leads to various challenges of performance andcomplex transaction management.The key reasons why HTTP REST is used as thedefault for microservices implementation: REST API has become very popularand developers are comfortable with itsimplementation. Reactive services need additional messaginginfrastructure to implement besidesmicroservices, which is not generally available.To avoid these pitfalls, we recommend the followingbest practices as shown in Figure 3 (see next page). Understanding the distinction between APImicroservices and core microservices. Duringthe microservices design, there should be aclear distinction between API microservicesthat expose their functionality to the externalworld against core microservices that are usedby other microservices. The core microservicesshould be implemented on a reactive pattern. Developer awareness of reactive systemarchitecture is key. Developers shouldunderstand reactive system architecture andassociated benefits such as responsive andresilient microservices. Most developers are not experienced in reactivepatterns and hence avoid implementing servicesbased on asynchronous messaging.6/Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsQuick TakeOvercoming REST ChallengesOne of our large banking clients has implemented a core platform that offers bothmessage-based and service (REST) interfaces. However, in pursuit of REST-onlyintegration, the company implemented a REST interface on top of messaging thatresulted in interface complexity, transaction losses and latency issues due to the increasedprocessing pipeline and number of components engaged.This is now addressed by offering APIs as either messaging or services. Inter-servicecommunication is now being handled through messages directly across components,helping with both loose coupling and high reliability.Reactive microservices andintegrationOverall, while REST is a very useful protocolto expose functionality for microservices,indiscriminate use can lead to challenges that canbe avoided by using asynchronous patterns.Chatty servicesMS1 APIMS 2 APIEvent busA chatty application is one that relies on numerousservices to fulfill a request or a process. Inmost cases, chattiness is a result of designingmicroservices that are too fine-grained and breakthe bounded context and independent businesscapability principle.While calling other services to fulfill a request isoften considered as normal and acceptable, chattyservices incur numerous overhead such as:Reactivemicroservice 1Reactivemicroservice 2Reactivemicroservice 3For any microservices-based implementation, thearchitecture should have a provision for core messaginginfrastructure. For more complex architectures, a moreelaborate event bus architecture should be considered.Figure 37/ Network latency, disk reads, database queries,etc. on both the calling service and the servicebeing called. Runtime dependency between themicroservices, resulting in a distributedmonolith. All dependent microservices need tobe available and operational at the same time.Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsQuick TakeEmbracing an Event-DrivenArchitectureA large bank had embarked on a transformation program to modernize its paymentlandscape using a microservices architecture style.A centralized service orchestration model was implemented for payments processingthat led to chattiness between orchestrator and functional services. This affected bothlatency and throughput of the platform. Additionally, the orchestrator became a scalabilitybottleneck for the system.Our recommendation was to consider an event-driven architecture and implement longrunning processes using service choreography since it results in a highly scalable andperformant design due to loose coupling and non-blocking. Testing, which can become challenging as all thedependent microservices need to be available.If such issues are observed, then first revisit themicroservices design to ensure that the essentialprinciples of domain-driven design havebeen followed.It is also worth analyzing the dependency on othermicroservices. If the dependency is on the dataprovided by another microservice, then the IT teamshould consider replicating that data to avoid theremote call. This also allows the service to transformand store the data in a way that is optimal for a givenmicroservice. Additional benefits result beyond anavoided remote procedure call. For example, withincustomer management and know your customer(KYC) bounded contexts, a customer snapshotremains persistent, which avoids the need for aremote call. See Figure 4.8/Sharing data across stomer managementbounded contextFigure 4Pitfalls & Challenges Faced During a Microservices Architecture ImplementationKYC bounded context

Cognizant 20-20 InsightsLoose coupling through asynchronous communicationCustomerserviceKYCservicePublish: InitiateKYC eventConsume: InitiateKYC eventEvent busFigure 5In some cases, one microservice might need to callanother microservice to trigger the business logicit contains. In these situations, one service cannotavoid communicating with the other, but theIT team can implement it as efficiently as possiblevia asynchronous communication protocols(see Figure 5).Technology-only thinkingWhile designing microservices, we often seedevelopment teams acting in complete isolationwith business stakeholders. IT teams tend tothink that once the business has provided itsproject requirements, design is an IT-only activityand sub-system decomposition, and definingmicroservices and release mechanisms are thetechnology team’s agenda. This turns out to bea major shortcoming in projects where businesssubject matter experts (SMEs) are not involved in9/microservice design systems that are misalignedwith business objectives. In addition, the evolutionof these microservices tends to be influenced bythe technologists.In the majority of cases, this snag is a result ofproblems on both sides. The business thinkstopics like microservice design are too “techie”and thus believes it has no role to play. IT thinksbusiness doesn’t have any useful know-how tocontribute to microservices design and thusshouldn’t be invited/consulted. System designerscreate application boundaries that do not alignwith the business capabilities and the experiencedesign that the business requires. The result:the microservices identified for such projects donot reflect the business domain (both problemand solution) and instead are filled with technicalservices.Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Our experience suggests that, more than technology, it’s the cultureand systems thinking that influences how well we deal with thesepitfalls in microservices-based systems.To avoid this pitfall, solution architects must play amajor role. They need to ensure that business has aseat at the table while designing microservices andboth business and IT are able to offer reasons aboutdesign for delivery, lifecycle management andevolution of business capability in scope.Another major issue in this category tendsto be rooted in the accelerating evolution oftechnology. Every few months (sometimes evenweeks) a new shiny technology is released byvendors who talk up their use of microservices.While continuous technology evolution is agood thing, it tends to stimulate interest in thetechnology by business and IT teams, who steertheir project in this direction without reallyunderstanding the implications.An example is Docker and Kubernetes.Statements like “We are designing ourmicroservices using Kubernetes” or “Theseperformance problems will now be gone as weare structuring our system as microservices onDocker” are becoming commonplace. We believethis pitfall is one of the biggest issues facingmicroservices adoption today.Technology is a strong enabler to getmicroservices right, but that’s not the endgame.Teams should not let these technologies steertheir efforts toward microservices. Once theyhave designed the right level of microservicesthat are aligned to the business being automated,technology innovation should be used to deliverthe promise of high quality and agility. Some ofthe areas where microservices will really benefitfrom technology evolution include elementssuch as automated deployment, release, scaling,secure communication, high performance,availability, monitoring and provisioning. Infact, our experience suggests that, more thantechnology, it’s the culture and systems thinkingthat influences how well we deal with thesepitfalls in microservices-based systems.Confronting the challengesA microservices implementation is no easy taskand there are many challenges that test a team’sabilities.While the pitfalls can be attributed to speedof change and a lack of perspective (this is justnew SOA technology), there are some genuinechallenges that teams face while adopting themicroservices architecture style.Although some of these challenges are relatedto how systems are designed, others concern10/how these systems are operated and managed inproduction. For example, architects and developersat one of Europe’s major banks, whose operationspivot around a large mainframe and database-richlandscape, had a hard time grasping the designof business-aligned microservices using domaindriven design.In another case, one of our clients implementeda series of microservices but had a hard timeachieving production stability of these servicesPitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 Insightsor obtaining a good view of service integrationacross applications. In addition, we observed thatteams faced real challenges in terms of people skillsand capabilities and teams have spent substantialefforts and money to carry out workforce re-skilling.We’ll look at intricacies of these challenges next. Architects or technologists always considerdata as the most important thing and use adata-centric view when modeling a problemdomain. Without logic, the data is meaningless.Hence, architects and technologists shouldstart with context (business capability) and logicinstead of data.Design challenge At times, UI screens are used as guidelinesfor identifying data ownership and serviceboundaries. User interface (UI) doesn’t helphere as data matters only when it is involvedin some business logic – not when it is justdisplayed.Organizations struggle consistently withmicroservices design challenges such asdetermining the optimal boundaries between themicroservices, size of microservices, integrationbetween microservices, etc. Microservicesarchitecture design challenges include: The team only consists of IT specialists ortechnology architects. Defining capabilityaligned service boundaries requires domainexperts. Fundamentally, this should be acombined exercise independent of technologyused. There is a tendency to focus on databasetransactions instead of business transactionsor business processes. Focus should be on realworld processes, such as actions, their outcomesand compensating for the failed actions iffailures occur. A properly designed boundedcontext modifies only one aggregate instanceper transaction.Quick TakeGoing Domain DrivenOne of our clients faced challenges in correctly modeling the microserviceaggregate – the cohesive core model of any microservice. The team fell into a trapof designing for compositional convenience and the resulting aggregates were toolarge, with data consistency problems.We recommended a domain-driven design approach to discover the aggregates ina business operating construct aligned with boundaries called bounded contexts.This approach resulted in a domain-aligned, coherent model with true invariantsthat addressed the data consistency problems.11 /Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsQuick TakeA Decoupling ApproachOne of our financial services clients faced outages on its online portal as result of resourcestarvation by a system performance monitoring solution. The agents on the tool exhaustedresources required for business logic processing, causing the portal to go down.Not isolating the system software from business software was one of the reasons for thefailure, and detecting and isolating it was a difficult job.The recommendation to decouple the system policy concerns from functional softwarewas applied through proper runtime-decoupling to resolve this issue. Additionally, themonitoring and resiliency test practices were enhanced to detect such dependenciesthrough DevOps continuous integration/continuous delivery (CI/CD). Developer-centric terms such as create, read,update and delete are too technical and haveno specific business meaning. The team mustalways think from the business’s point of view,and give a clear context to it. Building a large organization’s system ofmicroservices is difficult and requires buildinga view, context by context. A starting point forrepresenting a system of microservices can be acontext map. Consistent use of unambiguous languageis missing, which leads to a lack of domainunderstanding. The technical and businessobstructions in the language may not discoverthe vital concepts hidden or assumed by domainexperts. For example: a customer enrolls usinga social profile. “Enroll” here has a technicalor business obstruction because of variousquestions about issues, such as what happensduring enrollment? Is the customer enrolled forany product/s or is the customer enrolled only tocreate his or her profile?12 /Resiliency challengeMicroservices bring a host of benefits – primarilyenhanced operational agility; however, amicroservices implementation increasescomplexity by its decomposition of applicationfunctionality into many independent deployableunits. One challenge that emerges with thiscomplexity is of resiliency due to the followingfactors: The distributed nature of request processing.In a microservices environment, most requestsare processed by multiple microservices, whichincreases the dependency on network andinfrastructure services, thus increasing theprobability of failure. Challenges in failure detection. In a traditionalmonolithic system, failures are simple to detectdue to fewer probable causes and failure ofapplication as a whole. In a microservicesenvironment, the failure can be of many causessuch as the microservice itself, the containerPitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 Insightsit is running on, and the network that isinterconnecting the microservices. Recovery after failures. As the failure usuallyresults in complex intermediate states, it isoften difficult to recover from. While respectivemicroservices can be restarted, the transactionsthat were in-flight must be recovered from theirfailure state, which is often difficult.Some strategies that we have found helpful toaddress the challenge of resilience in a distributedmicroservices environment include: Observability as a key architecture concern.For a microservices environment to be highlyresilient it needs observability implemented ateach level (i.e., infrastructure and application).The capability to log, monitor and trace requestsacross the network is key to providing resiliency. Design for recoverability more than failures.While any well-implemented system is definedfor failures, it is recoverability more than failuresthat address the concern of resilience. Theapplication should have the ability to recoverfrom a failure automatically at the container(e.g., restarting a container), a microservice (e.g.,reinitiating a connection pool) and applicationstate level (e.g., maintaining consistent stateafter recovery). Design for idempotency. One of the keyfeatures to be implemented at the microservicelevel to enable flawless recovery is idempotency.Idempotency is the feature to retry the samerequest without impacting the state. Withidempotency, each of the inflight transactionscan be retried without compromising the overallsystem state. Delegation of intercommunication to aservice mesh. While some of the microservicesimplementations use patterns like a circuitbreaker, in any complex microservicesbased application circuit breaking is notenough. Implementation of a full-servicemesh (e.g., Istio5) or simpler side car proxy(e.g., Envoy6) can take away the complexity ofintercommunication.In summary, resiliency is a big challenge inmicroservices-based applications and unlessdedicated architecture and design focus is given,the desired outcomes will not be achieved.Complexity challengeComplexity reduction through well-definedbounded contexts and communication patternsis one of the critical benefits that microservicesprovide. If done right, microservices offer excellentsupport for autonomous evolution of businesscapabilities. Typically, such microservices are alsobusiness-capability driven and therefore act asthe common vocabulary used by both business andIT teams, resulting in effective evolution of businesscapabilities.Complexities introduced by microservices YOPERATIONALCOMPLEXITY Design approaches Runtime infrastructure Scalability & performance Implementation guidance Runtime dependencies Runtime monitoring Frameworks and libraries Environment parity Container technology Integration and data Deployment automation Lifecycle management Build, integration & testing Release strategies Security & resilienceFigure 613/Pitfalls & Challenges Faced During a Microservices Architecture Implementation

Cognizant 20-20 InsightsHowever, microservices come in systems, whichmeans that often any non-trivial enterprise systemtends to have dozens or hundreds of these systems(each developed as a microservice). As eachof these systems are narrowly focused, singlepurpose microservices, any business process oruser interaction tends to result in invocation andinteraction of multiple microservices, resulting inchallenges across multiple phases of projects:Development complexityMicroservices development requires teams tothink in terms of distributed application designand interaction patterns. Applying concepts suchas CQRS, functional interfaces, CAP,7 BASE,8 andsagas9 in contemporary programming languagesand configuration is not something that developersare used to.Moreover, this is a new area of complexity for manyteams. Data persistence and integration requiresthem to not just understand aspects such as polyglotpersistence,10 persistence ignorance11 or eventdriven messaging,12 but also poses challenges interms of frameworks, libraries and programminglanguages to choose from.Finally, how to build and generate these polyglotmicroservices as a coherent whole through thecomplex continuous integration/continuousdelivery (CI/CD) pipeline is a major concern thatmany teams must overcome. Last but not least,testing microservices is still an evolving area andposes a major challenge to the majority of teams.Delivery complexityWith the advent of CI/CD and automatedinfrastructure provisioning through APIs,deployment and release practices have evolved overthe last few years. In addition, the use of containersand managed cloud environments in the platformas-a service (PaaS) model requires teams to workwith constructs provided by these technologies/services.While developing microservices in this environment,deployment and release is typically coded in theform of YAML or JavaScript Object Notation (JSON)scripts and these artifacts have become a first-classcitizen of the code repositories for microservices.Technology diversity, a lack of standards and aplethora of agility-oriented release mechanisms(canary release, blue-green deployment, push-to-Quick TakeGoing ServerlessIn one of our serverless microservices-base

microservices. This database can lead to a monolith at the data persistence layer, resulting in several challenges such as: Performance bottlenecks. One of the key drivers for microservices architecture is the ability to scale horizontally and dynamically. Microservices granularity levels. Figure 1. Issue policy Address change Process claim Email