Een monolithische toepassing migreren naar microservices met behulp van een domeingestuurd ontwerp

ASP.NET

In dit artikel wordt beschreven hoe u DDD (Domain-Driven Design) gebruikt om een monolithische toepassing te migreren naar microservices.

Een monolithische toepassing is doorgaans een toepassingssysteem waarin alle relevante modules als één implementeerbare uitvoeringseenheid worden verpakt. Het kan bijvoorbeeld een Java-webtoepassing (WAR) zijn die wordt uitgevoerd op Tomcat of een ASP. NET-toepassing die wordt uitgevoerd op IIS. Een typische monolithische toepassing maakt gebruik van een gelaagd ontwerp, met afzonderlijke lagen voor gebruikersinterface, toepassingslogica en gegevenstoegang.

Een typische monolietarchitectuur

Deze systemen beginnen klein, maar hebben de neiging om in de loop van de tijd te groeien om te voldoen aan bedrijfsbehoeften. Op een bepaald moment, als er nieuwe functies worden toegevoegd, kan een monolithische toepassing beginnen te lijden aan de volgende problemen:

  • De afzonderlijke onderdelen van het systeem kunnen niet onafhankelijk worden geschaald, omdat ze nauw zijn gekoppeld.
  • Het is moeilijk om de code te onderhouden, vanwege een nauwe koppeling en verborgen afhankelijkheden.
  • Testen wordt moeilijker, waardoor de kans op het introduceren van beveiligingsproblemen toeneemt.

Deze problemen kunnen een belemmering vormen voor toekomstige groei en stabiliteit. Teams worden voorzichtig met het aanbrengen van wijzigingen, met name als de oorspronkelijke ontwikkelaars niet meer aan het project werken en ontwerpdocumenten schaars of verouderd zijn.

Ondanks deze beperkingen kan een monolithisch ontwerp zinvol zijn als uitgangspunt voor een toepassing. Monolieten zijn vaak de snelste weg naar het bouwen van een proof-of-concept of minimaal levensvatbaar product. In de vroege fasen van ontwikkeling zijn monolieten meestal:

  • Eenvoudiger te bouwen, omdat er één gedeelde codebasis is.
  • Eenvoudiger om fouten op te sporen, omdat de code wordt uitgevoerd binnen één proces en geheugenruimte.
  • Gemakkelijker te redeneren, omdat er minder bewegende delen zijn.

Naarmate de toepassing steeds complexer wordt, kunnen deze voordelen echter verdwijnen. Grote monolieten worden vaak steeds moeilijker om te bouwen, fouten op te sporen en te redeneren. Op een gegeven moment wegen de problemen zwaarder dan de voordelen. Dit is het punt waarop het zinvol kan zijn om de toepassing te migreren naar een microservicearchitectuur. In tegenstelling tot monolieten zijn microservices doorgaans gedecentraliseerde, losjes gekoppelde uitvoeringseenheden. In het volgende diagram ziet u een typische microservicearchitectuur:

Een typische microservicearchitectuur

Het migreren van een monoliet naar een microservice vereist veel tijd en investeringen om fouten of overschrijdingen te voorkomen. Om ervoor te zorgen dat elke migratie succesvol is, is het goed om inzicht te hebben in de voordelen en uitdagingen die microservices met zich meebrengen. Enkele voordelen:

  • Services kunnen onafhankelijk van elkaar worden ontwikkeld op basis van de behoeften van de gebruiker.
  • Services kunnen onafhankelijk worden geschaald om te voldoen aan de vraag van gebruikers.
  • Na verloop van tijd worden ontwikkelingscycli sneller naarmate functies sneller op de markt kunnen worden gebracht.
  • Services zijn geïsoleerd en zijn toleranter voor fouten.
  • Als één service mislukt, wordt niet de hele toepassing uitgeschakeld.
  • Testen wordt coherenter en consistenter met behulp van gedragsgestuurde ontwikkeling.

Zie Architectuurstijl voor microservices voor meer informatie over de voordelen en uitdagingen van microservices.

Domeingestuurd ontwerp toepassen

Elke migratiestrategie moet teams in staat stellen om de toepassing stapsgewijs te herstructureren in kleinere services, terwijl eindgebruikers toch de continuïteit van de service kunnen bieden. Dit is de algemene benadering:

  • Stop met het toevoegen van functionaliteit aan de monoliet.
  • Splits de front-end van de back-end.
  • De monoliet splitsen en loskoppelen in een reeks microservices.

Om deze ontleding te vergemakkelijken, is het toepassen van de principes van domain-driven design (DDD) een levensvatbare benadering voor softwareontwikkeling.

Domain Driven Design (DDD) is een softwareontwikkelingsbenadering die voor het eerst is geïntroduceerd door Eric Evans. DDD vereist een goed begrip van het domein waarvoor de toepassing wordt geschreven. De benodigde domeinkennis voor het maken van de toepassing bevindt zich in de mensen die de toepassing begrijpen: de domeinexperts.

