Als Je aan het Bouwen bent Microservices, Moet U Begrijpen Wat een Begrensde Context

Mar 16, 2020 · 19 min lezen

Foto door het National Cancer Institute op Unsplash

De groei van microservice vaststelling heeft geleid tot een opleving in de populariteit van sommige eerder over het hoofd gezien software design patterns. Veel van deze patronen zijn gedolven uit Eric Evans’ Domain Driven Design, een boek dat is net zo veel over teamstructuur als het is over software-architectuur.

en van deze patronen is de begrensde Context misschien wel het belangrijkste om te begrijpen. Als ingenieurs beschouwen we de begrensde Context als een ontwerppatroon voor softwarearchitectuur. Maar dat komt omdat we het een beetje hebben overgenomen van het oorspronkelijke gebruik. Zoals Evans gebruikt, is de begrensde Context zowel een organisatorisch als een technisch patroon.

daarom ben ik gekomen om het begrensde Contextpatroon te zien als een spil in het begrijpen van microservices. Niet alleen hoe we ze kunnen bouwen, maar ook waarom we ze in de eerste plaats bouwen, en hoe ze onze organisaties succesvoller kunnen maken. Als we begrijpen wat begrensde contexten zijn – als we de begrensde Context mindset zowel technisch als organisatorisch aannemen — dan kunnen we echt succesvol zijn in het bouwen van onze microservices architectuur.

waarom verhuizen naar microservices?

om te beginnen, laten we een kleine oefening uitvoeren. Stel jezelf deze vraag: Waarom bouwen we eigenlijk microservices?

neem even de tijd om erover na te denken. Wat zijn de voordelen die het eerst in gedachten komen? Wat zijn de belangrijkste problemen die we zouden moeten oplossen? Schrijf wat antwoorden op, om eerlijk te zijn.

heeft u uw antwoord? Goed. Lees het voor jezelf. Heb je de standaard technische voordelen gehaald? Continue levering, schaalbaarheid, polyglot omgevingen, containers en wolken, en al dat goede spul? Grote.

maar bevatte uw belangrijkste antwoord iets over het mogelijk maken van uw organisatie om efficiënter te werken? Dat zou wel moeten. Omdat het bouwen van microservices niet gaat over het realiseren van technische voordelen. Echt, het gaat over het verkrijgen van organisatorische voordelen. Al het andere is een implementatiedetail.

monolieten = coupled code and coupled teams

naarmate onze monolieten groter en groter worden, begint de productiviteit af te nemen. Daar zijn ten minste twee belangrijke redenen voor.

remmen op onze snelheid

Ten eerste draagt elk ingenieursteam bij aan één gigantische codebase. Als zodanig, teams geconfronteerd met een steeds groeiende kans dat hun code zal conflicteren met de code van anderen. Om de mogelijke problemen die dit kan veroorzaken te helpen beperken, stellen we procedures in — code bevriest, QA-testperioden, release treinen, enz. – die letterlijk ontworpen zijn om onze productiviteit te vertragen.

natuurlijk voorkomen deze procedures dat functies en verbeteringen tijdig worden geïmplementeerd. Ze richten ook schade aan aan het vermogen van ingenieurs om zich te concentreren op de prioriteiten van hun teams. Als een bug wordt gevonden tijdens een testperiode, moet het verantwoordelijke team context-shift en zich richten op het oplossen van die bug. Als een ernstige bug wordt gevonden in de productie, het team moet niet alleen de bug te repareren, maar ook springen door hoepels om het te krijgen ingezet door de volgende release trein.

aanwezigheidsdienst wordt een boondoggle. Als er iets mis gaat met onze monoliet, moet er iemand beschikbaar zijn — dag of nacht — om het probleem op te lossen. Maar wie? Grote organisaties met grote monolieten worden over het algemeen geconfronteerd met twee keuzes:

  • een incident-management team waarvan de enige, trieste, betreurenswaardige taak binnen de organisatie is om te reageren op problemen veroorzaakt door de code van andere ingenieurs, en erachter te komen hoe deze op te lossen.
  • een roterend aanwezigheidsschema, waarbij elke week een willekeurige ingenieur de trieste, betreurenswaardige taak krijgt om verantwoordelijk te worden voor het oplossen van problemen die hoogstwaarschijnlijk veroorzaakt worden door code geschreven door een andere ingenieur, in een ander ingenieursteam.

