Johdanto

Mikropalveluarkkitehtuurista on tullut hallitseva malli skaalautuvien, riippumattomien ja kestävien ohjelmistojärjestelmien rakentamiselle. Siirtyminen monoliittisista sovelluksista hajautettuihin palveluihin tuo kuitenkin uusia monimutkaisia piirteitä, jotka ovat hyvin tiiviitä palvelujen välisiä, epäselviä rajoja ja ongelmia testauksessa ja käyttöönotossa. SOLID-periaatteiden soveltaminen mikropalvelujen suunnitteluun vastaa näihin haasteisiin. Nämä viisi esinesuuntautunutta suunnitteluohjetta, jotka on mukautettu palvelurajoihin ja palvelujen väliseen viestintään, tuottavat palveluja, jotka ovat helpompia ylläpitää, laajentaa ja kehittää. Tässä artikkelissa tarkastellaan jokaista periaatetta, sen käytännön soveltamista mikropalveluissa ja konkreettisia etuja organisaatioille.

Mitkä ovat SOLID-periaatteet?

SOLID on lyhenne, jonka Robert C. Martin (Bob-setä) on ottanut käyttöön ja joka edustaa viittä muotoiluperiaatetta, jotka kannustavat ylläpitämään ja laajentamaan objektilähtöistä koodia. Mikropalvelujen yhteydessä nämä periaatteet johtavat irti tuotannosta, kohdennetuista palveluista ja selkeistä sopimuksista.

Yhden vastuun periaate

Luokalla tai moduulilla pitäisi olla yksi ja vain yksi syy muutokseen. Mikropalveluissa tämä tarkoittaa, että jokaisella palvelulla pitäisi olla yksi liiketoimintavalmius tai aliverkkotunnus. Esimerkiksi tilauksenhallintapalvelun tulisi käsitellä vain elinkaaritapahtumia, ei maksujen käsittelyä tai varaston seurantaa. Tämä vähentää muutosten räjähdyssädettä ja tekee palveluista itsenäisesti käyttöönotettavia.

Avoin/suljettu periaate

Ohjelmistoyksiköiden tulisi olla avoimia laajennuksia varten, mutta suljettuja muutoksia varten. Sovellettavat mikropalvelut, palvelut pitäisi paljastaa vakaat rajapinnat (API tai tapahtumasopimukset), joita voidaan laajentaa uusilla ominaisuuksilla muuttamatta olemassa olevaa koodia. Tämä saavutetaan usein versioitujen sovellusrajapintojen, tapahtumaskeemakehityksen tai plugin-arkkitehtuurien avulla.

Liskovin korvausperiaate (Liskov substitution principle, LSP)

Superluokan kohteet tulisi korvata alaluokan objekteilla ilman, että se vaikuttaa ohjelman oikeellisuuteen. Mikropalvelujen osalta LSP varmistaa, että palveluliittymän eri toteutustavat (esim. maksuväylä, joka voi siirtyä Stripestä PayPaliin) toimivat johdonmukaisesti ja että ne voidaan vaihtaa ilman, että ne rikkovat kuluttajia.

Liitäntärajapinnan eriyttämisperiaate (ISP)

Monet asiakaskohtaiset rajapinnat ovat parempia kuin yksi yleiskäyttöliittymä. Mikropalveluissa tämä tarkoittaa pieniä, kohdennettuja sovellusrajapintoja tai tapahtumamääritelmiä, jotka on räätälöity kunkin kuluttajan tarpeisiin. Esimerkiksi asiakaspalvelu saattaa paljastaa erillisiä päätepisteitä profiilin hakemiseen, osoitteen hallintaan ja uskollisuusstatukseen yhden ainoan asiakasreitin sijaan.

Riippuvuus- ja inversioperiaate (DIP)

Riippuu abstraktit, ei concretions. Mikropalveluissa, palvelut pitäisi riippua abstraktien rajapintojen kuten viesti välittäjät, API-portit, tai palveluverkkoja sijaan kovakoodatut viittaukset muihin palveluihin. Tämä mahdollistaa swap-toteutukset, käyttöön piirin katkaisimet, tai lisäämällä välimuisti kerroksia muuttamatta liiketoiminnan logiikkaa.

Miksi SOLID-periaatteet ovat kriittisiä mikropalveluissa

