16 mars 2020 · 19 min läs
foto av National Cancer Institute på Unsplash
tillväxten av mikroservice adoption har orsakat en återuppkomst i popularitet av några tidigare förbisedda mjukvarudesignmönster. Många av dessa mönster har utvunnits från Eric Evans Domändriven Design, En bok som handlar lika mycket om lagstruktur som om mjukvaruarkitektur.
och av dessa mönster är det begränsade sammanhanget kanske det viktigaste att förstå. Som ingenjörer har vi kommit att betrakta det begränsade sammanhanget som ett designmönster för mjukvaruarkitektur. Men det beror på att vi har adjungerat det lite från dess ursprungliga användning. Som används av Evans är det begränsade sammanhanget lika mycket ett organisatoriskt mönster som det är ett tekniskt.
därför har jag kommit för att se det begränsade Kontextmönstret som en lynchpin för att förstå mikrotjänster. Inte bara hur man bygger dem, men verkligen varför vi bygger dem i första hand, och hur de kan göra våra organisationer mer framgångsrika. Om vi förstår vad avgränsade sammanhang är — om vi antar den avgränsade Kontextinriktningen både tekniskt och organisatoriskt — kan vi verkligen lyckas med att bygga vår mikroservicearkitektur.
varför flytta till mikrotjänster?
för att börja, låt oss utföra en liten övning. Ställ dig själv den här frågan: Varför bygger vi mikrotjänster i första hand?
ta en stund att tänka på det. Vilka är fördelarna som först kommer att tänka på? Vilka är de största problemen vi borde hoppas lösa? Skriv ner några svar, bara för att hålla dig ärlig.
…
har du ditt svar? Bra. Läs det tillbaka till dig själv. Fick du de vanliga tekniska fördelarna? Kontinuerlig leverans, skalbarhet, polyglot miljöer, behållare och moln, och allt det bra grejer? Stor.
men innehöll ditt bästa svar något om att göra det möjligt för din organisation att fungera mer effektivt? Det borde det. Eftersom att bygga mikrotjänster inte handlar om att förverkliga tekniska fördelar. Det handlar verkligen om att få organisatoriska fördelar. Allt annat är en implementeringsdetalj.
Monoliths = kopplad kod och kopplade lag
När våra monoliter blir större och större börjar produktiviteten minska. Det finns minst två huvudorsaker till det.
att sätta bromsarna på vår hastighet
först bidrar varje ingenjörsteam till en jätte kodbas. Som sådan står lag inför en ständigt växande Sannolikhet för att deras kod kommer att strida mot andras kod. För att mildra de potentiella problem som detta kan orsaka, vi införa förfaranden-kod fryser, QA testperioder, släppa tåg, etc. – det är bokstavligen utformat för att sakta ner vår produktivitet.
naturligtvis håller dessa procedurer funktioner och förbättringar från att distribueras i tid. De orsakar också kaos på ingenjörernas förmåga att fokusera på sina lags prioriteringar. Om en bugg hittas under en testperiod måste det ansvariga teamet kontextskifta och fokusera på att lösa felet. Om en allvarlig bugg hittas i produktionen måste laget inte bara fixa buggen utan också hoppa genom hoops för att få den utplacerad av nästa släpptåg.
jourtjänstgöring blir en boondoggle. Om något går fel med vår monolit måste någon vara tillgänglig — dag eller natt — för att lösa problemet. Men vem? Stora organisationer med stora monoliter står i allmänhet inför två val:
ett incidenthanteringsteam vars enda, ledsna, ledsna jobb inom organisationen är att svara på problem som orsakas av andra ingenjörers kod och ta reda på hur man löser dem.
ett roterande jourschema, där varje vecka någon godtycklig ingenjör tilldelas det sorgliga, ledsna jobbet att bli ansvarig för att lösa problem som sannolikt orsakas av kod skriven av någon annan ingenjör, i något annat ingenjörsteam.
(Mis)organisera våra team
monoliter röra med våra organisationer på ett annat sätt. Hela vår organisation arbetar med samma stora produkt. Men vi måste fortfarande bryta organisationen i hanterbara Team. Så vi tenderar att titta på funktionella roller för att hitta laggränser:
tyvärr begränsar denna typ av organisationsstruktur samarbetsarbete. Snarare än att arbeta tillsammans för att lösa det verkliga problemet (t. ex. hur designar, bygger och underhåller vi funktion X?) medlemmar i de olika funktionella områdena fokuserar helt enkelt på egen hand och kastar metaforiskt sitt arbete över staketet när de är klara. Potentialen för samarbete och synergi — där den kombinerade kvaliteten på lagets ansträngning är mycket mer än summan av de enskilda teammedlemmarna — går förlorad.
det är också fullt av flaskhalsar. När vi organiserar våra team efter funktionellt område kommer vi naturligtvis att ha felinriktning i prioriteringar. Låt oss säga att produktledningsteamet bestämde att vår monoliths kassaprocess måste moderniseras. De kommer att schemalägga tid med designteamet för att sätta ihop några mocks. Vid någon tidpunkt kommer hånarna att vara färdiga och överlämnas till frontend-teamet för att genomföra. Naturligtvis behöver frontend-teamet API: er som ska implementeras av backend-teamet, så de kommer att blockeras tills det är klart. När backend-teamet prioriterar sitt arbete med de nya kassatjänsterna finner det att det behöver hjälp från Databasadministrationsteamet (DBA). Som naturligtvis har sina egna prioriteringar. Så backend-teamet kommer att blockeras tills en DBA frigörs.
på ett sätt verkar denna organisationsstruktur lite som en dåligt utformad, alltför kopplad mjukvaruarkitektur… eller hur?
Microservices = avkopplad kod, avkopplade lag
däremot möjliggör en mikroservicearkitektur teamautonomi. Det blir mycket lättare att bilda lag som är fristående, som arbetar effektivt tillsammans och som inte ständigt blockeras av beroenden från andra lag.
team kan ta fullt ägande över sitt arbete, från design till utveckling till distribution. Varje medlem delar ansvaret för att uppnå sitt lags mål, så de blir incitament att delta i mer än bara ”deras del”. Jag har arbetat med team där produktchefer, designers, front-end, back-end och mobila ingenjörer har fått tillsammans för att utforma produktegenskaper, vilket ger mycket bättre resultat än vad som kunde ha uppnåtts av en person.
teamet får ansvar för sina egna artefakter när de är utplacerade i produktion. Detta leder i allmänhet till högre kvalitet kod som är lättare att felsöka. Varför är det så? Till skillnad från en monolit tenderar team att ha en helhetssyn på de mikrotjänster de äger. Så det är mycket lättare för teamet att förutse problem, att lägga till bra loggning och mätvärden för att felsöka problem när de uppstår och att använda sig av resiliensmönster (t.ex. försök, Brytare och fallbacks, etc) för att undvika problem i första hand.dessutom, eftersom lag har en full känsla av ägande över sitt arbete, blir deras tjänster hälsosamma och löpande i produktion mindre om ett mardrömsligt släppschema och mer om att vårda deras skapande.
slutligen arbetar lag mot samma mål, på samma tidslinje. Det betyder inte mer att blockera en person när de väntar på att någon i ett annat funktionellt område ska frigöra sig.
vi måste vara avsiktliga om autonomi
men vi får inte dessa fördelar gratis helt enkelt genom att bryta vår monolit i mikrotjänster. Låt oss ta en titt på vår första, naiva syn på en mikroservicearkitektur:
om vi är som de flesta ingenjörer är vår första uppfattning om en mikroservicearkitektur, ja, en massa mikrotjänster. Varje exponerar någon form av API (vila, kanske) för att tillåta någon annan tjänst att läsa från den och skriva till den.
När vi får erfarenhet lär vi oss att inte alla mikrotjänster tjänar samma syfte — eller åtminstone borde de inte. Och därför, precis som vår monolit hade ordnats i lager, så ordnar vi våra mikrotjänster:
vid denna tidpunkt har vi definierat de olika typerna av mikrotjänster och applikationer som vi vill bygga. Stor. Men vi har fortfarande inte gjort mycket framsteg när det gäller lagautonomi. Varje mikroservice måste ägas av något team. Och så uppstår frågan: vilka lag kommer att äga vilka mikrotjänster?
Cross functional teams
vårt första naiva tillvägagångssätt kan vara att organisera våra lag genom att efterlikna vår monolith org-struktur:
här ser vi lag (i lila) organiserade efter funktion: UX design, frontend Engineering, backend Engineering, Data Engineers, dba, QA, etc.
detta kan kännas rätt, åtminstone initialt. Men låt oss ta ett steg tillbaka och titta på det värde vi försöker leverera till våra kunder. Är det vårt mål att bygga saker som följande för våra kunder?
ett gäng databasscheman
ett gäng användargränssnitt mockups
ett gäng mikrotjänster som kan prata med en MySQL-databas?
inte riktigt. Det är bara de verktyg som vi använder för att skapa värde för våra kunder. Det verkliga värdet som vi ger våra kunder / användare kommer i form av funktioner och funktionalitet som:
en produktkatalog för att söka
en mekanism för att placera varor i en kundvagn och därefter köpa dem
ett anmälningssystem för att varna kunder om statusen för deras inköp
På samma sätt vill vi inte organisera vårt team efter funktionsområde. Snarare bör vi definiera våra team med det värde som de skapar för kunderna; det vill säga över funktioner, i (de lämpligt namngivna) tvärfunktionella teamen.
med tvärfunktionella team arbetar alla tillsammans för att bygga en specifik produkt eller funktion, från början till slut. Alla i teamet har samma mål och prioriteringar, så inget funktionellt område blockeras av en annan. Kräver den nya backend API-tjänsten något databasdesignarbete? Bra; lagets backend-ingenjör och DBA kan båda prioritera sitt arbete tillsammans.
i bästa fall uppmuntrar tvärfunktionella team medlemmarna att samarbeta under varje fas av projektet. Varje teammedlem bidrar till den övergripande utformningen av funktionen. Frontend, backend och mobila ingenjörer gemensamt definiera API kontrakt. Alla testar. Och alla börjar bli välkända inom sin specifika domän.
och så kan våra teamstrukturer börja se ut så här:
det är bättre. Men något känns fortfarande inte rätt.
Visst, vi har bildat team som sannolikt kommer att vara mer effektiva i att äga produkter. Men vi har fortfarande tagit en top-down-strategi för att identifiera topologin för mikrotjänster som vår organisation avser att bygga. Vi har en stor samling av ömsesidigt beroende mikrotjänster, varav de flesta är kopplade ihop. Vi har helt enkelt tilldelat dem till olika lag att bygga.
detta leder till problem som:
Hur kan vi skapa API: er som uppfyller alla nuvarande och framtida behov som någon klient kan ha? Kan vi inkapsla våra data när någon av våra tjänster kan anropas av något annat teams tjänster?
hur mycket tid kommer vi att slösa väntar på andra lag att genomföra våra beroenden?
vilka fel i våra system kan orsakas av fel i andra system (kaskadfel)?
kan vi kontrollera antalet samtal våra tjänster kan vara inblandade i? Kan vi se till att vår organisation inte slutar skapa gränslösa synkrona samtal mellan tjänster, vilket leder till astronomiska svarstider, eller värre (och ja, jag har sett detta hända) oändligt rekursiva samtal över tjänster?
vad händer om vårt teams specifika funktion eller problemutrymme inte är väl lämpat för den förplanerade mikroservicetopologin?
vi behöver ännu ett annat sätt att tänka. Kanske finns det redan ett mönster för oss att följa?
ange det avgränsade sammanhanget
det avgränsade sammanhanget är ett nyckeldesignmönster som bärs av domändriven design eller DDD. Att förstå det begränsade sammanhanget hjälper oss att bilda autonoma team och, i förlängning, autonoma mikroservicearkitekturer.
DDD själv beskriver en metodik för mjukvaruutveckling där individer inom en organisation arbetar tillsammans för att definiera ett gemensamt språk. I sin bok Domain Driven Design skildrar Eric Evans ofta ingenjörer som arbetar med produktägare för att upprätta ett överenskommet ordförråd för att beskriva saker som produkter, komponenter i produkterna, åtgärder som en produkt kan utföra (eller kan utföras på produkten), delar av arbetsflöden etc. Detta ordförråd omfattar organisationens domän.
i många stora organisationer blir det emellertid omöjligt att definiera en enda konsekvent ordförråd. I dessa fall bryter vi vår domän i underdomäner. Exempel på underdomäner kan inkludera:
lagerhantering
produkt upptäckt
orderhantering
kundvagnar och kassan
som designers, ingenjörer, produktchefer, etc, träffas för att bygga ut en underdomän, de bildar sitt eget sätt att tänka och prata om underdomänen och dess komponenter.
det är här DDD möter tvärfunktionell lagstruktur. Även om gruppmedlemmarna är från olika funktionella områden, de är ansvariga för sin egen underdomän, så småningom bli bosatta experter. Dessutom ansvarar teamet för att bestämma vilka artefakter-mikrotjänster, webbapplikationer, mobilappar, databaser och relaterad infrastruktur — som behövs för att få underdomänen till liv och till organisationens kunder.
Vi kan tänka på laget och dess artefakter som består av ett avgränsat sammanhang.
definiera det avgränsade sammanhanget
medan Evans diskuterar avgränsade sammanhang ofta i sin bok, definierar han inte riktigt mönstret uttryckligen. Så jag ska försöka göra det här:
begränsat sammanhang:
ett internt konsekvent system med noggrant utformade gränser som förmedlar vad som kan komma in i systemet och vad som kan lämna det.
med andra ord representerar ett avgränsat sammanhang ett sammanhang — i huvudsak ett system som inkapslar kooperativa komponenter — med tydligt definierade gränser som styr vad som kan komma in i systemet och vad som kan lämna det.
celler (de små saker som kollektivt utgör alla levande varelser) erbjuder en fin analogi. Inom en cell finns alla typer av komponenter (kärnan, ribosomer, cytoplasma, cytoskeletoner, etc) som alla är inkapslade i själva cellen. Omgivande varje cell är emellertid ett membran som fungerar som barriären mellan cellens inre och resten av organismen. Membranet skyddar cellen från sin miljö, tillåter specifika näringsämnen att komma in i den och tillåter olika biprodukter att lämna.
På samma sätt består ett avgränsat sammanhang av en mängd olika komponenter (mikrotjänster, webbapplikationer, mobilappar, databaser, meddelandeköer etc.). Det fungerar också som en logisk barriär som inkapslar dessa komponenter. Internt kan komponenterna kopplas och kan fritt överföra data till varandra. Men det begränsade sammanhanget hjälper till att genomdriva lös koppling externt, definiera uttryckliga punkter där:
externa data kan komma in (kanske via konsument som prenumererar på ett Kafka-ämne)
interna data kan avsluta (kanske via ett annat Kafka-ämne eller via ett väldesignat GET API, noggrant utformat för att dölja eventuella interna systemdetaljer)
ett avgränsat sammanhang representerar också sitt tvärfunktionella team. Teamet består av olika gruppmedlemmar (designers, frontend/backend/mobila ingenjörer, produktchefer, dataingenjörer och QA ingenjörer, etc). Internt arbetar dessa medlemmar tillsammans mot samma konsekventa mål. Dessutom är dessa teammedlemmar (eller bör) inkapslade så att de har minimala beroenden på andra lag.
så istället för att börja på organisationsnivå och definiera alla applikationer och mikrotjänster som vi förväntar oss att bygga, bygger vi Team runt våra underdomäner, så att dessa lag kan växa sina underdomäner och definiera vad som behöver byggas. Gjort ordentligt, vi tenderar att se olika avgränsade sammanhang i organisationen som växer organiskt, snarare än som styva, fördefinierade strukturer.
konsekvenser för att bryta monoliten
Conways lag berättar för oss att organisationer designar mjukvarusystem som efterliknar deras organisations kommunikationsstruktur. Det visar sig ofta vara sant, så vi bör tänka på hur vi strukturerar vår organisation när vi börjar bygga mikrotjänster.
faktum är att en bild borde dyka upp i ditt sinne. När vi flyttar från monolit till mikrotjänster bör vi börja tänka vertikalt (dela monoliten med dess underdomäner) istället för horisontellt (dela monoliten med dess funktionella lager).
vi bör dela saker inte som vi gör till vänster, men som vi gör till höger
med andra ord bör vi inte börja med att ersätta monolitens dataåtkomstlager med datamikrotjänster. Snarare bör vi börja med att dela ut en hel funktion (till exempel kassaprocessen eller kanske produktsökning). Varje funktion kommer att representera ett begränsat sammanhang. Och var och en kommer att delas ut av ett dedikerat tvärfunktionellt team.
dessutom bör det laget fokusera på sin uppgift, vilket är att antingen:
troget replikera befintlig funktionalitet,
eller (bättre) för att bygga en helt ny, förbättrad upplevelse för sina kunder.
som en del av processen bör teamet utforma det system som passar bäst för strävan.
till exempel kan vi besluta att skala vår produkt sökfunktion ur vår monolit. Produktsökningsteamet kan i slutändan utforma ett system som innehåller:
Kafka-konsumenter som lyssnar på ett antal externa Kafka-ämnen för att uppdatera sitt eget interna system för rekord (SoR) för produkter.
en Kafka-utgivare som trycker på ändringar i sin SoR på ett internt Kafka-ämne
en annan Kafka-konsument som lyssnar på det interna ämnet och uppdaterar ett elastiskt sökindex
en GraphQL-slutpunkt för freeform-sökningar som frågar elastisk sökning
en ReST-slutpunkt som hämtar enskilda produkter med ID
en nydesignad webbapplikation som använder dessa slutpunkter för att låta kunder söka efter produkter och utforska produktinformation
en liknande uppsättning av skärmar i våra mobilappar som använder dessa slutpunkter
en Kafka-utgivare som driver meddelanden, representerar distinkta frågor som utförs av kunder, till ett externt Kafka-ämne, för användning av något annat avgränsat sammanhang (säg analytics) som kan vara intresserade
hur utformningen av vår produktsökning avgränsad kontext, inkapslad i rött, kan se ut När vi börjar peeling av fler och fler vertikala delar av vår monolit, bygger andra lag ut sina egna avgränsade sammanhang. Dessa avgränsade sammanhang kan hamna ser helt annorlunda från varandra.
varje lag bestämmer hur man bäst bygger lösa sin uppgift till hands
Lägg märke till att komponenter inom ett givet avgränsat sammanhang kan vara tätt kopplade; men vi håller våra avgränsade sammanhang frikopplade från varandra. I vårt exempel sker all kommunikation mellan avgränsade sammanhang genom att skicka meddelanden via en Kafka-meddelandekö. Det är viktigt att vi undviker synkrona begäran/svarssamtal mellan begränsade sammanhang.
detta är också sant med vad som återstår av monoliten. Vi vill verkligen inte ha en tät koppling mellan våra nya mikrotjänster och vår äldre monolit. Så när vi skalar bort delar av monoliten utnyttjar vi meddelandeöverföring för att låta de återstående delarna kommunicera med våra nya begränsade sammanhang.
verklighetskontroll på allt detta frikoppling
Vid denna tidpunkt kan vi Fråga oss om det verkligen är möjligt att hålla våra begränsade sammanhang frikopplade.
i den verkliga världen, kan vi verkligen hålla våra team skyddade från externa beroenden? Kommer det aldrig att finnas fall där ett lag måste blockeras av ett annat lag för att få sitt arbete gjort?
och kan vi faktiskt skapa servicearkitekturer för våra underdomäner som är helt frikopplade från andra underdomäner? Finns det verkligen inget behov av en applikation i ett avgränsat sammanhang för att någonsin synkront ringa en tjänst i en annan?
i verkligheten kan det vara omöjligt att hålla våra begränsade sammanhang 100% frikopplade. Men vi kan komma nära, mycket närmare än de flesta av oss kanske tror.
verkliga arkitekturer
låt oss börja med att titta på avkopplade arkitekturer. Ofta köper vi in i felaktigheten att en viss typ av data ska bo på exakt en plats, och att alla andra system direkt måste ringa in i den platsen för att komma åt data.
vi hänvisar till detta som att tilldela en enda källa till sanning (SSoT) till våra data. Men som beskrivs i den här artikeln som dissekerar tanken på SSoTs, är just det begreppet i stort sett ett antimönster. Istället bör de flesta avgränsade sammanhang lagra sin egen lokala kopia av alla data som de behöver använda.
detta exemplifieras av vårt Produktsökningsbegränsade sammanhang från föregående avsnitt. Detta begränsade sammanhang är naturligtvis starkt beroende av vår organisations produktkatalogdata. Men oddsen är att data genereras i ett annat avgränsat sammanhang (vi kallar det Produktinmatningsbegränsat sammanhang).
vårt första (naiva) tillvägagångssätt kan vara att exponera ett ReST API från Produktinmatningsbegränsat sammanhang och tvinga tjänsterna inom Produktsökningsbegränsat sammanhang att kalla det API. Men vi kan göra bättre. Vi kan istället hålla systemen frikopplade genom att publicera de ändringar som gjorts av Produkttjänsterna på Kafka. Våra produktsökning Kafka-konsumenter hämtar sedan dessa meddelanden och uppdaterar produktsökningsdatabaserna.
Observera att dessa två avgränsade sammanhang så småningom är konsekventa. Detta innebär att det kommer att finnas korta tidsperioder där en viss del av data kan vara inkonsekvent mellan produktinmatning och produktsökning. Till exempel, om priset på Vita Wombat Widgets höjs från $1,99 till $2.49, kommer det att finnas en kort tidsperiod (ofta en fråga om sekunder om inte millisekunder) där det finns en 50 kg skillnad i vitt Wombat Widget pris över de två avgränsade sammanhang.
detta leder till de verkliga fallen när vi inte har något annat alternativ än att koppla avgränsade sammanhang. I vissa fall är eventuell konsistens inte acceptabel. Till exempel, innan en kund kan slutföra sitt onlineköp, kan vi behöva se till att varje artikel i deras kundvagn faktiskt är tillgänglig just nu. Även då kan vi ofta minimera kopplingen mellan de två avgränsade kontexterna.
våra interaktioner kan se ut så här:
eftersom kunden använder PRODUKTSÖKNINGSGRÄNSSNITTET för att hitta produkter används produktsökningsdatabaserna för att hämta information (t.ex. stilar, kundrecensioner, prissättning etc.) om produkterna
även när kunden börjar kassaprocessen använder vi fortfarande produktsökningsdatabaserna för att hämta den information som behöver visas.
slutligen, när kunden klickar på den slutliga ”Komplett köp”-knappen, gör vi ett enda synkront samtal till Produktinmatningen begränsad kontext för att validera varornas tillgänglighet innan köpet slutförs.
ett annat vanligt exempel som kräver omedelbar konsistens relaterad till auktorisering. I många system måste säkerhetstoken hämtas eller valideras vid varje förfrågan. I dessa fall måste vi förmodligen låta våra begränsade sammanhang kalla ett annat, säkerhetsorienterat avgränsat sammanhang.
verkliga org-strukturer
vad sägs om fristående, tvärfunktionella team? Hur möjliga är de i den verkliga världen?
i verkligheten är det en process av kontinuerlig rörelse mot helt självförsörjande lag. Sällan kommer vi någonsin att nå 100% autonomi med våra team. Men om vi börjar med att organisera våra team på ett intelligent sätt och känner igen och svarar på flaskhalsar som uppstår kan vi komma nära.
till att börja med bör vi maximera våra vertikala, tvärfunktionella lag och minimera antalet horisontella, enkelfunktionella lag. Det innebär att motstå lusten att bilda så kallade ”core”-team — vars uppgift är att bygga gemensamma datatjänster som konsumeras av andra produktorienterade team-och istället bilda våra team kring det affärsvärde som de kommer att ge.
många organisationer tippar mot detta mål och bildar först domänorienterade team av produktchefer och front-end och back-end ingenjörer. Det är en början. Men vem ska dessa lag inkludera? Exakt medlemskap kan skilja sig mellan olika team med olika behov. Men vi bör överväga saker som:
om vårt team har front-end ingenjörer, är oddsen att de ska arbeta nära med en grafisk formgivare som är dedikerad till domänen.
mobila ingenjörer — ofta sekvestrerade i sitt eget område av organisationen-bör inkluderas för domäner med en mobil komponent.
i sin upplysande artikel om datanät beklagar Zhamak dehghani att dataingenjörer ofta utesluts från tvärfunktionella team-till nackdel för dataingenjörerna och de tvärfunktionella lagen själva.
När vi har bestämt medlemskapet i våra lag bör vi se upp för flaskhalsar. Finns det några andra lag som vanligtvis blockerar våra tvärfunktionella teams produktivitet?
till exempel har många organisationer ett dedikerat säkerhetsteam. Detta är naturligtvis en bra praxis; organisationer behöver en sammanhängande säkerhetsstrategi och ett sätt att säkerställa styrning över den strategin. Det är dock också vanligt att Team stoppar sitt arbete i olika skeden för att tillåta säkerhetsgranskningar av sitt arbete. Även i de bästa situationerna etablerar detta vägspärrar för våra team som en rutinmässig affärspraxis. Dessutom kommer det ofta att leda till att team måste skrota hela eller delar av sitt arbete och börja om, eftersom de upptäcker säkerhetskrav som inte hade uppfyllts.
detta är helt klart en dålig lukt. Men hur kan vi genomdriva vår organisations säkerhetsstandarder samtidigt som team kan förbli autonoma och produktiva?
Vi kan göra detta genom att lägga till säkerhetsingenjörer till våra tvärfunktionella team. Det finns tre tillvägagångssätt vi kan ta:
Om vi har turen att ha ett relativt stort säkerhetsteam kan vi tilldela varje tvärfunktionellt team en heltidssäkerhetsingenjör (SE).
med mindre säkerhetsteam kan varje SE tilldelas ett antal tvärfunktionella team på deltid. Detta skulle fortfarande göra det möjligt för SEs att förstå lagens mål och mönster och att arbeta med teamet för att följa organisationens säkerhetsstandarder under hela processen.
Om vi inte har tillräckligt med säkerhetsresurser för antingen kan vi gå i motsatt riktning. I stället för att ta med medlemmar av säkerhetsteamet i våra tvärfunktionella team kan vi ta med medlemmar av de tvärfunktionella lagen ut till säkerhetsteamet. Varje tvärfunktionellt team skulle utse en eller två säkerhetsrepresentanter. Företrädarna skulle regelbundet träffa säkerhet och hållas uppdaterade om organisationens säkerhetskrav och standarder. De kanske inte är säkerhetsexperter själva. Men de kommer att kunna tjäna rollen som en säkerhetsingenjör och se till att deras team följer organisationens säkerhetspraxis.
Guilds
detta sammanfaller i ett annat organisationsmönster som har fått dragkraft: guilds. Guildmodellen föddes från den tvärfunktionella teammodellen. Av deras natur är dessa lag befolkade med medlemmar som specialiserar sig i olika funktioner. Än, det är ofta vettigt för människor som är specialiserade på en specifik funktion att träffas också; till exempel, till:
finslipa sina färdigheter och lära av varandra
Upptäck och etablera bästa praxis för deras speciella funktion
beroende på funktionen, Skapa företagsstandarder och krav
vår senaste säkerhetslösning bildade effektivt en ”säkerhetsgilde”. Teammedlemmar arbetade främst med sina vertikala team; men med jämna mellanrum skulle några av dem träffas med security ”guild” för att diskutera organisationens säkerhetspraxis och standarder.
guildmodellen fungerar också särskilt bra när det gäller mjukvaruarkitektur. Särskilt med en mikroservicearkitektur krävs en viss nivå av organisationsomfattande teknisk styrning. Men att ha en grupp arkitekter som sitter i ett metaforiskt elfenbenstorn, dela ut regler till lag, är i allmänhet kontraproduktivt. Istället kan senior / lead ingenjörer från våra tvärfunktionella team regelbundet träffas i en arkitekturgille. Där kan de ta upp frågor från sina team och utarbeta lösningar och etablera pattens och standarder.
exempel på vertikal tvärfunktionella team, kompletterade med horisontella Guilder Guilder kan också utökas till nästan alla andra funktioner också. När allt kommer omkring vill vi att designers ska utveckla och arbeta från en gemensam UI-stilguide. Vi vill att våra frontend-ingenjörer ska använda samma gränssnittselement. QA-ingenjörer bör anpassas till hur testning görs i våra organisationer. Och produktchefer bör vara synkroniserade med organisationens övergripande produktplan.
Bring it all together
att flytta till mikrotjänster kan dramatiskt förbättra produktiviteten i våra team. Men vi måste förstå hur vi kan dra nytta av en mikroservicearkitektur för att få oss dit. Av alla designmönster och koncept som relaterar till mikrotjänster är det begränsade sammanhanget utan tvekan det enskilt viktigaste för att ge oss den förståelsen.
med ett fast grepp om det begränsade sammanhanget förstår vi det:
vår organisationsstruktur och vår tekniska arkitektur går hand i hand
våra produktorienterade Team bör ha minimala beroenden på andra team, precis som de system de bygger bör frikopplas från andra system
i allmänhet, omfamna det begränsade sammanhanget sätter i tankesättet att vi måste lyckas med vår mikroservicearkitektur. Se till att du förstår detta viktiga mönster innan du börjar på din mikroserviceresa!