Houd in het ontwerp rekening met ontwikkeling
Een ontwerp dat rekening houdt met ontwikkeling is de sleutel voor continue innovatie
Alle succesvolle toepassingen worden na verloop van tijd gewijzigd, vanwege het corrigeren van fouten, het toevoegen van nieuwe functies en nieuwe technologieën of het robuuster en schaalbaarder maken van bestaande systemen. Als alle onderdelen van een toepassing nauw zijn gekoppeld, wordt het erg moeilijk wijzigingen in het systeem te introduceren. Een wijziging in een deel van de toepassing kan ander deel teniet doen of ervoor zorgen dat wijzigingen in de hele code worden doorgevoerd.
Dit probleem is niet beperkt tot monolithische toepassingen. Een toepassing kan in services worden ontleed, maar nog steeds zo nauw gekoppeld zijn dat het systeem star en fragiel blijft. Maar als services zijn ontworpen om zich te ontwikkelen, kunnen teams innovaties aanbrengen en voortdurend nieuwe functies leveren.
Microservices worden een populaire manier om een evolutief ontwerp te bereiken, omdat ze veel van de hier vermelde overwegingen aanpakken.
Aanbevelingen
Sterke samenhang en losse koppeling afdwingen. Een service is samenhangend als deze functionaliteit biedt die op een logische samenhangt. Een service is los gekoppeld als afzonderlijke services onafhankelijk kunnen worden gewijzigd. Een hoge samenhang betekent in het algemeen dat wijzigingen in één functie wijzigingen in andere gerelateerde functies vereisen, waarbij alle gerelateerde functies zich in één service bevinden. Als u merkt dat voor het bijwerken van een service gecoördineerde updates aan andere services zijn vereist, kan dat een teken zijn dat uw services niet samenhangend zijn. Een van de doelen van domeingestuurd ontwerp (DDD) is het identificeren van deze grenzen.
Bouw kennis van het domein in. Als een client van een service gebruikmaakt, dient de verantwoordelijkheid voor het afdwingen van bedrijfsregels van het domein niet bij de client te liggen. De service dient alle domeinkennis te bevatten die onder haar verantwoordelijkheid valt. Als dat niet zo is, moet elke client bedrijfsregels afdwingen. Het gevolg is dat de domeinkennis over verschillende delen van de toepassing verspreid raakt.
Gebruik asynchrone messaging Asynchrone messaging is een manier waarmee de berichtenproducent van de gebruiker wordt losgekoppeld. De producent is niet afhankelijk van de consument die op het bericht reageert of die een bepaalde actie onderneemt. Met een pub-/subarchitectuur is de producent mogelijk niet eens op de hoogte wie het bericht gebruikt. De berichten kunnen makkelijk door nieuwe services worden gebruikt zonder dat de producent hoeft te worden gewijzigd.
Bouw geen domeinkennis in een gateway in. Gateways kunnen in een architectuur met microservices nuttig zijn voor items als aanvraagroutering, protocolvertaling, taakverdeling of verificatie. De gateway moet echter worden beperkt tot dit type infrastructuurfunctionaliteit. Er mag geen domeinkennis worden geïmplementeerd om een sterke afhankelijkheid te voorkomen.
Maak open interfaces beschikbaar. Vermijd het maken van aangepaste vertalingslagen tussen services. Een service dient een API beschikbaar te maken met een goed-gedefinieerd API-contract. Het versiebeheer van de API moet worden bijgehouden, zodat de API kan worden ontwikkeld terwijl de compatibiliteit met eerdere versies wordt gehandhaafd. Op die manier kunt u een service bijwerken zonder dat u de updates voor alle upstream-services die ervan afhankelijk zijn, hoeft te coördineren. Openbare services dienen een RESTful API over HTTP beschikbaar te maken. Back-end-services kunnen omwille van de prestaties een messaging-protocol in RPC-stijl gebruiken voor betere prestaties.
Voer het ontwerp en de tests uit aan de hand van servicecontracten. Als services goed-gedefinieerde API's beschikbaar maken, kunt u deze op basis hiervan ontwikkelen en testen. Op die manier kunt u een afzonderlijke service ontwikkelen en testen zonder alle ervan afhankelijke services in gang te zetten. (Uiteraard voert u nog steeds integratie- en belastingtests uit voor de echte services.)
Gebruik fitnessfuncties. Fitnessfuncties meten het resultaat om te zien of deze zich dichter of verder van een optimale oplossing bevindt. Fitnessfuncties helpen bij het beschermen van architecturale kenmerken als er in de loop van de tijd veranderingen optreden. Fitnessfunctie is elk mechanisme dat een objectieve integriteitsbeoordeling van architectuurkenmerken biedt. De evaluatie kan verschillende mechanismen bevatten, zoals metrische gegevens, eenheidstests, chaos-engineering, enzovoort. De architect kan bijvoorbeeld de laadtijd van pagina's identificeren als een belangrijk kenmerk. Vervolgens moet de workload een fitnessfunctie hebben om de laadtijd van pagina's te testen en de test uit te voeren als onderdeel van continue integratie.
Isoleer infrastructuur van de domeinlogica. Voorkom een nauwe samenhang tussen de domeinlogica en infrastructuurgerelateerde functies, bijvoorbeeld messaging of persistentie. Anders kunnen wijzigingen aan de logica updates vereisen aan de infrastructuurlagen en omgekeerd.
Verplaats functies naar een afzonderlijke service om wederzijdse beïnvloeding te voorkomen. Als bijvoorbeeld aanvragen door meerdere functies moeten worden geverifieerd, kunt u deze functies in een eigen service onderbrengen. Vervolgens kunt u de verificatieservice ontwikkelen, bijvoorbeeld door een nieuwe verificatiestroom toe te voegen, zonder een van de services aan te raken die deze gebruiken.
Implementeer services onafhankelijk van elkaar. Als het DevOps-team één service onafhankelijk van andere services in de toepassing kan implementeren, kunnen updates sneller en veiliger worden uitgevoerd. Foutcorrecties en nieuwe functies kunnen regelmatiger worden uitgebracht. Ontwerp zowel de toepassing als het uitgifteproces ter ondersteuning van onafhankelijke updates.