Gæstebloggen

Cloud og microservices: Et smugkig ind i vores systemer

I indlægget her, som handler om vores egne it-systemer hos Novicell, har vi som it-arkitekter givet den fuld gas på de tekniske detaljer (læs: vi har nørdet igennem). Vi har valgt at fokusere på vores egne systemer, for det er sjældent at vi må fortælle detaljeret om kundernes it-setup - det er ofte forretningskritisk information.

Vi fortæller om, hvordan vi har bygget en række interne services i Amazon Web Services (AWS). Først introducerer vi kort cloud computing og beskriver, hvordan Novicell har bygget en service med omkringliggende infrastruktur til at styre og synkronisere kundedata. Helt konkret ved en event-driven arkitektur i et microservice serverless landskab.

Frederik Nygaard Svendsen er softwareudvikler hos Novicell. Illustration: Novicell

Læs med og bliv klogere på, hvordan vi som organisation bruger AWS.

Hvorfor cloud computing?

Cloud computing, som vi kender det i dag, har været under opsejling, siden Amazon Web Services lancerede deres EC2 service tilbage i 2006.

Siden da er mange store virksomheder gået med på cloud-bølgen, eksempelvis Netflix, Spotify, IMDb og SIEMENS - for bare at nævne nogle få.

AWS er den suverænt største cloud provider og har ifølge Gartners analyser de seneste to år afviklet mere end 10 gange så meget “compute capacity” som de 14 næststørste cloud providers sammenlagt.

Amazon Web Services er egentlig 'blot' en infrastruktur- og serviceplatform (kombination af IaaS og PaaS), alt sammen udstillet som et væld af services. Services bygget med fokus på provisionering og administration af infrastruktur og deployment, afvikling og monitorering af applikationer - baseret på et Pay-As-You-Go system.

Med det sæt af services, AWS tilbyder (alt lige fra Compute, Storage og Database til Messaging, Network og Content Delivery) kan man bygge sikre, skalérbare og kosteffektive applikationer.

Ud fra det traditionelle softwareudviklingsperspektiv med en udviklings- og hostingafdeling betyder en Cloud Platform større frihed og agilitet.

Men dermed også et større ansvar hos den enkelte udvikler, fordi det ikke længere kun er applikationen, der udvikles, men også den omkringliggende infrastruktur og platform.

Udviklere skal i højere grad arbejde med opgaver, der tidligere typisk lå inden for DevOps (software development + software operation). Det er både en fordel og en ulempe, for som udvikler på en cloud-platform styrer man i højere grad alt rundt om applikationen.

Den enkelte udvikler skal dermed forholde sig til problemstillinger, som en traditionel Hosting eller DevOps enhed normalt hjælper med.

Case: CustomerService

Internt i Novicell er administrering af kundedata fordelt i forskellige systemer, mere specifikt CRM og tidsregistreringssystem. Her ønskede vi let at kunne vedligeholde data på tværs af systemerne.

Vi har i det hele taget længe haft en række microservices på tegnbrættet - til at servicere interne systemer. I sammenhæng med kundedata er det fx vores projektstyringssystem.

Det var dermed oplagt at bygge en CustomerService med masterdata for kunder og lade disse data synkronisere ud i vores tidsregistreringssystem og CRM. Samtidig skulle data også synkroniseres - efterhånden som de opdateres af brugerne i de to systemer.

Vi havde dermed følgende data flows:

Illustration: Novicell

En event-drevet arkitektur var oplagt, netop fordi vi ville synkronisere data mellem systemerne. Vi byggede derfor vores CustomerService til at reagere på events fra TimeRegistering og CRM og samtidig lade disse systemer modtage events fra CustomerService.

For at have lav kobling mellem systemerne og nemt tillade en fire-and-forget fremgangsmåde valgte vi at implementere en worker, der stod for at modtage og håndtere events, til hvert system:

Illustration: Novicell

Med det udgangspunkt byggede vi vores løsning i AWS.

CustomerService setup i detaljer

Vores CustomerService er udviklet som et RESTful API i .NET Core, der afvikles serverless i Lambda. Til at servicere den og andre serverless microservices, der ligger i Lambda, har vi opsat en API Gateway.

I API Gateway'en kan vi desuden centralt styre authentication og authorization uden at bekymre os om det i den enkelte applikation. Til datastore bruger vi DynamoDB. CustomerServicen consumes bl.a. af vores projektstyringsværktøj, en angular applikation, der er hosted som et static website på S3, der tilgås gennem CloudFront.