(Mis)het organiseren van onze teams

monolieten knoeien met onze organisaties op een andere manier. Onze hele organisatie werkt aan hetzelfde grote product. Maar we moeten de organisatie in beheersbare teams opsplitsen. Dus we hebben de neiging om te kijken naar functionele rollen om teamgrenzen te vinden:

helaas, dit soort organisatiestructuur beperkt collaboratief werk. In plaats van samen te werken om het echte probleem op te lossen (bijvoorbeeld hoe ontwerpen, bouwen en onderhouden we functie X?) leden van de verschillende functionele gebieden richten zich gewoon op hun eigen deel, metaforisch gooien hun werk over het hek als ze klaar zijn. Het potentieel voor samenwerking en synergie — waarbij de gecombineerde kwaliteit van de inspanning van het team veel meer is dan de som van de individuele teamleden — gaat verloren.

Het is ook rijk aan knelpunten. Wanneer we onze teams organiseren op functioneel gebied, dan zullen we natuurlijk een verkeerde afstemming hebben in prioriteiten. Laten we zeggen dat het product management team besloten dat onze Monolith checkout proces moet worden vernieuwd. Ze zullen tijd plannen met het ontwerpteam om wat spot te maken. Op een gegeven moment, de mocks zal worden afgewerkt en overhandigd aan de frontend team te implementeren. Natuurlijk, het frontend team zal API ‘ s moeten worden geïmplementeerd door het backend team, dus ze zullen worden geblokkeerd totdat dat is voltooid. Zodra het backend team prioriteit geeft aan zijn werk aan de nieuwe checkout services, vindt het dat het hulp nodig heeft van het Database Administration (DBA) team. Die natuurlijk zijn eigen prioriteiten heeft. Dus het backend team zal worden geblokkeerd totdat een DBA is vrijgegeven.

Op een manier, deze organisatiestructuur lijkt een beetje op een slecht ontworpen, overdreven-gekoppelde software architectuur… niet?

Microservices = ontkoppelde code, ontkoppelde teams

daarentegen maakt een microservices-architectuur teamautonomie mogelijk. Het wordt veel gemakkelijker om teams te vormen die op zichzelf staan, die efficiënt samenwerken en die niet constant worden geblokkeerd door afhankelijkheden van andere teams.

Teams kunnen volledig eigenaar worden van hun werk, van ontwerp tot ontwikkeling tot implementatie. Elk lid deelt in de verantwoordelijkheid voor het bereiken van het doel van hun team, zodat ze worden gestimuleerd om deel te nemen aan meer dan alleen “hun deel”. Ik heb met teams gewerkt waar productmanagers, ontwerpers, front-end, back-end en mobiele ingenieurs samen zijn gekomen om productfuncties te ontwerpen, wat veel betere resultaten oplevert dan door één persoon had kunnen worden bereikt.

het team krijgt verantwoordelijkheid voor zijn eigen artefacten zodra ze in productie zijn. Dit leidt over het algemeen tot een hogere kwaliteit code die is gemakkelijker op te lossen. Waarom is dat? In tegenstelling tot een monoliet, teams hebben de neiging om een holistische kijk op de microservices die ze bezitten. Het is dus veel gemakkelijker voor het team om problemen te anticiperen, om goede logging en metrics toe te voegen om problemen op te lossen wanneer ze zich voordoen, en om goed gebruik te maken van veerkrachtpatronen (bijvoorbeeld opnieuw proberen, stroomonderbrekers en fallbacks, enz.) om problemen in de eerste plaats te helpen voorkomen.

bovendien, omdat teams een volledig gevoel van eigendom hebben over hun werk, gaat het houden van hun diensten gezond en draaien in de productie minder over een nightmarish release schema, en meer over het voeden van hun creatie.

ten slotte werken teams aan hetzelfde doel, op dezelfde tijdlijn. Dat betekent niet meer blokkeren van een persoon als ze wachten op Iemand in een ander functioneel gebied vrij te maken.

we moeten bewust zijn over autonomie