Mikropalvelut edellyttävät luonnostaan selkeitä rajoja, löysiä kytkentöjä ja korkeaa yhteenkuuluvuutta. SOLID-periaatteet tarjoavat todistetun kehyksen näiden ominaisuuksien saavuttamiseksi. Ilman niitä tiimit joutuvat usein anti-patterit kuten ...jaetut monolithit, ... jossa palvelut yhdistetään tiiviisti yhteisten tietokantojen tai keskustelullisten sovellusliittymien kautta.

Lisäksi palvelujen määrän kasvaessa muutosten kustannukset nousevat räjähdysmäisesti, jos riippuvuuksia ei hoideta. SOLID-periaatteet pitävät riippuvuussuhteet selvinä ja käännettävissä, jolloin tiimit voivat kehittää palveluita itsenäisesti. Tämä linjautuu suoraan mikropalvelujen tavoitteisiin: itsenäinen käyttökelpoisuus, skaalautuminen ja sietokyky.

SOLID-periaatteiden soveltamisesta mikropalveluihin koituvat hyödyt

Parannetaan kestävyyttä

Kun jokaisella palvelulla on yksi vastuu, yhden palvelun muuttaminen vaikuttaa harvoin muihin. Esimerkiksi uuden käyttäjävarmennusvaiheen lisääminen tunnistautumispalveluun ei edellytä muutoksia käyttäjäprofiilipalveluun. Eristyminen vähentää merkittävästi regressiotestausta ja käyttöönottoriskejä. Joukkueet voivat julkaista päivityksiä yksittäisiin palveluihin omalla kaistanleveydellään ja nopeuttaa toimitusta.

Parannettu skaalattavuus

SRP:n ja ISP:n kanssa suunnitellut palvelut ovat luonnollisesti rakeisempia. Tämän rakeisuuden ansiosta organisaatiot voivat skaalata vain niitä komponentteja, jotka kokevat suurempaa kysyntää. Esimerkiksi videostreaming-alusta voi skaalata transkoodauspalvelunsa metadatan etsimisestä riippumatta. Koska riippuvuudet ovat käänteisiä (DIP), palvelun skaalaaminen ei edellytä sen alku- tai loppupään yhteistyökumppaneiden skaalaamista.

Joustavuuden lisääminen ja uudelleenkäytettävyyden lisääminen

Käyttöliittymän erottelu varmistaa, että palvelut paljastavat vain sen, mitä kuluttajat tarvitsevat. Tämä minimoi kytkennän ja tekee näistä rajapinnoista uudelleenkäytettäviä useissa kuluttajissa. Esimerkiksi ilmoituspalvelu, jossa on erilliset rajapinnat sähköpostia, tekstiviestejä ja työntöilmoituksia varten, voidaan käyttää uudelleen tilaus-, laskutus- ja tilipalveluilla ilman muutoksia. Avoin/suljettu periaate mahdollistaa myös uusien ilmoituskanavien (esim. WebSocket) lisäämisen muuttamatta nykyisiä rajapintoja.

Parempi testaus

Erillisillä palveluilla, joissa on tarkkaan määritellyt rajapinnat, on paljon helpompi testata. Yksikössä testaaminen on riippuvainen abstrakteista (DIP) konkreettisten palveluiden sijaan mahdollistaa kehittäjille malleja tai pantoja. Integraatiotestaus helpottuu, koska jokainen palvelu voidaan suorittaa eristyksissä testivaljaita vastaan. Suurempi testikattavuus johtaa harvempiin tuotantotilanteisiin ja nopeampiin takaisinkytkentäsilmukkaan.

Viansietokyky ja sietokyky

DIP-sovelluksen avulla palvelut perustuvat abstraktiin viestintäkanavaan, kuten viestijonoihin tai palveluverkkoihin. Nämä abstraktit sovellukset voivat toteuttaa retries-, aikakatkaisu-, virtakatkaisija- ja laipioita muuttamatta palvelulogiikkaa. Esimerkiksi maksutapahtumat viestien välittäjän (DIP) kautta lähettävä tilauspalvelu toimii edelleen, vaikka maksupalvelu olisi tilapäisesti käytettävissä, koska tapahtumat ovat jonossa myöhempää käsittelyä varten.

Helpompi aluksella ja tiimiautonomia

Kun palvelut seuraavat SRP:tä ja ISP:tä, niiden vastuut ovat selkeät ja rajalliset. Uudet kehittäjät voivat ymmärtää nopeasti palvelun tarkoituksen. Joukkueet voivat omistaa joukon siihen liittyviä palveluja ilman, että tarvitsevat syvää tietoa muista. Tämä mahdollistaa sen, minkä tyyppisiä itsenäisiä, monitoimisia tiimit, jotka mikropalvelut lupaavat.