Events publishes vha. SNS. Hvert system (CustomerService, TimeRegistrering og CRM) har sit eget Topic, hvorpå der publishes beskeder til vores workers. Strukturen medfører, at vi nemt kan udvide med nye workers, der reagerer på events fra en service, og vi udvikler let nye services, der sender events til eksisterende workers.

For at have en mere ensartet tilgang til events, der publishes på SNS, har vi udviklet vores eget beskedformat, som vi altid følger.

Vores workers afvikles i Docker i et ECS cluster. Hver worker har sin egen SQS queue, som er subscribed til en eller flere SNS topics. Workeren kigger efter og processerer beskeder fra SQS queuen.

SNS-SQS opsætningen er med til at sikre data-integritet, da events dermed ikke forsvinder, hvis workeren går ned.

I nogle tilfælde sender vi beskeder over i en DeadLetterQueue, hvis de ikke kan behandles korrekt, så vi manuelt kan inspicere beskeden eller afspille den igen.

Illustration: Novicell

Infrastructure as Code

Med clouden kan vi nemt udvikle software i form af mange mindre komponenter. Det øger den samlede agilitet og overskueligheden af den enkelte komponent - men kan også blive det rene kaos, hvis man ikke har en struktureret tilgang.

Her er Infrastructure As Code (IaC) et essentielt værktøj til styre komponenterne, hvis struktur øger behovet for orkestrering og administrering af ressourcer. Derfor er det vigtigt at have en struktureret tilgang til sine ressourcer, som eksempelvis konventioner for navngivning og tagging.

Langt de fleste af vores AWS ressourcer opretter vi derfor ved hjælp af Infrastructure as Code. Det har følgende fordele:

  • Færre fejl, der opstår som følge af manuel opsætning (fx opsætning og konfigurering af ressourcer på tværs af miljøer)
  • Høj genanvendeligehed, da man nemt kopierer og tilretter eksisterende konfigurationer
  • Versionskontrol på infrastruktur (i kraft af versionskontrol på sit IaC script)
  • Overblik over alle de ressourcer, en komponent består af

I softwareudvikling er det almindelig praksis, at man kan redeploy'e en ældre version af sin applikation, hvis noget går i stykker.

Men hvad gør man, hvis selve infrastrukturen går i stykker? Her er IaC uundværligt for at kunne restore.

Vi har valgt at opbygge en account struktur for at adskille ressourcer i vores udviklings- og produktionsmiljø fuldstændig. Dermed kan vi også let styre bruger- og systemadgange:

Illustration: Novicell

Til at styre Continuous Integration og Contionuous Deploy har vi opsat en TeamCity på AWS med tilhørende agenter. Den er opsat til at checkout fra git, build, test og deploy til dev, når der checkes in.

Fra TeamCity interagerer vi nemt med AWS gennem deres CLI og administrerer og deploy'er vores services:

Illustration: Novicell

Alle vores services er opsat til at logge til CloudWatch. Her kan vi nemt overvåge og debugge ved hjælp af logs med tilhørende custom metrics. Foruden de metrics, der findes som standard i AWS (fx Metrics på SQS, Lambda, APIGateway osv.).

Ud fra disse metrics har vi opsat alarmer, der advarer os (i Slack), hvis der eksempelvis logges en Error, eller hvis ResponseTime på requests er for høje.

På sigt vil vi gerne sætte dashboards op (gennem fx Grafana) eller ved at hælde vores logs i ElasticSearch/Kibana. Det vil lette søgning i logs, og vi kan nemt oprette visualiseringer og dashboards.

Til at dokumentere vores services har vi et swagger-ui, der er hosted som et static website på S3 med CloudFront.

Swagger-UI’et trækker en swagger-beskrivelse fra hver af vores services, som servicen selv genererer ved hjælp af Swashbuckle.AspNetCore.

Vi har dermed én indgang til dokumentation for hele vores Novicell API, som består af adskillige microservices.

Her kan vi nemt danne os et overblik over de forskellige services og deres funktionaliteter - samt gå i detaljer med de enkelte endpoints.

Illustration: Novicell

Cloud og microservices gør din udvikling agil

Ved at opbygge vores interne systemer og services i mindre komponenter - og samtidigt basere os på cloud services - kan vi i løbet af relativt kort tid opbygge og vedligeholde store mængder forretningslogik og infrastruktur.

Og det hele kan varetages af et lille team, der (næsten) kun er udstyret med et kreditkort og en kode-editor.

Frederik Nygaard Svendsen er softwareudvikler hos Novicell. Han er professionsbachelor i softwareudvikling og har også en datamatiker-uddannelse.

Relateret indhold

Kommentarer (0)
Log ind eller Opret konto for at kommentere