# Shoprockets vei mot mikrotjenester, del 1: hva jeg tok feil av når man deler opp monolitten

> Et innlegg fra utviklerteamet i de første Shoprocket-årene om det første forsøket på å trekke ut en tjeneste fra en PHP-monolitt. Hvorfor jeg valgte feil første tjeneste, hva tett kobling lærte meg, og Newman-rådet jeg burde fulgt tidligere.

Winston Berty  - 17. mars 2016 - 5 min lesing

Noen måneder ut i jobben hos Shoprocket begynte jeg å bli frustrert. Vi hadde en PHP-applikasjon som et lite team av skarpe utviklere spredt over hele kloden jobbet på, og for meg så det ut til at feilrettinger skapte flere feil, at det ikke var så enkelt som det burde være å integrere nye funksjoner, og at utrullinger skjedde sjelden og var stressende. Årsaken: sterkt koblet kode.

Vi hadde en monolittisk applikasjon, nesten alt i ett GitHub-repo. Oppdateringer eller rettinger i én funksjon krevde ofte endringer flere steder. For testing hadde vi en fagfellevurdering der minst to andre utviklere måtte godkjenne en gren før den ble slått sammen med master og rullet ut. Alt dette gjorde at når en feil snek seg inn, var det ofte vanskelig å finne endringen som hadde ødelagt noe. Når vi først hadde funnet den, gikk rettingen gjennom samme prosess, og hele applikasjonen måtte rulles ut på nytt.

Som en ivrig ung utvikler som alltid var på jakt etter det nye, trodde jeg at mikrotjenester ville løse alle problemene våre da jeg først kom over dem.

## Hva jeg trodde mikrotjenester var

