Microservices zijn een populaire architectuurstijl voor het bouwen van robuuste, zeer schaalbare en onafhankelijk implementeerbare toepassingen die snel met veranderende vereisten kunnen meegroeien. Maar een geslaagde microservicearchitectuur vereist een andere benadering voor het ontwerpen en bouwen van toepassingen.
Een microservicearchitectuur bestaat uit een verzameling kleine, autonome services. Elke service is zelfstandig en moet één bedrijfsmogelijkheid binnen een gebonden context implementeren. Een gebonden context is een natuurlijke divisie binnen een bedrijf en biedt een expliciete grens waarbinnen een domeinmodel bestaat.
Wat zijn microservices?
Microservices zijn klein, onafhankelijk en losjes met elkaar verbonden. Een klein team van ontwikkelaars is voldoende om een service te schrijven en te onderhouden.
Elke service is een afzonderlijke codebasis, die kan worden beheerd door een klein ontwikkelteam.
Services kunnen onafhankelijk van elkaar worden geïmplementeerd. Een team kan een bestaande service bijwerken zonder dat hiervoor de hele toepassing opnieuw hoeft te worden gebouwd en geïmplementeerd.
Services zijn verantwoordelijk voor het persistent maken van hun eigen gegevens of externe status. Dit wijkt af van het traditionele model, waarin een afzonderlijke gegevenslaag de persistentie van gegevens afhandelt.
Services communiceren met elkaar via goed gedefinieerde API's. Interne implementatiegegevens van een service zijn onzichtbaar voor andere services.
Ondersteunt polyglotprogrammering. Services hoeven bijvoorbeeld niet dezelfde technologiestack, bibliotheken of frameworks te delen.
Een typische microservicearchitectuur bevat enkele andere componenten, naast de services zelf:
Beheer/indeling. Deze component is verantwoordelijk voor het plaatsen van services op knooppunten, het identificeren van fouten, het herverdelen van services over knooppunten, enzovoort. Dit onderdeel is doorgaans een kant-en-klare technologie zoals Kubernetes, niet iets dat op maat wordt gebouwd.
API-gateway. De API-gateway is het toegangspunt voor clients. Een client roept services niet direct aan, maar verstuurt een aanroep naar de API-gateway, die de aanroep doorstuurt naar de juiste services in de back-end.
Enkele voordelen van het gebruik van een API-gateway zijn:
Clients worden losgekoppeld van services. Services kunnen een nieuwe versie krijgen of worden geherstructureerd zonder dat alle clients hoeven te worden bijgewerkt.
Services kunnen berichtenprotocollen gebruiken die niet webvriendelijk zijn, zoals AMQP.
De API-gateway kan andere algemene functies uitvoeren zoals verificatie, logboekregistratie, SSL-beëindiging en taakverdeling.
Out-of-the-box-beleid, zoals voor beperking, caching, transformatie of validatie.
Vergoedingen
Flexibiliteit. Omdat microservices onafhankelijk van elkaar worden geïmplementeerd, is het eenvoudiger om het oplossen van problemen en het uitgeven van nieuwe releases te beheren. U kunt een service bijwerken zonder dat u de hele toepassing opnieuw hoeft te implementeren en u kunt een update terugdraaien als er iets misgaat. Wanneer echter een bepaald deel van een traditionele toepassing een fout bevat, dan wordt hierdoor vaak het volledige vrijgaveproces geblokkeerd. Nieuwe functies kunnen worden vastgehouden totdat een foutoplossing is geïntegreerd, getest en gepubliceerd.
Kleine, doelgerichte teams. Een microservice moet zo klein zijn dat één enkel functieteam deze kan bouwen, testen en implementeren. Inzet van kleinere teams stimuleert meer flexibiliteit. Grote teams zijn vaak minder productief: de communicatie verloopt langzamer, de managementoverhead neemt toe en de flexibiliteit juist af.
Kleine codebasis. In een monolithische toepassing is er een tendens in de loop van de tijd dat codeafhankelijkheden worden verward. Als u een nieuwe functie toevoegt, moet u op veel plaatsen code aanraken. Door geen code of gegevensarchieven te delen, bestaat er binnen een microservicesarchitectuur een minimum aan afhankelijkheden, waardoor het gemakkelijker wordt om nieuwe functies toe te voegen.
Combinatie van technologieën. Teams kunnen de technologie kiezen die het beste past bij de service waar ze aan werken en de combinatie van technologiepakketten gebruiken die zij het meest geschikt achten.
Foutisolatie. Als een afzonderlijke microservice niet meer beschikbaar is, wordt de hele toepassing niet onderbroken, zolang eventuele upstream-microservices zijn ontworpen om fouten correct te verwerken. U kunt bijvoorbeeld het circuitonderbrekerpatroon implementeren of u kunt uw oplossing zo ontwerpen dat de microservices met elkaar communiceren met behulp van asynchrone berichtpatronen.
Schaalbaarheid. De schaal van services kan onafhankelijk worden aangepast, dus u kunt subsystemen uitschalen waarvoor meer resources nodig zijn, zonder dat u de volledige toepassing hoeft uit te schalen. Met behulp van een orchestrator zoals Kubernetes kunt u een hogere dichtheid van services inpakken op één host, waardoor resources efficiënter kunnen worden gebruikt.
Gegevensisolatie. Het is veel eenvoudiger om schema-updates uit te voeren, aangezien het slechts één microservice betreft. In een monolithische toepassing kunnen schema-updates erg lastig worden, omdat verschillende onderdelen van de toepassing allemaal dezelfde gegevens aanraken, waardoor eventuele wijzigingen in het schema riskant zijn.
Uitdagingen
Er staat wel iets tegenover de voordelen van microservices. Hier volgen enkele uitdagingen waarmee u rekening moet houden voordat u kiest voor een microservicearchitectuur.
Complexiteit. Een microservicetoepassing bevat meer bewegende onderdelen dan de equivalente monolithische toepassing. Elke service is eenvoudiger, maar het systeem als geheel is complexer.
Ontwikkelen en testen. Het schrijven van een kleine service die afhankelijk is van andere afhankelijke services vereist een andere benadering dan het schrijven van een traditionele monolithische of gelaagde toepassing. Bestaande hulpprogramma's zijn niet altijd ontworpen voor gebruik met serviceafhankelijkheden. Herstructurering buiten servicegrenzen kan lastig zijn. Het testen van serviceafhankelijkheden is ook een uitdaging, met name wanneer de toepassing zich snel ontwikkelt.
Ontbreken van toezicht. Een gedecentraliseerde aanpak voor het bouwen van microservices heeft zo zijn voordelen, maar kan ook problemen veroorzaken. De kans bestaat dat er uiteindelijk zo veel verschillende talen en frameworks zijn dat het moeilijk wordt om de toepassing te onderhouden. Het kan daarom zinvol zijn om enkele projectbrede standaarden vast te leggen, zonder de flexibiliteit van teams te veel te beperken. Dit is vooral een goed idee voor algemene functionaliteit zoals logboekregistratie.
Netwerkcongestie en -latentie. Het gebruik van veel kleine, gespecialiseerde services kan resulteren in meer communicatie tussen deze services. Als de keten van serviceafhankelijkheden te lang wordt (service A roept service B aan, die C aanroept..), kan de extra latentie ook een probleem worden. U moet daarom zorgvuldig te werk gaan bij het ontwerpen van API's. Vermijd te veel chatieve API's, denk na over serialisatie-indelingen en zoek naar plaatsen om asynchrone communicatiepatronen te gebruiken, zoals load leveling op basis van wachtrijen.
Gegevensintegriteit. Elke microservice die verantwoordelijk is voor zijn eigen gegevenspersistentie. Als gevolg hiervan kan gegevensconsistentie tussen meerdere services een uitdaging zijn. Verschillende services behouden gegevens op verschillende momenten, met behulp van verschillende technologie en met mogelijk verschillende niveaus van succes. Wanneer meer dan één microservice betrokken is bij het persistent maken van een nieuwe of gewijzigde datum, is het onwaarschijnlijk dat de volledige gegevenswijziging kan worden beschouwd als een ACID-transactie. In plaats daarvan is de techniek beter afgestemd op BASE (Basically Available, Soft state en Eventually consistent). Kies waar mogelijk voor uiteindelijke consistentie.
Beheer. U hebt een goed ontwikkelde DevOps-cultuur nodig om succesvol te kunnen werken met microservices. Gecorreleerde logboekregistratie tussen services kan lastig zijn. Doorgaans moet logboekregistratie zo zijn geconfigureerd dat meerdere serviceaanroepen voor één gebruikersbewerking worden gecorreleerd.
Versiebeheer. Updates van een service mogen geen gevolgen hebben voor de beschikbaarheid van afhankelijke services. Het is mogelijk dat op een bepaald moment meerdere services tegelijk worden bijgewerkt, dus zonder een zorgvuldig ontwerp kunnen er al snel problemen ontstaan met achterwaartse of voorwaartse compatibiliteit.
Vaardigheden. Microservices zijn zeer sterk gedistribueerde systemen. Evalueer zorgvuldig of het team beschikt over de vaardigheden en ervaring om succesvol te zijn.
Proces voor het ontwikkelen van een microservicearchitectuur
De hier genoemde artikelen beschrijven een gestructureerde benadering voor het ontwerpen, bouwen en gebruiken van een microservicearchitectuur.
Domeinanalyse. Gebruik domeinanalyse om de grenzen van uw microservice te definiëren om enkele veel voorkomende valkuilen bij het ontwerpen van microservices te voorkomen. Volg vervolgens deze stappen:
- Gebruik domeinanalyse om microservices te modelleren.
- Gebruik tactische DDD om microservices te ontwerpen.
- Bepaal de grenzen van microservices.
Ontwerp van de services. Voor microservices is een andere benadering vereist voor het ontwerpen en ontwikkelen van toepassingen. Raadpleeg voor meer informatie Een microservicearchitectuur ontwerpen.
Werk tijdens productie. Omdat microservicearchitecturen gedistribueerd werken, moet u beschikken over robuuste procedures voor implementatie en bewaking.
- CI/CD voor microservicearchitecturen
- Een CI/CD-pijplijn bouwen voor microservices in Kubernetes
- Microservices uitvoeren in Azure Kubernetes Service (AKS)