maar we krijgen deze voordelen niet gratis door simpelweg onze monoliet in microservices te breken. Laten we een kijkje nemen bij onze eerste, naïeve kijk van een microservices architectuur:

Als we zoals de meeste ingenieurs, ons oorspronkelijke idee van een microservice architectuur is, nou, een heleboel microservices. Elk bloot een soort van API (ReST, misschien) om elke andere dienst om te lezen van het en schrijven naar het.

naarmate we ervaring opdoen, leren we dat niet alle microservices hetzelfde doel dienen — of dat zouden ze in ieder geval niet moeten doen. En daarom, net als onze monoliet was georganiseerd in lagen, dus we regelen onze microservices:

Op dit punt, we hebben gedefinieerd in de verschillende types van microservices en toepassingen die we willen bouwen. Grote. Maar we hebben nog steeds niet veel vooruitgang geboekt op het gebied van teamautonomie. Elke microservice moet eigendom zijn van een of ander team. En dus rijst de vraag: welke teams zullen welke microservices bezitten?

Cross-functionele teams

Onze eerste, naïeve benadering kan worden aan het organiseren van onze teams door het nabootsen van onze monoliet-organisatiestructuur:

Hier zien we teams (in paars) georganiseerd door de functie: UX design, frontend techniek, backend engineering, data-ingenieurs, dba ‘ s, QA, enz.

Dit kan in eerste instantie goed aanvoelen. Maar laten we een stap terug doen en kijken naar de waarde die we proberen te leveren aan onze klanten. Is het ons doel om dingen als het volgende te bouwen voor onze klanten?

  • een aantal databaseschema ‘ s
  • een aantal mockups
  • een aantal microservices die met een MySQL-database kunnen praten?

niet echt. Dat zijn slechts de tools waarmee we waarde creëren voor onze klanten. De werkelijke waarde die we bieden onze klanten / Gebruikers komt in de vorm van functies en functionaliteit, zoals:

  • een productcatalogus om
  • te zoeken een mechanisme om items in een winkelwagentje te plaatsen en ze vervolgens aan te schaffen
  • een meldingssysteem om klanten te waarschuwen voor de status van hun aankopen

evenzo willen we ons team niet op functioneel gebied organiseren. In plaats daarvan moeten we onze teams definiëren op basis van de waarde die ze creëren voor klanten; dat wil zeggen, over de functies heen, in (de toepasselijk genoemde) cross-functionele teams.

met cross functionele teams werkt iedereen samen om een specifiek product of functie te bouwen, van begin tot eind. Iedereen in het team heeft dezelfde doelstellingen en prioriteiten, dus geen functioneel gebied wordt geblokkeerd door een ander. Vereist de nieuwe backend API-service wat databaseontwerp? Prima; de backend engineer van het team en DBA kunnen beide hun werk samen prioriteren.

op hun best moedigen cross functionele teams leden aan om gedurende elke fase van het project samen te werken. Elk teamlid draagt bij aan het algemene ontwerp van de functie. Frontend, backend en mobiele engineers definiëren gezamenlijk API-contracten. Iedereen test. En iedereen begint goed thuis te raken in hun specifieke domein.

En zo, ons team structuren zou kunnen gaan kijken iets als dit:

Dat is beter. Maar iets voelt nog steeds niet goed.

Zeker, we hebben teams gevormd die waarschijnlijk effectiever zullen zijn in het bezitten van producten. Maar we hebben nog steeds een top-down benadering genomen om de topologie van microservices te identificeren die onze organisatie wil bouwen. We hebben nog een grote verzameling van onderling afhankelijke microservices, waarvan de meeste aan elkaar gekoppeld zijn. We hebben ze gewoon toegewezen aan verschillende teams om te bouwen.

