Dela via


Design för utveckling

Utvecklingsdesign är nyckeln till ständig innovation

Alla framgångsrika tillämpningar förändras med tiden – det kan handla om att åtgärda fel, lägga till nya funktioner, införa nya tekniker eller göra befintliga system mer skalbara och elastiska. Om alla delar i en tillämpning är nära sammanlänkade blir det mycket svårt att införa ändringar i systemet. En ändring i en del av programmet kan bryta en annan del eller orsaka ändringar i hela kodbasen.

Det här problemet är inte begränsat till monolitiska program. En applikation kan brytas ner i tjänster, men ändå uppvisa den typ av nära koppling som gör systemet stelt och skört. Om tjänsterna i stället utformas för vidareutveckling kan teamen förnya och skapa nya funktioner kontinuerligt.

Mikrotjänster blir ett populärt sätt att uppnå en evolutionär design, eftersom de tar upp många av de överväganden som anges här.

Rekommendationer

Säkerställ hög sammanhållning och lösa kopplingar. En tjänst är sammanhängande om den erbjuder funktioner som hänger samman logiskt. Tjänsterna är löst kopplade om en tjänst kan ändras utan att påverka den andra. Hög sammanhållning innebär i allmänhet att ändringar i en funktion kräver ändringar i andra relaterade funktioner, där alla relaterade funktioner finns i en tjänst. Om du upptäcker att uppdatering av en tjänst kräver samordnade uppdateringar av andra tjänster kan det vara ett tecken på att dina tjänster inte är sammanhängande. Ett av målen med domändriven design (DDD) är att identifiera dessa gränser.

Sammanfatta domänkunskap. När en klient använder en tjänst ska ansvaret för at framtvinga affärsreglerna för domänen inte ligga på klienten. I stället ska tjänsten kapsla in all kunskap om domänen som ligger på tjänstens ansvar. Annars måste varje klient framtvinga affärsreglerna, och resultatet blir att domänkunskapen sprids över olika delar av tillämpningen.

Använd asynkrona meddelanden. Asynkrona meddelanden är ett sätt att frikoppla meddelandeproducenten från konsumenten. Producenten är inte beroende av att konsumenten svarar på meddelandet eller vidtar någon särskild åtgärd. Med en pub/sub-arkitektur kanske producenten inte ens vet vem som tar emot meddelandet. Nya tjänster kan enkelt förbruka meddelanden utan att det medför några ändringar för producenten.

Bygg aldrig in domänkunskap i en gateway. Gatewayer kan vara användbara i en arkitektur med mikrotjänster för funktioner som routning av begäranden, översättning av protokoll, belastningsutjämning eller autentisering. Gatewayen bör dock vara begränsad till den här typen av infrastrukturfunktioner. För att undvika att den blir alltför beroende bör den inte implementera någon domänkunskap.

Exponera öppna gränssnitt. Undvik att skapa anpassade översättningslager mellan tjänster. En tjänst bör i stället exponera ett API med ett väldefinierat API-kontrakt. API-gränssnittet ska vara versionsbaserat, så att du kan utveckla det med bibehållen bakåtkompatibilitet. På så sätt kan du uppdatera en tjänst utan samordna uppdateringar för alla överordnade tjänster som är beroende av tjänsten i fråga. Offentliga tjänster ska exponera ett RESTful-API via HTTP. Backend-tjänster kan använda ett meddelandeprotokoll i RPC-format av prestandaskäl.

Designa och testa mot servicekontrakt. När tjänster uppvisar väldefinierade API-gränssnitt kan du utveckla och testa mot dessa API-gränssnitt. På så sätt kan du utveckla och testa en enskild tjänst utan att alla dess beroende tjänster berörs. (Naturligtvis kan du fortfarande utföra integrerings- och belastningstester mot de verkliga tjänsterna.)

Använd träningsfunktioner. Träningsfunktioner mäter resultatet för att se om det är närmare eller längre bort från en optimal lösning. Träningsfunktioner hjälper till att skydda arkitektoniska egenskaper när ändringar sker över tid. Fitnessfunktion är en mekanism som ger en objektiv bedömning av integritet av arkitekturella egenskaper. Utvärderingen kan innehålla en mängd olika mekanismer, till exempel mått, enhetstester, kaosteknik och så vidare. Arkitekten kan till exempel identifiera sidinläsningstiden som en viktig egenskap. Därefter bör arbetsbelastningen ha en träningsfunktion för att testa sidinläsningstiden och köra testet som en del av kontinuerlig integrering.

Abstrakt infrastruktur separat från domänlogiken. Blanda inte samman domänlogiken med infrastrukturrelaterade funktioner för exempelvis meddelanden eller beständighet. Annars kräver ändringar i domänlogiken att även infrastrukturlagren uppdateras, och tvärtom.

Avlasta övergripande frågor till en separat tjänst. Om flera tjänster till exempel måste autentisera begäranden kan du flytta funktionen till en egen tjänst. Sedan kan du utveckla autentiseringstjänsten , till exempel genom att lägga till ett nytt autentiseringsflöde, utan att röra någon av de tjänster som använder den.

Distribuera tjänster oberoende av varandra. När DevOps-team kan distribuera en enskild tjänst oberoende av andra tjänster i tillämpningen kan uppdateringar genomföras både snabbare och säkrare. Felkorrigeringar och nya funktioner kan lanseras i jämnare takt. Utforma både tillämpningen och lanseringsprocessen så att oberoende uppdateringar underlättas.