Det finnes ingen formell definisjon av mikrotjenester, men etter research satt jeg igjen med at mikrotjenestearkitektur er en måte å designe programvare på som distribuerte systemer av uavhengige tjenester, hver av dem sterkt spesialisert og med sin egen livssyklus. For en grundig introduksjon er Martin Fowlers [artikkel](https://martinfowler.com/articles/microservices.html) utmerket.

To sider ved dette fenget meg. For det første ideen om å dele applikasjonen i tjenester med strenge grenser. Det reduserer sjansen for at logikk som hører til én forretningskontekst lekker mellom komponentene, fordi grensesnittene mellom grensene må planlegges nøye. Det er ikke så enkelt som å gjøre lokale funksjonskall. For det andre kan hver komponent ha sin egen uavhengige livssyklus. Team kan eie koden sin og bruke den teknologistabelen som passer tjenesten best, og endringer kan rulles ut én tjeneste om gangen og rulles tilbake uten å påvirke resten.

Jeg var solgt. Shoprocket skulle dele opp monolitten. Dette er del 1 av en kort serie som følger reisen. Jeg håper lesere som planlegger eller står midt i en lignende overgang kan lære av det som gikk bra og det som gikk galt hos oss.

## Den første utfordringen var menneskelig, ikke teknisk

Jeg måtte selge ideen til resten av teamet. De var nysgjerrige, men delte ikke begeistringen, og de var motvillige til å gi fra seg utviklertimer så tidlig i produktets liv. Heldigvis ville CTO-en at jeg skulle se på sesjonshåndteringen vår, så jeg grep øyeblikket: Jeg overbeviste ham om at jeg kunne skille ut en sesjonstjeneste.

Når jeg ser tilbake, var dette et dårlig valg som første tjeneste. Produktet vårt inneholder en JavaScript-widget som [gir nettbutikk på alle nettsteder](https://v3.shoprocket.io/nb/funksjoner/selg-pa-hvilken-som-helst-nettside.md). Vi behandler sesjoner som en ressurs og lagrer sesjonsinformasjon i databasen for å analysere forlatte handlekurver og andre nøkkeltall. Men denne ressursen er ikke like håndgripelig som for eksempel ordrer eller ordrelinjer, og vi brukte sesjoner på nesten hver endring i applikasjonstilstanden. Det betydde at tjenesten uunngåelig ville bli pratsom mot resten av applikasjonen, noe jeg ikke så for meg, og som gjorde oppgaven min vanskeligere.

## Hva jeg lærte av å faktisk bygge den

Jeg trappet opp researchen. Ved siden av Fowler viste **Building Microservices** av Sam Newman seg å være en uunnværlig ressurs.

Newmans råd var, i ettertid, rådet jeg burde ha fulgt: Omstrukturer først den eksisterende applikasjonen til moduler som speiler domenets avgrensede kontekster (bounded contexts). Når utviklerne er fornøyde med grensene, *da* splitter du modulene ut i egne tjenester. Grunnen er at det er langt enklere å bryte ned og skrive om moduler med dårlige grenser enn å bryte ned og skrive om hele tjenester med all den ekstra rørleggerkoden og de lagrede ressursene de har.

Jeg fulgte ikke det rådet. Ivrig etter å bygge en komponent på egen hånd gikk jeg i gang med sesjonstjenesten.

Jeg valgte en teknologistabel som bare var marginalt forskjellig fra monolittens, og begynte å bygge. Selve tjenesten kom raskt på plass: Det tok noen uker å lage en frittstående applikasjon med et REST-API. Der lå ikke det vanskelige. Det vanskelige var å få tjenesten til å snakke med monolitten.

Det viste seg at sesjonshåndteringen var tett koblet til resten av kodebasen. Å erstatte funksjonskall med API-kall var seigt arbeid. Fordi sesjonstjenesten og monolitten hadde hvert sitt databaseskjema, måtte jeg skrive om all logikk i monolitten som brukte sesjonsressurser fra den gamle databasen, og omstrukturere data i grensesnittet mellom dem for å holde klienter som JavaScript-widgeten vår kompatible.

Integreringen tok lengre tid enn byggingen. Og da var ikke det meste av overheaden mikrotjenester vanligvis fører med seg, regnet med: tjenesteoppdagelse, logging, overvåking, distribuert sporing. Verre var det at tett kobling gjorde at endringene spredte seg over mange deler av koden. Siden teamet hadde jobbet parallelt i mellomtiden, ville det å slå sammen og få sesjonstjenesten i produksjon ha krevd mye mer koordinering enn jeg hadde anslått.

## Den ærlige vurderingen

Tjenesten går kanskje snart i produksjon. Men jeg mener nå at jeg burde fulgt Newmans råd og lagt innsatsen i å modularisere den eksisterende applikasjonen først. Gevinsten ved å ha én tjeneste som lever for seg selv er marginal. Den virkelige gevinsten kommer av å dele opp hele greia, i hvert fall i grovkornede tjenester som snakker så lite som mulig med hverandre. Det krever gjennomtenkte komponentgrenser, og dit hadde vi ikke kommet ennå.

Jeg tror fortsatt på mikrotjenester som idé. Jeg ser på forsøket mitt som et nyttig eksperiment. Jeg lærte veldig mye om applikasjonsarkitektur, domenemodellering og REST-prinsipper, og de lærdommene fikk ringvirkninger i andre deler av koden vår.

For deg som vurderer en lignende overgang, er dette mine ærlige anbefalinger:

- Les så mye som mulig om temaet før du forplikter deg
- Utsett arbeidet til du er genuint trygg på den eksisterende kodebasen og domenemodellen din
- Husk at det finnes andre måter å gi en monolitt stabilitet og robusthet på. Automatiserte enhets- og funksjonstester hjelper enormt. Testdrevet utvikling reduserer regresjoner. Horisontal skalering gjør utrullinger mindre smertefulle
- Begynn med å modularisere monolitten før du trekker ut tjenester

Shoprocket fortsetter reisen. Del 2 er der det blir mer interessant.

---

*Opprinnelig publisert som den første i en kort serie som dokumenterer Shoprockets tidlige migrering bort fra en PHP-monolitt. Hele reisen, inkludert feilene som ble rettet i senere runder, har fortsatt gjennom hver større omskriving av plattformen siden.*

---

- HTML version: https://v3.shoprocket.io/nb/blogg/shoprockets-vei-mot-mikrotjenester-del-1-hva-jeg-tok-feil-av
- Language: Norsk (nb)
- Also in: [العربية](https://v3.shoprocket.io/ar/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Deutsch](https://v3.shoprocket.io/de/blog/shoprocket-microservices-teil-1-monolith-zerlegen-fehler.md), [Ελληνικά](https://v3.shoprocket.io/el/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [English](https://v3.shoprocket.io/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Español](https://v3.shoprocket.io/es/blog/shoprocket-microservicios-parte-1-lo-que-hice-mal-monolito.md), [Français](https://v3.shoprocket.io/fr/blog/shoprocket-vers-les-microservices-partie-1-decouper-le-monolithe.md), [עברית](https://v3.shoprocket.io/he/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [हिन्दी](https://v3.shoprocket.io/hi/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Bahasa Indonesia](https://v3.shoprocket.io/id/blog/perjalanan-shoprocket-menuju-microservices-bagian-1-salah-memecah-monolit.md), [Italiano](https://v3.shoprocket.io/it/blog/viaggio-di-shoprocket-verso-i-microservizi-parte-1-cosa-ho-sbagliato-sul-monolite.md), [日本語](https://v3.shoprocket.io/ja/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Lietuvių](https://v3.shoprocket.io/lt/tinklarastis/shoprocket-kelione-i-mikropaslaugas-1-dalis.md), [Nederlands](https://v3.shoprocket.io/nl/blog/shoprocket-microservices-deel-1-monoliet-opknippen.md), [Polski](https://v3.shoprocket.io/pl/blog/droga-shoprocket-do-mikroserwisow-czesc-1-rozbijanie-monolitu.md), [Português](https://v3.shoprocket.io/pt/blog/jornada-do-shoprocket-para-microsservicos-parte-1-o-que-errei-ao-quebrar-o-monolito.md), [Română](https://v3.shoprocket.io/ro/blog/drumul-shoprocket-spre-microservicii-partea-1-ce-am-gresit-cu-monolitul.md), [Русский](https://v3.shoprocket.io/ru/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [ไทย](https://v3.shoprocket.io/th/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Türkçe](https://v3.shoprocket.io/tr/blog/shoprocket-mikroservis-yolculugu-1-monoliti-parcalarken-yanlis-yaptiklarim.md), [中文](https://v3.shoprocket.io/zh/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md)