Dit leidt tot problemen zoals:

  • Hoe kunnen we API ‘ s maken die voldoen aan alle huidige en toekomstige behoeften die een client zou kunnen hebben? Kunnen we onze gegevens inkapselen wanneer een van onze diensten door de diensten van een ander team kan worden gebeld?
  • hoeveel tijd zullen we verspillen met wachten op andere teams om onze afhankelijkheden te implementeren?
  • welke storingen van onze systemen kunnen worden veroorzaakt door storingen in andere systemen (trapsgewijze storingen)?
  • kunnen we het aantal gesprekken waarin onze diensten betrokken kunnen zijn controleren? Kunnen we ervoor zorgen dat onze organisatie niet eindigt met het creëren van grenzeloze synchrone oproepen tussen diensten, wat leidt tot astronomische responstijden, of erger (en ja, Ik heb dit zien gebeuren) oneindig recursieve oproepen tussen diensten?
  • Wat als de specifieke functie of probleemruimte van ons team niet geschikt is voor de vooraf geplande microservice-topologie?

we hebben echter een andere manier van denken nodig. Misschien bestaat er al een patroon voor ons om te volgen?

Enter the Bounded Context

De Bounded Context is een belangrijk ontwerppatroon gebaseerd op domain driven design, of DDD. Het begrijpen van de begrensde Context helpt ons bij het vormen van autonome teams en, bij uitbreiding, autonome microservice architecturen.

DDD zelf beschrijft een methodologie voor softwareontwikkeling waarbij individuen binnen een organisatie samenwerken om een gemeenschappelijke taal te definiëren. In zijn boek Domain Driven Design schildert Eric Evans vaak ingenieurs die met producteigenaren samenwerken om een overeengekomen woordenschat op te stellen om dingen te beschrijven zoals producten, componenten van de producten, acties die een product kan uitvoeren (of kan worden uitgevoerd op het product), delen van workflows, enz. Deze woordenschat omvat het domein van de organisatie.

in veel grote organisaties wordt het definiëren van een enkele, consistente woordenschat echter onmogelijk. In deze gevallen splitsen we ons domein op in subdomeinen. Voorbeelden van subdomeinen kunnen zijn:

  • voorraadbeheer
  • Productontdekking
  • orderbeheer
  • winkelwagentjes en kassa

als ontwerpers, ingenieurs, productmanagers, enz.samenkomen om een subdomein op te bouwen, vormen zij hun eigen manier van denken en praten over het subdomein en zijn componenten.

Dit is waar DDD ontmoet cross-functionele teamstructuur. Hoewel de teamleden zijn uit verschillende functionele gebieden, ze zijn verantwoordelijk voor hun eigen subdomein, uiteindelijk worden resident experts. Bovendien is het team verantwoordelijk voor het bepalen welke artefacten-microservices, webapplicaties, mobiele apps, databases en gerelateerde infrastructuur — nodig zijn om het subdomein tot leven te brengen, en om de klanten van de organisatie.

we kunnen het team en zijn artefacten zien als een begrensde Context.

Defining the Bounded Context

terwijl Evans vaak begrensde contexten bespreekt in zijn boek, definieert hij het patroon niet echt expliciet. Dus Ik zal het hier proberen:

Bounded Context:

een intern consistent systeem met zorgvuldig ontworpen grenzen die bemiddelen wat het systeem kan binnenkomen en verlaten.

met andere woorden, een begrensde Context vertegenwoordigt een context — in wezen een systeem dat coöperatieve componenten inkapselt — met duidelijk gedefinieerde grenzen die bepalen wat het systeem kan binnenkomen en wat het kan verlaten.

cellen (die kleine dingen die samen alle levende wezens vormen) bieden een mooie analogie. Binnen een cel bevinden zich allerlei componenten (de kern, ribosomen, cytoplasma, cytoskeletten, enz.) die allemaal ingekapseld zijn in de cel zelf. Omringende elke cel, echter, is een membraan, die als barrière tussen de internals van de cel en de rest van het organisme dienst doet. Het membraan beschermt de cel tegen zijn omgeving, staat specifieke voedingsstoffen toe om het in te gaan, en staat diverse bijproducten toe om te vertrekken.

In dezelfde geest bestaat een begrensde Context uit een verscheidenheid aan componenten (microservices, webapplicaties, mobiele apps, databases, berichtwachtrijen, enz.). Het dient ook als een logische barrière die deze componenten inkapselt. Intern kunnen de componenten worden gekoppeld en kunnen ze vrij gegevens aan elkaar doorgeven. Maar de begrensde Context helpt bij het afdwingen van losse koppeling extern, het definiëren van expliciete punten waar:

  • externe gegevens kunnen worden ingevoerd (misschien via een consument die is geabonneerd op een Kafka-onderwerp)
  • interne gegevens kunnen worden afgesloten (misschien via een ander Kafka-onderwerp, of via een well-design GET-API, zorgvuldig ontworpen om interne systeemdetails te verbergen)