De DDD-benadering kan met terugwerkende kracht worden toegepast op een bestaande toepassing, als een manier om te beginnen met het opsplitsen van de toepassing.

  1. Begin met een alomtegenwoordige taal, een gemeenschappelijke woordenlijst die wordt gedeeld door alle belanghebbenden.

  2. Identificeer de relevante modules in de monolithische toepassing en pas daarop de gemeenschappelijke woordenlijst toe.

  3. Definieer de domeinmodellen van de monolithische toepassing. Het domeinmodel is een abstract model van het bedrijfsdomein.

  4. Definieer gebonden contexten voor de modellen. Een gebonden context is de grens binnen een domein waarop een bepaald domeinmodel van toepassing is. Pas expliciete grenzen toe met duidelijk gedefinieerde modellen en verantwoordelijkheden.

De gebonden contexten die in stap 4 zijn geïdentificeerd, zijn kandidaten voor herstructurering in kleinere microservices. In het volgende diagram ziet u de bestaande monoliet met de begrensde contexten eroverheen:

Gebonden contexten binnen een monoliet

Zie Using domain analysis to model microservices (Domeinanalyse gebruiken om microservices te modelleren) voor meer informatie over het gebruik van een DDD-benadering voor microservicesarchitecturen.

Lijmcode gebruiken (anti-beschadigingslaag)

Terwijl dit onderzoekswerk wordt uitgevoerd om de monolithische toepassing te inventariseren, kan nieuwe functionaliteit worden toegevoegd door de principes van DDD als afzonderlijke services toe te passen. Met 'Lijmcode' kan de monolithische toepassing proxy-aanroepen naar de nieuwe service uitvoeren om nieuwe functionaliteit te verkrijgen.

 Code lijmen zodat een monoliet kan communiceren met een nieuwe service

De lijmcode (adapterpatroon) fungeert effectief als een anti-corruptielaag, zodat de nieuwe service niet wordt vervuild door gegevensmodellen die vereist zijn voor de monolithische toepassing. De lijmcode helpt bij het bemiddelen van interacties tussen de twee en zorgt ervoor dat alleen gegevens worden doorgegeven die nodig zijn voor de nieuwe service om compatibiliteit mogelijk te maken.

Via het proces van herstructurering kunnen teams de monolithische toepassing inventariseren en kandidaten identificeren voor herstructurering van microservices, terwijl ze ook nieuwe functionaliteit met nieuwe services tot stand brengen.

Zie Anti-corruptielaagpatroon voor meer informatie over anti-corruptielagen.

Een presentatielaag maken

De volgende stap bestaat uit het scheiden van de presentatielaag van de back-endlaag. In een traditionele n-tier-toepassing is de toepassingslaag (bedrijfslaag) meestal de onderdelen die de kern vormen van de toepassing en die domeinlogica bevatten. Deze grofkorrelige API's werken samen met de gegevenstoegangslaag om persistente gegevens op te halen uit een database. Deze API's vormen een natuurlijke grens met de presentatielaag en helpen bij het ontkoppelen van de presentatielaag in een afzonderlijke toepassingsruimte.

In het volgende diagram ziet u de presentatielaag (UI) die is gescheiden van de toepassingslogica en gegevenstoegangslagen.

API-gatewaypatroon

In dit diagram wordt ook een andere laag geïntroduceerd, de API-gateway, die zich tussen de presentatielaag en de toepassingslogica bevindt. De API-gateway is een gevellaag die een consistente en uniforme interface biedt voor de presentatielaag om mee te communiceren, terwijl downstreamservices onafhankelijk kunnen worden ontwikkeld, zonder dat dit van invloed is op de toepassing. De API-gateway kan gebruikmaken van een technologie zoals Azure API Management en stelt de toepassing in staat restful te communiceren.

De presentatielaag kan worden ontwikkeld in elke taal of elk framework waarin het team expertise heeft, zoals een toepassing met één pagina of een MVC-toepassing. Deze toepassingen communiceren met de microservices via de gateway, met behulp van standaard HTTP-aanroepen. Zie API-gateways gebruiken in microservices voor meer informatie over API-gateways.

De monoliet buiten gebruik stellen

In deze fase kan het team beginnen met het verwijderen van de monolithische toepassing en langzaam de services extraheren die zijn ingesteld door hun gebonden contexten in hun eigen set microservices. De microservices kunnen een RESTful-interface beschikbaar maken voor de toepassingslaag om via de API-gateway met lijmcode te communiceren om in specifieke omstandigheden met de monoliet te communiceren.

API-laag gebruiken

Als u de monoliet blijft verwijderen, komt er uiteindelijk een punt waarop deze niet meer hoeft te bestaan en de microservices met succes uit de monoliet zijn geëxtraheerd. Op dit moment kan de anti-corruptielaag (lijmcode) veilig worden verwijderd.

Deze benadering is een voorbeeld van het strangler Fig-patroon en maakt een gecontroleerde ontleding van een monoliet in een set microservices mogelijk. Na verloop van tijd, wanneer bestaande functionaliteit naar microservices wordt verplaatst, neemt de monoliet in omvang en complexiteit af, tot het punt dat deze niet meer bestaat.

Medewerkers

Dit artikel wordt onderhouden door Microsoft. Het is oorspronkelijk geschreven door de volgende inzenders.

Hoofdauteur:

Als u niet-openbare LinkedIn-profielen wilt zien, meldt u zich aan bij LinkedIn.

Volgende stappen

Wanneer de toepassing is opgesplitst in samenstellende microservices, wordt het mogelijk om moderne indelingshulpprogramma's zoals Azure DevOps te gebruiken om de levenscyclus van elke service te beheren. Zie CI/CD voor microservicearchitecturen voor meer informatie.