SOLID-yhdisteiden käytännön soveltaminen mikropalveluihin

Palvelurajat määritellään SRP:llä

Aloita hajottamalla verkkotunnuksesi rajoitettuihin kontekstiin. Jokainen konteksti tulee palveluksi. Esimerkiksi verkkokaupan järjestelmässä, luoda erillisiä palveluja luettelo, ostoskoriin, tilauksiin, maksuihin, lähetyksiin ja arvosteluihin. Jokainen palvelu omistaa datansa ja liiketoimintasääntönsä. Vältä luomasta ... utility palvelua, joka sekoittaa vastuut.

Vakaiden rajapintojen suunnittelu OCP:llä ja ISP:llä

Luo käyttöliittymän määritelmät (sopimukset) käyttäen protobufia, OpenAPI:tä tai AsyncAPI:tä. Varmista, että nämä rajapinnat ovat versioituja ja laajalle ulottuvia. Esimerkiksi ... Tilaus luodun tapahtuman tulisi sisältää kenttiä, joista olet varma, mutta salli tulevia kenttiä valinnaisten ominaisuuksien kautta. Vältä murtamasta muutoksia lisäämällä uusia päätepisteitä tai viestityyppejä nykyisten muutosten sijaan.

Korvaavuuden varmistaminen LSP:llä

Kun useat palvelut toteuttavat saman käyttöliittymän (esim. useita maksu yhdyskäytävän adapterit), standardoi sopimus. Kirjoita integraatiotestit, jotka vahvistavat, että kaikki toteutus noudattaa odotettua käyttäytymistä (esim., hyväksyä maksu palauttaa menestys tai vika johdonmukaiset virhekoodit). Tämä tekee vaihtamisesta yhdyskäytävät turvallisia.

Käännetään riippuvuudet viestimessuilla ja palvelumeshillä

Palvelun sijaan A suoraan HTTP-puhelun Service B:hen, on palvelu A julkaisee tapahtuman viestinvälittäjälle (Kafka, RabbitMQ) tai käyttää palveluverkkoa (Istio, Linkerd). Palveluverkko pystyy käsittelemään uudelleentry, aikakatkaisu ja piirinmurtamiskäytäntöjä. Liiketoimintalogiikka palvelun sisällä A on edelleen agnostinen taustalla verkossa.

Haasteet ja näkökohdat

SOLID-periaatteiden soveltaminen mikropalveluihin ei ole ilman haasteita. Liiallinen segmentointi (ISP-sovellus liian aggressiivisesti) voi johtaa puheisiin rajapintoihin ja liian moniin palveluihin, mikä lisää toiminnan yleisyyttä. Samoin tiukka SRP voi aiheuttaa tiimien luomia mikropalveluja jokaiselle pienelle työyksikölle, mikä johtaa ...

Toinen haaste on versiointi ja taaksepäin yhteensopivuus. Seuraamalla OCP vaatii huolellista poistokäytännöt. Työkalut kuten skeema rekisterit (Confluent Schema Registry, Apicurio) voi auttaa hallitsemaan yhteensopivuustasoja.

Lisäksi tiimikulttuuri ja organisaatiollinen yhdenmukaistaminen ovat tärkeitä asioita. Ilman selkeää omistajuutta ja viestintää jopa tarkkaan määritellyt SOLID-palvelut voidaan kytkeä tiiviisti yhteen organisaatiotapojen (esim. yhteiset tietokannat tai yhteiset kirjastot) avulla. Jatkuvan integraation ja DevOps-käytäntöjen tulee tukea itsenäistä käyttöönottoa.

Päätelmät

Keskittymällä selkeisiin vastuualueisiin, vakaisiin sopimuksiin, korvattavuuteen, hienojakoisiin rajapintoihin ja ylösalaisin oleviin riippuvuuksiin tiimit voivat välttää monia hajautettujen järjestelmien yhteisiä aukkoja. Sijoitukset etusuunnitteluun tuottavat tulosta järjestelmän kasvaessa ja kehittyessä. Jatkolukea varten tutkitaan Martin Fowler. [-esimerkkejä mikropalveluista[], alkuperäisiä [-SOLID-periaatteiden selityksiä[[]] ja vastaavia [[]-pilvimalleja.