een begrensde Context vertegenwoordigt ook het cross-functionele team. Het team bestaat uit verschillende teamleden (ontwerpers, frontend/backend/mobile engineers, productmanagers, data engineers en QA engineers, enz.). Intern werken deze leden samen aan dezelfde consistente doelen. Bovendien zijn deze teamleden (of moeten ze) ingekapseld zodat ze minimaal afhankelijk zijn van andere teams.

dus in plaats van te beginnen op een organisatorisch niveau en alle toepassingen en microservices te definiëren die we verwachten te bouwen, bouwen we teams rond onze subdomeinen, waardoor deze teams hun subdomeinen kunnen laten groeien en definiëren wat er gebouwd moet worden. Goed gedaan, hebben we de neiging om verschillende begrensde contexten in de organisatie te zien als organisch groeiende, in plaats van als rigide, vooraf gedefinieerde structuren.

implicaties voor het breken van de monoliet

Conway ‘ s wet vertelt ons dat organisaties software systemen ontwerpen die de communicatiestructuur van hun organisatie nabootsen. Dat blijkt vaak waar te zijn, dus we moeten attent zijn over hoe we onze organisatie structureren als we beginnen met het bouwen van microservices.

Er zou nu inderdaad een beeld in je hoofd moeten verschijnen. Als we van monoliet naar microservices, moeten we beginnen te denken verticaal (delen van de monoliet door zijn subdomeinen) in plaats van horizontaal (delen van de monoliet door zijn functionele lagen).

We moeten het verdelen van de dingen niet zoals wij dat doen, aan de linkerkant, maar als wij op de juiste

In andere woorden, we moeten niet beginnen met het vervangen van de monoliet de data access laag met gegevens microservices. In plaats daarvan moeten we beginnen met het splitsen van een hele functie (zoals het afrekenproces, of misschien product zoeken). Elke functie vertegenwoordigt een begrensde Context. En elk zal worden opgesplitst door een toegewijd cross-functioneel team.

bovendien moet dat team zich richten op hun taak, namelijk:

  • getrouw de bestaande functionaliteit repliceren,
  • of (beter) om een geheel nieuwe, verbeterde ervaring voor zijn klanten op te bouwen.

als onderdeel van het proces moet het team het systeem ontwerpen dat het meest geschikt is voor de inspanning.

bijvoorbeeld, we zouden kunnen besluiten om onze productzoekfunctionaliteit uit onze monoliet te halen. Het Product search team zou uiteindelijk het ontwerp van een systeem dat omvat:

  • Kafka consumenten die naar een aantal externe Kafka-onderwerpen luisteren om hun eigen internal system of record (SoR) voor producten bij te werken.
  • een Kafka uitgever die duwt wijzigingen aan de SoR op een interne Kafka onderwerp
  • een ander Kafka consument die luistert naar die interne onderwerp en updates en Elastic Search index
  • een GraphQL eindpunt voor vrije zoekopdrachten die query ‘ s Elastic Search
  • een ReST eindpunt haalt de afzonderlijke producten door ID
  • een vernieuwde web-applicatie die gebruik maakt van deze eindpunten om klanten toe te staan om producten te zoeken en ontdek de details van het product
  • een soortgelijke set van schermen in onze mobiele apps die gebruik maken van deze eindpunten
  • Een Kafka uitgever die duwt berichten, het vertegenwoordigen van verschillende query ‘ s uitgevoerd door de klanten, een externe Kafka onderwerp, voor het gebruik door een andere begrensd context (bijvoorbeeld google analytics) dat geïnteresseerd zou zijn

Wat het ontwerp van onze Product-Search Begrensd Context, ingekapseld in het rood, eruit zou kunnen zien

Als we beginnen met een peeling-off maakt meer en meer verticale delen van onze monolith, andere teams bouwen hun eigen Begrensd Contexten. Deze begrensde contexten kunnen uiteindelijk op zoek heel anders van elkaar.

elk team bepaalt hoe de taak het best kan worden opgelost bij hand

merk op dat componenten binnen een bepaalde begrensde context nauw met elkaar verbonden kunnen zijn; we houden echter onze begrensde contexten van elkaar Gescheiden. In ons voorbeeld, elke communicatie tussen begrensde contexten gebeurt door het doorgeven van berichten via een Kafka bericht wachtrij. Belangrijk is dat we synchrone verzoek/reactie oproepen tussen begrensde contexten vermijden.

Dit geldt ook voor wat overblijft van de monoliet. We willen zeker geen strakke koppeling tussen onze nieuwe microservices en onze oude monoliet. Als we delen van de monoliet verwijderen, gebruiken we het doorgeven van berichten om de resterende delen te laten communiceren met onze nieuwe begrensde contexten.

realiteitscontrole op al deze ontkoppeling

Op dit punt kunnen we ons afvragen of het echt mogelijk is om onze begrensde contexten ontkoppeld te houden.

in de echte wereld, kunnen we onze teams echt beschermen tegen externe afhankelijkheden? Zullen er nooit gevallen zijn waarin een team moet worden geblokkeerd door een ander team om hun werk gedaan te krijgen?

en kunnen we eigenlijk service architecturen maken voor onze subdomeinen die volledig zijn losgekoppeld van andere subdomeinen? Is het echt niet nodig dat een applicatie in de ene begrensde Context ooit synchroon een service in een andere aanroept?

in werkelijkheid kan het onmogelijk zijn om onze begrensde contexten 100% ontkoppeld te houden. Maar we kunnen dichterbij komen, veel dichterbij dan de meesten van ons zouden denken.

real-life architecturen

laten we beginnen door te kijken naar ontkoppelde architecturen. Vaak geloven we in de misvatting dat een bepaald type gegevens op precies één locatie moet leven, en dat elk ander systeem direct naar die ene locatie moet bellen om toegang te krijgen tot de gegevens.

we verwijzen naar dit als het toewijzen van een enkele bron van waarheid (SSoT) aan onze gegevens. Maar zoals beschreven in dit artikel dat het idee van SSoTs ontleedt, is dat begrip in grote lijnen een anti-patroon. In plaats daarvan moeten de meeste begrensde contexten hun eigen lokale kopie opslaan van alle gegevens die ze nodig hebben om te gebruiken.

Dit wordt geïllustreerd door onze Product-Search begrensde Context uit de vorige sectie. Deze begrensde Context is natuurlijk sterk afhankelijk van de productcatalogusgegevens van onze organisatie. Maar de kans is groot dat data wordt gegenereerd in een andere begrensde Context (we noemen het de product-Entry Bounded Context).

onze eerste (naïeve) benadering zou kunnen zijn om een ReST API van de product-Entry Bounded Context bloot te leggen en de services binnen de Product-Search Bounded Context te dwingen om die API te noemen. Maar we kunnen beter. In plaats daarvan kunnen we de systemen ontkoppeld houden door de wijzigingen van de Productinvoerdiensten op Kafka te publiceren. Onze Product-Search Kafka consumenten halen dan die berichten op en werken de product-Search databases bij.

merk op dat deze twee begrensde contexten uiteindelijk-consistent zijn. Dit betekent dat er korte perioden zullen zijn waarin een bepaald stuk gegevens inconsistent kan zijn tussen het invoeren van een Product en het zoeken naar een Product. Bijvoorbeeld, als de prijs van witte Wombat Widgets wordt verhoogd van $ 1.99 naar $2.49, zal er een korte periode van tijd (vaak een kwestie van seconden, zo niet milliseconden) waar er een 50¢ verschil in witte Wombat widget prijs over de twee begrensde contexten.

Dit leidt tot de real-world gevallen waarin we geen alternatief hebben dan om gebonden contexten te koppelen. In sommige gevallen is uiteindelijke consistentie niet aanvaardbaar. Bijvoorbeeld, voordat een klant zijn online aankoop kan voltooien, moeten we er misschien voor zorgen dat elk item in zijn winkelwagentje op dat moment beschikbaar is. Zelfs dan kunnen we vaak de koppeling tussen de twee begrensde contexten minimaliseren.

onze interacties kunnen er als volgt uitzien:

  • aangezien de klant de gebruikersinterface voor Productzoekopdrachten gebruikt om producten te vinden, worden de databases voor productzoekopdrachten gebruikt om informatie op te halen (zoals stijlen, klantrecensies, prijzen, enz.) over de producten
  • zelfs als de klant begint met het afrekenen, gebruiken we nog steeds de databases voor het zoeken naar producten om de informatie op te halen die moet worden weergegeven.
  • ten slotte, wanneer de klant klikt op de laatste “volledige aankoop” knop, maken we een enkele, synchrone oproep naar de product-Entry begrensde Context om de beschikbaarheid van de items te valideren voordat de aankoop wordt voltooid.

een ander algemeen voorbeeld dat onmiddellijke consistentie met betrekking tot autorisatie vereist. In veel systemen moeten beveiligingstokens op elk verzoek worden opgehaald of gevalideerd. In die gevallen moeten we waarschijnlijk toestaan dat onze begrensde contexten een andere, veiligheidsgerichte begrensde Context noemen.

Real-life org structuren

hoe zit het met zelfstandige, cross-functionele teams? Hoe mogelijk zijn ze in de echte wereld?

in werkelijkheid is het een proces van continue beweging naar volledig onafhankelijke teams. Zelden zullen we ooit 100% autonomie bereiken met onze teams. Maar als we beginnen met het intelligent organiseren van onze teams, en bottlenecks die zich voordoen herkennen en daarop reageren, kunnen we dichtbij komen.

om te beginnen moeten we onze Verticale, cross-functionele teams maximaliseren en het aantal horizontale, single-functionele teams minimaliseren. Dat betekent weerstand bieden aan de drang om zogenaamde “core” teams te vormen-waarvan de missie is om gemeenschappelijke dataservices te bouwen die worden gebruikt door andere productgerichte teams — en in plaats daarvan onze teams te vormen rond de bedrijfswaarde die ze zullen bieden.

veel organisaties tiptoe in de richting van dit doel, eerst het vormen van domein-georiënteerde teams van productmanagers, en front-end en back-end engineers. Dat is een begin. Maar wie moeten deze teams nog meer omvatten? Het exacte lidmaatschap kan verschillen tussen verschillende teams met verschillende behoeften. Maar we moeten dingen als:

  • als ons team front-end engineers heeft, dan is de kans groot dat ze nauw moeten samenwerken met een grafisch ontwerper die toegewijd is aan het domein.
  • mobiele ingenieurs – vaak afgezonderd in hun eigen gebied van de org — moeten worden opgenomen voor domeinen met een mobiele component.in haar verhelderende artikel over datamaas betreurt Zhamak Dehghani dat data engineers vaak worden uitgesloten van cross-functionele teams — ten nadele van de data engineers en de cross-functionele teams zelf.

zodra we het lidmaatschap van onze teams hebben bepaald, moeten we uitkijken voor knelpunten. Zijn er andere teams die gewoonlijk de productiviteit van onze cross-functionele teams blokkeren?

bijvoorbeeld, veel organisaties hebben een speciaal beveiligingsteam. Dit is natuurlijk een goede praktijk; organisaties hebben behoefte aan een samenhangende veiligheidsstrategie en een manier om te zorgen voor governance over die strategie. Het is echter ook gebruikelijk dat teams hun werk in verschillende stadia stoppen om veiligheidsbeoordelingen van hun werk mogelijk te maken. Zelfs in de beste situaties, dit stelt wegblokkades voor onze teams als een routine een business practice. Bovendien zal het er vaak toe leiden dat teams hun werk of een deel ervan moeten schrappen en opnieuw moeten beginnen, omdat ze beveiligingsvereisten ontdekken waaraan niet was voldaan.

Dit is duidelijk een slechte geur. Maar hoe kunnen we de beveiligingsstandaarden van onze organisatie handhaven terwijl teams autonoom en productief kunnen blijven?

we kunnen dit doen door security engineers toe te voegen aan onze cross-functionele teams. Er zijn drie benaderingen die we kunnen nemen:

  • als we het geluk hebben een relatief groot beveiligingsteam te hebben, kunnen we elk cross-functioneel team een fulltime security engineer (SE) toewijzen.
  • bij kleinere beveiligingsteams kan elke SE part-time worden toegewezen aan een aantal multifunctionele teams. Dit zou het SEs nog steeds in staat stellen om de doelstellingen en ontwerpen van de teams te begrijpen, en om samen met het team te werken aan de veiligheidsnormen van de org gedurende het hele proces.
  • als we niet genoeg beveiligingsbronnen hebben voor een van beide kunnen we in de tegenovergestelde richting bewegen. In plaats van leden van het beveiligingsteam in onze cross-functionele teams te brengen, kunnen we leden van de cross-functionele teams naar het beveiligingsteam brengen. Elk functioneel team zou één of twee veiligheidsvertegenwoordigers aanwijzen. De vertegenwoordigers zouden periodiek de veiligheid ontmoeten en op de hoogte worden gehouden van de veiligheidseisen en normen van de organisatie. Misschien zijn ze zelf geen beveiligingsexperts. Maar ze zullen in staat zijn om de rol van een security engineer te dienen, ervoor te zorgen dat hun teams zich houden aan de beveiligingspraktijken van de organisatie.

gilden

Dit sluit aan bij een ander organisatiepatroon dat steeds meer aandacht krijgt: gilden. Het gildemodel is ontstaan uit het cross-functionele teammodel. Door hun aard, die teams zijn bevolkt met leden die gespecialiseerd zijn in verschillende functies. Toch is het vaak zinvol voor mensen die gespecialiseerd zijn in een specifieke functie om ook samen te ontmoeten; bijvoorbeeld, om:

  • hun vaardigheden aan te scherpen en van elkaar te leren
  • beste praktijken voor hun specifieke functie ontdekken en vaststellen
  • afhankelijk van de functie, bedrijfsnormen en vereisten creëren

onze laatste beveiligingsoplossing vormde effectief een “beveiligingsguild”. Teamleden werkten voornamelijk met hun verticale teams; maar periodiek ontmoetten sommigen van hen de security “guild” om de beveiligingspraktijken en-normen van de organisatie te bespreken.

het gildemodel werkt ook bijzonder goed als het gaat om softwarearchitectuur. Met name met een microservices architectuur, een bepaald niveau van de organisatie-brede technische governance is vereist. Toch is het over het algemeen contraproductief om een groep architecten in een metaforische ivoren toren regels uit te delen aan teams. In plaats daarvan kunnen senior/lead engineers van onze cross-functionele teams elkaar periodiek ontmoeten in een architectuurgilde. Daar kunnen ze problemen van hun teams aan de orde stellen, oplossingen uitwerken en pattens en standaarden vaststellen.

Voorbeelden van verticale cross-functionele teams, aangevuld met horizontale gilden

Gilden kunnen ook worden uitgebreid tot bijna alle andere functies. Immers, we willen uit ontwerpers te ontwikkelen, en werken van, een gemeenschappelijke UI style guide. We willen dat onze frontend engineers dezelfde UI-elementen gebruiken. QA engineers moeten worden afgestemd op de manier waarop testen wordt gedaan in onze organisaties. En productmanagers moeten synchroon zijn met de Algemene productroad van de organisatie.

alles bij elkaar brengen

overstappen naar microservices kan de productiviteit van onze teams drastisch verbeteren. Maar we moeten begrijpen hoe we kunnen profiteren van een microservices-architectuur om ons daar te krijgen. Van alle ontwerppatronen en concepten die betrekking hebben op microservices, is de begrensde Context misschien wel de belangrijkste om ons dat begrip te geven.

met een solide begrip van de begrensde Context, begrijpen we dat:

  • onze organisatiestructuur en technische architectuur gaan hand in hand
  • onze productgerichte teams moeten minimale afhankelijkheden hebben ten opzichte van andere teams, net zoals de systemen die ze bouwen moeten worden losgekoppeld van andere systemen

in het algemeen, het omarmen van de begrensde Context zet in de mindset dat we succesvol moeten zijn met onze microservices architectuur. Zorg ervoor dat u dit belangrijke patroon begrijpt voordat u aan uw microservices-reis begint!

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.