performanceevaluering af en microservice og monolitisk...

70
1 Performanceevaluering af en microservice og monolitisk applikation Af Michael Birkholm & Jesper Mørup 14-06-2016 Vejleder Henrik Bærbak Christensen Abstract: Denne rapport indeholder en undersøgelse af en dobbelt implementeret applikation. Her sammenlignes responstid og througput af disse applikationer, der bygger på to arkitekturer.

Upload: buiminh

Post on 15-Mar-2018

227 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

1

Performanceevaluering af en

microservice og monolitisk applikation

Af

Michael Birkholm & Jesper Mørup

14-06-2016

Vejleder

Henrik Bærbak Christensen

Abstract:

Denne rapport indeholder en undersøgelse af en

dobbelt implementeret applikation.

Her sammenlignes responstid og througput af disse

applikationer, der bygger på to arkitekturer.

Page 2: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

2

Indholdsfortegnelse 1 Motivation ...........................................................................................................3

1.1 Definition af microservice ..................................................................................6

2 Hypotese ..............................................................................................................7

2.1 Afgrænsning .......................................................................................................7

3 Metode ................................................................................................................8

3.1 Web applikation .............................................................................................. 14

3.2 Event drevet microservice .............................................................................. 18

3.3 Driver til test ................................................................................................... 19

4 Analyse og resultater ........................................................................................ 25

4.1 Implementering af RabbitMQ ......................................................................... 25

4.2 Docker ............................................................................................................. 26

4.3 Docker compose ............................................................................................. 29

4.4 JMeter ............................................................................................................. 31

4.5 Test af den monolitiske applikation ................................................................ 32

4.6 Test af microservice applikation ..................................................................... 34

5 Diskussion ......................................................................................................... 38

6 Relateret arbejde .............................................................................................. 44

7 Konklusion ......................................................................................................... 45

8 Referencer......................................................................................................... 47

9 Bilag ................................................................................................................... 48

9.1 Docker compose - microservice ...................................................................... 48

9.2 Docker compose – monolitiske ....................................................................... 50

9.3 Gradle .............................................................................................................. 51

9.4 Implementering af RabbitMQ ......................................................................... 55

9.5 Konfiguration af performance test ................................................................. 59

9.6 JMeter opsætning af testplan ......................................................................... 62

9.7 Opsætning af Amazon instanser ..................................................................... 67

Page 3: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

3

1 Motivation Siden begrebet microservices blev introduceret af Dr. Peter Rodgers i 2005 til

Cloud Computing Expo, har der ikke været den store årvågenhed før 2012

hvor det langsomt begyndte at blive interessant igen, i takt med at der

begyndte at vise sig samstemmende udfordringer med den gennemprøvede

lagdelte arkitektur.

Efterhånden som etablerede virksomheder såsom Microsoft, Netflix, Ebay,

Amazon mv. fik øjnene op for fordelene ved microservice arkitekturen, har

det medført et enormt momentum igennem it verdenen.

Det kunne også ses på bl.a. goto og javazone konferencerne hvor mange

workshops omhandlede microservices.

Der har indtil starten af 2016 ikke været begrænset med videnskabelige

dokumenter omhandlende microservices.

Fordelene og ulemperne ved microservices er løst beskrevet på diverse sider,

også af kendte personer indenfor IT, blandt andet Martin Fowler [Martin

Fowler, Microservices] og Chris Richardson.

En af de påståede fordele ved microservices, er at man kan opnå bedre

performance gennem skalering, end man kan med den almindelig brugte

lagdelte monolitiske arkitektur.

Martin Fowler har dog skrevet at kommunikationsformen i en microservice

arkitektur gør at det ikke performer så godt. Vi har derfor sat os for at

undersøge hvor stor en indflydelse denne arkitektur har på performance,

samt hvad der skal til for at en micorservice arkitektur kan performe bedre.

Vi har igennem fagpakken ”Software architecture in Practice” lært omkring

kvalitetsattributter og metoder til at lave målinger af dem.

Mange elementer i tankegangen bag microservices harmonerer også med

fagpakken Reliable Software Architecture in Practice, specielt med Nygaards

taktikker.

En monolitisk web applikation er simpel at deploye, samt at overskue set fra

allocation viewpoint, den har typisk følgende opbygning:

Page 4: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

4

:Server

:EksempelApplication

:Server

:Database

Indeholder funktionalitet til:StoreFrontUIAccountingServiceInventoryServiceShippingService

:PC

:Browser http

Det er simpelt at overskue, da der kun er én server som hoster hele

applikationen med alt funktionalitet. Derudover er der en eller flere servere

der hoster en central database.

En typisk opbygning af en arkitektur baseret på microservices er vist

herunder, her ses at applikationen er splittet ud i flere mindre services, som

kan skaleres vertikalt.

Disse services har et lille ansvarsområde, og er afkoblet fra de andre services,

derfor kommunikeres der typisk ved HTTP kald eller gennem en

messagequeue.

:Server

:StoreFrontUI

:PC

:Browser http

:Server

:AccountingService

:Server

:InventoryService

:Server

:ShippingService

Page 5: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

5

Der er flere måder at skalere på, Abbott et. al. beskriver det som en terning

[Abbott et. al., Scale Cube], hvor Chris Richardson har lavet nedenstående

illustration [Chris Richardson, Scale Cube]:

Skalering på x aksen sker ved at klone applikationen, dvs. at køre flere

instanser af samme applikation.

Skalering på y aksen sker ved at splitte applikationen i flere dele, opdelingen

kan bl.a. ske på baggrund af ansvarsområde.

Slutteligt kan skalering ske på z aksen, ved at partitionere de data hver

applikation varetager, så de kun arbejder på et subset af data, der er relevant

for det pågældende request.

Vi har tidligere erfaring med skalering på x aksen, men ikke med skalering på

y aksen hvor man opdeler en applikation.

Derfor finder vi det interessant at se på hvilke indvirkningerne det har på

performance, at skalere på y aksen.

Page 6: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

6

1.1 Definition af microservice Før en arkitektur baseret på microservice kan evalueres, skal definitionen af

en microservice først slåes fast. Der er på nuværende tidspunkt ikke nogle

videnskabelige artikler der definerer en microservice.

Derfor findes karakteristika på denne arkitektur, som vil føre til vores

definition af microservices.

En af de vigtige karakteristika er at en microservice har et afgrænset

ansvarsområde. Dette sikrer høj samhørighed, og gør det let for udviklere at

overskue hvad formålet er med servicen, hvilket sikrer maintainability.

Microservices kan udvikles i vilkårlige sprog, derfor sætter dette krav til

kommunikationen for at gøre brug af dem. Det er påkrævet at det er en

sprog uafhængig kommunikation der anvendes, som gerne er letvægts, dvs

fx. REST eller ved brug af en message queue.

Derudover skal microservices kunne deployes uafhængigt af hinanden. Den

løst koblede kommunikation over fx. REST modvirker at lave stærke

bindinger.

Dette gør at en microservice også lettere kan udskiftes, så længe den

overholder samme interface som tidligere.

Ud fra ovenstående kan man konkludere at microservices er overskuelige set

fra module viewpoint. Uafhængige set fra allocation viewpoint. Derudover

har de et klart defineret interface der kommunikeres gennem, set fra

component and connector viewpoint. [Christensen et al, 2012]

Dette står i kontrast til en monolitisk software arkitektur, hvor

ansvarsområdet er større. Dette har indflydelse på kommunikationen, hvor

der nødvendigvis ikke er klare linjer for, hvilken del af applikationen der

kommunikeres med. Omvendt foregår kaldene her typisk som inter-process

kald. Ud fra allocation viewpoint vil man kun have 1 applikation, som

håndterer alt, modsat microservices hvor der er flere, men hvor det står klart

for system administratorerne hvilket ansvar hver enkel service har.

Derudover er der en central database, som står i kontrast til microservices

der ofte har hver deres egen private database.

Page 7: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

7

2 Hypotese Denne opgave vil undersøge forskellen i responstid og throughput af en

applikation udviklet af Chris Richardson, som enten kan afvikles som en

monolitisk applikation eller som microservices.

Da der er noget overhead ved at afvikle samme funktionalitet som flere

applikationer i stedet for én, forventer vi at microservices har en negativ

indvirkning på kvalitetsattributten performance, hvis der blot afvikles én

instans af hver service.

Microservices tror vi først giver værdi når der afvikles flere instanser af hver

service, og her forventer vi at man kan opnå bedre throughput og responstid.

Hypotesen er derfor:

Applikationen opbygget over en microservice arkitektur, har en højere

responstid end den monolitisk opbygget webside, ved en kontinuerlig

mængde service kald igennem 30 minutter.

Applikationen opbygget over en microservice arkitektur med 3 instanser af

hver service, har en lavere responstid og højere throughput end den

monolitisk opbyggede webside, ved en kontinuerlig mængde service kald

igennem 30 minutter.

2.1 Afgrænsning Da applikationerne anvender en event store fra tredje part [Eventuate], kan

den have dårlig indvirkning på performance, som vi ikke har mulighed for at

undersøge.

Resultaterne kan ikke sige noget generelt for en vilkårlig microservice eller

monolitisk applikation, da der kan være forskelle i implementering.

Page 8: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

8

3 Metode Til at undersøge performance vil der blive anvendt en dobbelt implementeret

applikation. Det vil sige to applikationer der har samme funktionalitet, men

kan afvikles henholdvis som microservices eller en monolitisk applikation.

Til kommunikationen til microservicen vil vi anvende RabbitMQ, da en

message queue giver nogle fordele hvis der skal skaleres horizontalt.

For at have sammenlignelige resultater vil kommunikationen til den

monolitiske applikation også anvende RabbitMQ.

RabbitMQ vil fungere med topic exchange, så hver besked bliver routet til

den relevante service.

For at kunne udføre performance målinger der er reproducerbare og

sammenlignelige, vil Apache JMeter [Apache JMeter] blive anvendt.

JMeter er et værktøj til performance målinger, den fungerer ved at sende

HTTP forespørgsler.

Disse HTTP forespørgsler vil blive sendt til en applikation der bliver udviklet til

formålet, som sender forespørgslen videre til message queuen, som derefter

afleverer det til web applikationen.

Grunden til at der skal anvendes en applikation til at modtage kaldet fra

JMeter og sende det videre, er at denne vil fungere som en test driver.

Dette giver mulighed for i applikationen, at der sendes forskellige parametre

med i disse requests, derved sendes samme forespørgsel ikke hver gang.

Apache anbefaler at man ved remote testing afvikler JMeter Engine tæt på

applikationen der skal testes, ved tæt på mener de samme Ethernet segment

[JMeter FAQ].

JMeter Engine er derved den applikation som udfører load testing, og sender

resultater tilbage til JMeter GUI.

JMeter GUI vil blive afviklet på vores egen computer, og anvendes blot til at

starte de instanser af JMeter Engine der skal bruges til test, samt til at

opsamle resultater.

For hurtigt at kunne opsætte et testmiljø afvikles applikationerne i Docker

containers.

Docker er en virtualiserings applikation oven på operativsystemet, der kan

afvikle containers.

Det sikrer at vores tests er lette at gentage, også på andre miljøer, især hvor

flere applikationer og tilhørende databaser skal integreres.

Under udførelsen af dette vil det være en hjælp at kunne opsætte containers

lokalt, og når alt fungerer kunne afvikle vores Docker containers i det rette

testmiljø og lave performance målinger.

Page 9: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

9

Vi har tidligere lavet et projekt i fagpakken Reliable Software Architecture in

Practice om Docker. Her voldte det at have et multi-container setup

problemer, med at linke dem til hinanden, og sikre at de rette porte var åbne

til kommunikation mellem fx. applikation og database.

Til at løse dette problem er der kommet en udvidelse til Docker kaldet Docker

Compose [Docker Compose], som er et værktøj til at håndtere et multi-

container setup og afhængigheder.

Docker containers beskrives i en Dockerfile, som sikrer reproducerbarhed og

samtidig kan fungere som dokumentation af containeren.

Hele multi container setup’et beskrives i en docker-compose fil, som sikrer at

containers startes i den korrekte rækkefølge hvis der er afhængigheder, samt

at porte mellem containers er åbne.

Applikationerne afvikles i Amazon EC2, som er en cloud løsning af IaaS typen.

IaaS står for Infrastructure as a Service, dette betyder at abstraktionslaget for

det virtuelle er hardwaren som Amazon varetager, men at vi har fuld kontrol

over konfiguration af OS og software på maskinerne.

Derfor skal vi selv installere og konfigurere alt software der skal anvendes.

Da der vil blive gjort brug af Docker containers kunne man argumentere for

at anvende en cloud løsning af PaaS typen, som står for Platform as a Service,

hvor Docker var konfigureret af udbyderen og vi blot skulle administrere

vores containers.

Men da JMeter Engine vil blive afviklet på samme netværk som

applikationerne der skal testes, og at Apache fraråder at der kører andet

software på de servere JMeter Engine afvikles på, er der brug for en cloud

løsning af typen IaaS.

På nedenstående allocation view er testmiljøet vist:

Page 10: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

10

:Amazon EC2 micro

:PC

:JMeter

:Docker container

:PerformanceTester

:Amazon EC2 micro

:JMeter Engine http

http

:Docker container

RabbitMQ:MessageQueue

:Amazon EC2 medium

:Docker container

:Monolith application

:Docker container

MongoDB:Database

:Amazon EC2 micro

:Docker container

:PerformanceTester

:Docker container

RabbitMQ:MessageQueue

:Amazon EC2 micro

http

:Docker container

:Microservice

:Amazon EC2 micro

:Docker container

:Microservice

:Amazon EC2 micro

:Docker container

:Microservice

:Amazon EC2 micro

:Docker container

MongoDB:Database

Page 11: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

11

De enkelte komponenter i testmiljøet er beskrevet herunder:

PC PC der afvikler JMeter, denne er vores egen computer og er ikke placeret ved Amazon.

JMeter Engine Bruges til at udføre loadtest, ved at sende http forespørgsler til PerformanceTester. JMeter Engine har ingen GUI og skal fjernstyres fra JMeter, som den sender resultater fra forespørgslerne tilbage til.

JMeter JMeter er klienten til at udføre loadtest, som modtager målingerne. Den forbinder til JMeter Engine og konfigurerer dem afhængigt af hvilken test der udføres. JMeter kører i 30 minutter for hver test, for at få et retvisende billede af loadtesten. Ud fra de målinger bliver 90% linjen anvendt, det vil sige de 90% som resultaterne ligger indenfor, derved vil grænsetilfælde ikke medtages, da de kan skyldes indvirkning fra baggrundsprocesser, problemer på netværket mm.

Amazon EC2 Serverne hvor applikationer og JMeter afvikles fra. Disse er virtuelle maskiner i Amazons cloud løsning af typen IaaS.

PerformanceTester Webapplikation udviklet i Java til at modtage forespørgsler fra JMeter og sende videre til den applikation som er under test.

Docker container Docker er en container virtualiserings applikation. Docker bruges til at opsætte testmiljøet med de rette applikationer. Dette gøres ud fra en Dockerfile, som kan bruges som dokumentation for hvordan testmiljøet er konfigureret.

Monolith application Den monolitiske udgave af den applikation der skal performance testes.

Page 12: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

12

Microservice Microservice dækker over flere individuelle microservices som til sammen udgør samme funktionalitet som den monolitiske applikation.

MongoDB NoSQL database som både den monolitiske og microservice applikationerne gør brug af til at persistere data.

RabbitMQ Message queue som applikationerne får deres requests fra. Dette gør det muligt at afvikle flere Docker containers med microservices som lytter på denne message queue.

Specifikationer på Amazon EC2 t2.medium Instanser:

2 vCPU, Intel Xeon processor med turbo op til 3,3GHz

4GB ram

Netværk oplyser Amazon ikke, serverne er placeret i deres datacenter i

Europa, men da JMeter Engine også afvikles fra Amazons eget netværk

har det ikke den store indflydelse

Til storage anvendes Amazon Elastic Block Store [Amazon EBS]

Ubuntu version 14.04

Specifikationer Amazon EC2 t2.micro instanser:

1 vCPU, Intel Xeon processor med turbo op til 3,3GHz

1GB ram

Netværk, storage og OS som medium instans

Specifikationer på PC:

Intel Core i7-3610QM

16gb DDR3 1600 mhz

Yousee 100/30 mbit/s

SSD harddisk

Windows 10

Da PC’en blot skal indsamle performance målinger fra JMeter Engine, og

dermed ikke skal load teste, er dens performance mindre vigtig. Dog bliver

analyse af de opsamlede data foretaget her, og JMeter Engine skal ikke

Page 13: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

13

opleve det som en flaskehals at aflevere de opsamlede resultater, så

performance af maskinen er ikke uvæsentlig.

Specifikationer på anvendte værktøjer:

Apache JMeter 3.0

RabbitMQ 3.6.1

Docker toolbox 1.10.3

MongoDB 3.2

Quality attribute scenario

Til at måle performance vil der blive anvendt Quality attribute scenario,

herefter forkortet QAS. [Bass et al., 2003]

QAS er en måde at beskrive et scenarie på, fra input stimuli, til det målbare

output.

Derved kan der på systematisk vis beskrives de test scenarier, som de to

applikationer vil blive testet under.

QAS beskrives ud fra en skabelon som vist nedenfor, som er tilpasset til at

måle på kvalitetsattributten performance:

Trin i scenarie

Beskrivelse

Source of stimulus

Entitet (internt eller eksternt til systemet, brugere eller programmer).

Stimulus Hvordan ankommer hændelserne. Periodisk, sporadisk eller stokastisk.

Environment Driftstilstand: Normal drift, nøddrift, peak load eller overload

Artifact Artifakten er den del af systemet, der bliver testet.

Response Hvad gør systemet. Fx. Requests bliver processeret. Eventuelt at servicestandarden skifter.

Response Measure

Skal være et målbart udtryk for hvad der er acceptabel svar fra systemet i det givne scenarie. Fx måling på latency, respons tid, throughput eller timeouts.

Page 14: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

14

3.1 Web applikation Til at foretage performance målinger har vi valgt at tage udgangspunkt i kode

kreeret af Chris Richardson [Chris Richardson, Money transfer]

[Microservices.io]

Koden er lavet således at den samme applikation er dobbelt implementeret,

det vil sige at det er de samme klasser/metoder der benyttes, programmet er

opbygget i moduler, som enten kan afvikles som en monolitisk applikation,

eller som flere microservices.

Domæne koden er derfor ens, men kan bygges enten som en jar fil, eller 3 jar

filer til hver service.

Dermed passer den perfekt til vores performance målinger da det er selve

arkitekturen vi ønsker at lave performance målinger på, og dermed skal det

ikke baseres på at kodebasen er forskellig.

Applikationerne er udviklet i Java, og anvender Spring Boot [Spring Boot].

Spring Boot er er et framework til at komme hurtigt i gang med Spring

applikationer. Det indeholder embedded webserver, fx. Tomcat eller Jetty, og

gør arbejdet med tredje parts libraries enklere.

Herunder ses den overordnede arkitektur for applikationen, som Chris selv

har beskrevet det. [Chris Richardson, Money transfer]

Page 15: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

15

Applikationerne er et eksempel på en lille bank applikation, hvor der kan

oprettes kontonumre, forespørges på kontonumre samt overføre penge

mellem to konti.

Opbygning af applikationerne

Applikationen består af 4 logiske services som vist på diagrammet.

Henholdsvis Accounts, Money Transfers, Account View Reader og Account

View Updater.

Applikationen kan startes på to måder, enten som en samlet Spring Boot jar

fil hvis det skal afvikles som en monolitisk application.

Det kan også afvikles som 3 selvstændige Spring Boot jar filer, hvis det skal

afvikles som microservices.

Her vil der være en service til Accounts command side, dvs. til oprettelse af

kontonumre, som svarer til den logiske service Accounts.

En til transactions command side, til udførsel af transaktioner, denne svarer

til den logiske service Money Transfers.

Herudover er der en service til Account query side, til opdatering og

forespørgsel til databasen, denne svarer til Account View Reader og Account

Page 16: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

16

View Updater.

Applikationerne anvender derfor samme kodebase.

Applikationen anvender et pattern kaldet command query responsibility

separation, herefter kaldet CQRS [Martin Fowler, CQRS], sammen med en

event drevet arkitektur, der er beskrevet i afsnit 3.2.

Med CQRS opdeles applikationen i en command side og en query side.

Command side håndterer update requests og publicerer disse som events,

query side subscriber til disse events fra command side, som den opdaterer

databasen med.

Derudover håndterer query side også read forespørgsler.

Det er en utraditionel måde at designe en microservice på, men det har

blandt andet været præsenteret på konferencen microxchg i Berlin 2015

[microxchg 2015].

Normalt ville man designe en service til accounts med tilhørende database,

og en service til transaktioner med sin egen database.

I en forretningsapplikation som dette er et eksempel på, er det dog svært at

sikre konsistens mellem de to databaser i de services, uden en to-faset

commit, hvilket gør at disse services ikke længere er uafhængige.

Med dette pattern er command side og query side uafhængig. Begge sider

har et afgrænset ansvarsområde, de er simple og kan udvikles og skaleres

uafhængigt.

Endpoints

Applikationerne udstiller 3 forskellige REST endpoints, som er følgende:

Account/{kontonummer} – forespørgsel på angivet kontonummer, returnerer

kontonummer og saldo

Account – oprettelse af kontonummer, parameter er ’initial balance’ til at

angive startsaldo, samt kontonummer. Returnerer bekræftelse af oprettelse

ved at skrive kontonummer

Transfer – til at lave overførsel i mellem to kontonumre. Parameter er

’amount’ hvor beløb angives, samt fra kontonummer, og til kontonummer.

Ved korrekt udførelse returneres der et moneytransferid.

Nedenstående diagram viser sekvensen for applikationen når der modtages

et kald til /Account

Page 17: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

17

AccountController er ansvarlig for kommunikation med klienten, den laver et

kald til AccountService, som står for at lave kald så der både oprettes og

persisteres den nye konto.

AccountControlleren sender HTTP 200 svar tilbage til klienten.

Page 18: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

18

3.2 Event drevet microservice En udfordring med microservices er at der ofte er flere databaser, derfor er

det en udfordring at sikre konsistens af data. Herudover anvendes der typisk

NoSQL databaser, der ud fra CAP theoremet giver afkald på konsistens og i

stedet vægter availability [Gilbert et al., 2002].

Det vil sige at hver service har sin egen private database, og ejerskab over de

data. Databasen behøver ikke være samme type heller, en service kan

anvende en NoSQL database hvor en anden anvender en relationel database.

Dette gør det vanskeligt at lave joins, eller distribuerede transaktioner.

En mulig løsning til dette er at anvende en event drevet arkitektur sammen

med CQRS til sine microservices, hvilket applikationen der anvendes i denne

test har, hvor der anvendes en central Event Store, i denne test anvendes

Eventuate [Eventuate].

Med denne arkitektur opnås ”eventual consistant transactions”.

Transaktioner udføres med et multi-step event drevet workflow, hvor hver

service opdaterer data, og derefter publicerer et event som starter næste

trin.

For at sikre at events er atomare, dur det ikke at man først opdaterer

databasen, og derefter publicerer et event.

Derfor anvendes Event sourcing [Martin Fowler, Event Sourcing], hvilket

betyder at et objekt persisteres ved at gemme en sekvens af events.

Derved kan man genskabe et objekts tilstand ved at genskabe den sekvens af

events der omhandler det objekt.

Eventuate fungerer derfor som en database, hvor den gemmer alle events.

Derudover sørger den for at notificere subscribers om ændringerne, vha.

observer pattern.

En afledt gevinst ved dette er at man på samme tid har implementeret en

audit log.

Eventuate kan man enten afvikle selv, eller bruge en hostet version. Den

hostede version kører på Amazon AWS, hvilket også er her performance

testen udføres. Derfor anvendes den hostede version.

Page 19: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

19

3.3 Driver til test Nødvendigheden for at lave en driver – facade

For at kunne lave performance test med et automatiseret værktøj som

JMeter, har vi behov for at kunne lave tilstandsløse kald mod den kørende

web applikation, og dermed måle responstid og throughput.

Web applikationerne baseret på Chris´ kode, som vi har valgt at lave

performance test mod, udstiller 3 forskellige REST services som vi kan bruge

til dette formål. Det giver os dog ét problem, hvilket er at der i alle 3 kald er

behov for at medsende en parameter som det kaldende system, her JMeter,

skal vide.

Ved oprettelse af konto skal der medsendes startbalancen på kontoen, ved

overførsel skal der bruges beløb, fra konto, og til konto, og endelig ved

forespørgsel på konto skal der naturligvis angives hvilket kontonummer der

forespørges på.

Det kan ikke bruges i JMeter da vi ikke kan persistere data og læse derfra for

at lave testkald til applikationen.

For at løse det problem har vi bygget en test driver der fungerer som en

facade udefra mod den kørende applikation.

Vi foretrækker denne metode, for hvis man ændrede applikationen til ikke at

skulle modtage disse parametre, ville dette være en væsentlig ændring.

Derudover er denne metode med en driver mere generisk.

Beskrivelse af driveren

Driveren fungerer således at det er muligt at kalde de 3 eksisterende REST

kald uden at have kendskab til specifikke data på kontonummer samlingen

(collection) i MongoDB.

Driveren er lavet som en Spring Boot applikation og udstiller 3 nye REST

services, som vist herunder :

Page 20: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

20

/createTestAccount

Ved kald af denne service, laves et http kald til den kørende web applikation

/account med en fast kodet start saldo på 100000.

Der returneres med en String der angiver at ”kontonummer x er oprettet”

såfremt alt er ok, hvor x er det oprettede kontonummer.

/createTestTransfer

Laver først en count() på accountInfo for at få max antal kontonumre der

bruges, dernæst vælges to tilfældige kontonumre i intervallet 1=min – max

kontonumre der bruges som fra og til kontonummer parameter til /transfer

servicen, samt en fast parameter på 1 til overførselsbeløb.

Der laves kald til /transfer og returneres med en String der angiver

”overførsel i mellem konto x og y er gennemført”

/readTestAccount

Først count() som i den foregående operation for at få max antal, og dernæst

udvælges et tilfældigt tal i intervallet 1=min og max for at få et kontonummer

der kan bruges til at kalde /account service.

Der laves kald til /account, og returneres med en String ”konto : x beløb : y”

Page 21: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

21

Klassediagram over Test driveren

Applikationen er lavet som en Spring Boot applikation.

De 3 klasser med annotationen @RestController er de endpoints som JMeter

kan kommunikere med.

Annotationen bliver brugt af Spring Boot, til at udstille denne klasse som et

REST endpoint.

Til at repræsentere en konto findes AccountInfo klassen, hvor

AccountTransactionInfo og AccountChangeInfo repræsenterer transaktioner,

og ændringer i balance.

Page 22: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

22

Nedenstående diagram viser sekvensen fra at JMeter sender en request til at

applikationen returnerer et svar:

CreateAccountController

DatabaseAccount service

Http get request til /CreateTestAccount

Besked til accountstopic med data I JSON format:{\initialBalance\ : 1000000 }

Return success

Return accountnumber

JMeter

PerformanceTester:Tomcat server Applikation der performance testes

accountService.openAccount(initialBalance)

db.collection.insert(accountnumber, balance)

HTTP response code 200

Det første request rammer RestControlleren, som er det endpoint der kan

kommunikeres med. Denne sender beskeden videre til applikationen under

test.

Kontoen oprettes og persisteres i databasen, hvorefter der returneres svar til

klienten.

Udfordringer i den eksisterende kode.

For at kunne lave ovenstående ændringer er der behov for at vi kan benytte

et heltal som input til at læse kontonummer, samt lave overførsler. Chris´

kode er dog lavet således at ved oprettelse af kontonummer, dannes der et

unikt tilfældigt UUID, der bruges som _id i mongodb samlingen.

Vi har derfor lavet en mindre rettelse der gør at vi har kontrol over _id ved

oprettelse af kontonumre, og får oprettet kontonumre med fortløbende

numre i intervallet fra 1 - ….

Vi har rettet i AccountQueryWorkFlow således at id i stedet bliver fundet ved

at lave en count på accountInfo samlingen i yourdb databasen, og dernæst

lægge 1 til.

Page 23: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

23

AccountQueryWorkFlow.java

@EventHandlerMethod

public Observable<Object>

create(DispatchedEvent<AccountOpenedEvent> de) {

AccountOpenedEvent event = de.event();

//String id = de.getEntityIdentifier().getId();

String id = "" + (accountQueryService.findMaxId() +

1);

String eventId = de.eventId().asString();

logger.info("**************** account version=" + id +

", " + eventId);

BigDecimal initialBalance =

event.getInitialBalance();

accountInfoUpdateService.create(id, initialBalance,

eventId);

return Observable.just(null);

}

AccountQueryService.java

public long findMaxId() {

return accountInfoRepository.count();

}

Metoden findMaxId henter antallet af rækker fra databasen, her kunne man

være i tvivl, om den ændring der er lavet til koden har negative performance

indvirkninger.

Vores overbevisning er at med index på databasen er det en operation der

kan udføres på konstant tid, men for at være sikker på at ændringerne ikke

har haft negative indvirkninger på performance er der blevet udført nogle

tests for at måle eksekveringstiden af denne metode.

Her blev der observeret en nærmest konstant tid for denne funktion, ved

udførsel af test med indsættelse af op til 1 million records.

Dette blev gjort ved en modificering af create metoden til dette:

String id = de.getEntityIdentifier().getId();

Instant start = Instant.now();

String account = "" + (accountQueryService.findMaxId() + 1);

Instant end = Instant.now();

Duration dur = Duration.between(start, end);

System.out.print("tid ialt : " + dur);

Duration er en ny klasse I Java8, dens output er I ISO-8601.

Outputtet er I formatet P<dato>T<tid>.

P for at markere en periode, da vi har med Duration at gøre.

Da vores målinger kun varer sekunder er der intet dato element mellem P og

Page 24: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

24

T, derfor starter outputtet med PT<tid>S, hvor S er for at angive at

tidsenheden er sekunder.

Målingerne gav følgende resultater:

Tid med 0 records på MongoDB

PT0.015S

Tid med 1 record på MongoDB

PT0.022S

Tid med 1 million records

PT0.014S

Derfor har de modificeringer til den oprindelige kode ikke negativ indvirkning

på performance, og vil ikke ødelægge testresultaterne.

Test driveren bliver afviklet på samme Amazon server som Rabbit MQ, derfor

vil der ikke være langsomme netværkskald. Indvirkningen test driveren har

på den overordnede performance er derfor minimal, desuden bliver den

brugt til test på begge applikationer, og derfor vil påvirkningen være ens i

begge tilfælde.

Page 25: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

25

4 Analyse og resultater

4.1 Implementering af RabbitMQ For at kunne besvare anden del af hypotesen, er det nødvendigt at afvikle

flere instanser af hver microservice.

Chris’ applikation anvender REST endpoints, og ligger derfor ikke op til at

afvikle flere instanser af hver service, da en klient i så fald skulle kende

adressen til hver service for at kommunikere med dem.

Derfor implementeres RabbitMQ til at tage imod requests.

Implementeringen er beskrevet i bilag 9.4.

Hver service vil fungere som consumer på køen, derved kan requests

distribueres mellem alle services når der afvikles flere instanser af hver.

Da der er 3 forskellige services der skal gøre brug af denne message queue,

vil den blive opsat som en topic exchange.

Med en topic exchange bliver beskeder ikke broadcastet til alle services, men

kun routet til de services de er relevante for.

For at få den korrekte responstid fra en besked er afsendt fra publisheren, i

dette tilfælde driveren, til den er udført er det nødvendigt at sende et svar

tilbage fra servicen til driveren gennem message queuen.

Dette bliver gjort ved at implementere en request/reply kø, så svaret først

kommer tilbage til produceren når servicen er færdig.

Da applikationerne i forvejen anvender Spring Boot, er integrationen med

Rabbit også udført i dette, for at fortsætte i samme stil.

Alternativer

Et alternativ til at anvende en message queue kunne være at indføre en

loadbalancer.

Derved kan man opnå samme resultat med at kunne fordele requests mellem

de forskellige services.

Eftersom vi har anvendt Rabbit MQ i fagpakken Reliable Software

Architecture, og dermed opbygget en vis erfaring, faldt valget på den.

Vi har ikke tidligere erfaring med at opsætte fx Nginx til at fungere som HTTP

loadbalancer, og valgte derfor message queuen.

Senere opdagede vi dog at Amazon tilbyder en loadbalancer service [Elastic

Load Balancing]. Ved at bruge denne kunne man have sparet opsætningen af

fx Nginx, der skulle dog formentligt også noget konfiguration til at sætte

dette op.

Page 26: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

26

4.2 Docker I forbindelse med udførelse af performance test, er der brug for at deploye

henholdsvis:

den monolitiske opbygning af applikationen.

den microservice baserede version.

test driveren

Rabbit MQ

og sidst en mongoDB database hvor data kan persisteres.

Da vi skal have mulighed for hurtigt at kunne skifte imellem versioner og

konfigurationer stiller det naturligvis nogle udfordringer, for der vil nemt

kunne ske fejl, hvorved man kommer til at køre test på en forkert version

eller konfiguration.

Dette problem løser Docker, da man med Docker kan specificere sin

opsætning i en fil.

Denne fil fungerer derfor både som specifikation af ens konfiguration, samt

sikrer at der ikke sker miskonfigurationer i miljøet, som kan have indvirkning

på testen.

Docker containere er platform uafhængige, derfor giver det mulighed for at

konfigurere miljøet lokalt, og når det er klar til test kan denne konfiguration

provisioneres på serverne der driver test platformen.

I følge kvalitetsattributten for testability i Bass [Bass et al., 2003] bog,

beskriver han bl.a. at tiden det tager at klargøre ens test miljø kan være et

response measure man måler på.

Denne kvalitetsattribut er påvirket positivt af indførslen af Docker, for hvis

dette skulle gøres manuelt vil der være store sandsynligheder for at testen vil

kunne blive afviklet på et forkert grundlag, og derfor ikke valid for nogen

konklusion, samt at det vil være omfattende tidsmæssigt at opsætte et test

miljø.

Derfor er det yderst relevant at anvende Docker til at besvare hypotesen, da

der er flere applikationer og konfigurationer.

Page 27: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

27

Opbygning af Dockerfile

De Dockerfiles der anvendes følger samme opbygning, da det de skal gøre, er

at afvikle en jar fil. Derfor er Dockerfilen til den monolitiske applikation vist

herunder, men fremgangsmåden er ens for de andre applikationer, det er

blot en anden jar fil der bliver anvendt.

Her ses Dockerfilen:

FROM frolvlad/alpine-oraclejdk8:slim

VOLUME /tmp

ADD monolithic-service.jar app.jar

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-

jar","/app.jar"]

Filen starter med at beskrive at der skal anvendes et image, kaldet

frovlad/alpine-oraclejdk8:slim.

Dette betyder at det er en bruger ved navn frovlad der har lagt dette image i

Dockerhubs repository. Navnet på imaget er alpine-oraclejdk8:slim.

Dette er et image der er baseret på Alpine linux, og indeholder Oracle JDK8.

Den er tagget med slim, da det er en version med kun de nødvendige ting fra

JDK, for at der kan afvikles java applikationer.

Derefter oprettes et mount point under /tmp til brug for applikationen.

Den byggede Jar fil fra udviklingsværkøjet kopieres ind i containeren hvor den

har navnet app.jar. Hvordan dette kopieres fra udviklingsværktøjet er

beskrevet i bilag 9.3 der beskriver build processen.

Entrypoint angiver hvad Docker containeren skal gøre ved start, her startes

applikationen.

Dockerfilen til RabbitMQ og MongoDB anvender de standard konfigurationer

som findes i Docker Hub.

Docker Hub er Dockers repository over Docker containers der kan anvendes.

Integration mellem Docker og Spring Boot

Applikationerne der performance testes, er lavet i Spring Boot.

Spring Boot er et framework der kan importeres med support for Docker.

Dog er der ikke gjort brug af Docker i den oprindelige udgave af

applikationen, derfor skal dette importeres, og da der allerede anvendes

Spring Boot er det mest naturlige at integrere det der.

Page 28: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

28

Hvordan Spring boot og Docker er integreret i udviklingsværktøjet, og

anvendes er ligeledes beskrevet i detaljer i bilag 9.3 der omhandler build

processen hvor Gradle indgår.

Applikationen anvender allerede Gradle [Gradle], der er et build automation

værktøj. I bilaget beskrives hvordan afhængighederne til disse 3. parts

værktøjer, som Docker er, refereres i Gradle, så vi sikrer at alle

afhængigheder er inkluderet i builds.

I tidligere fagpakker har vi anvendt ANT som build værktøj, derfor var Gradle

en ny teknologi for os.

At implementere ANT i stedet for ville være spildt arbejde, da der blot skulle

bygges videre på det eksisterende arbejde der var lavet med Gradle.

Men derfor er der en del at skulle sætte sig ind i, og fejlsøgningen er ikke let

når de først opstår ved build tidspunktet, modsat hvis det havde været ved

kompilering.

Page 29: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

29

4.3 Docker compose Docker løste problemstillingen med at sikre de rette applikationer, og

konfigurationer under performancetest.

Disse applikationer skal dog kommunikere sammen, dette er endnu et

element som skal konfigureres, og som kan føre til fejl i performancetesten

såfremt dette ikke er konfigureret korrekt.

For henholdsvis den monolitiske og den microservice baserede applikation er

der flere docker containere der skal deployes, hvor der er afhængigheder

imellem dem. For at kunne styre det bedst muligt er der et værktøj der

hedder Docker compose der muliggør dette.

I bilag 9.1 findes docker-compose filen til microservice applikationen, i bilag

9.2 findes filen til den monolitiske applikation.

I Docker compose filerne er der forskellige docker containere der skal startes

op.

Fx applikationen, testdriver, Rabbit MQ og mongoDB.

I en Docker compose fil konfigureres hvilke containere der skal starte, dette

gøres i image der fortæller hvilket image som skal bruges fra dockerhub til at

bygge docker containeren.

For at starte test miljøet op og udføre performance tests skal der bruges

applikationen og test-driveren fra vores docker repository, samt et mongoDB

og Rabbit MQ image fra Dockerhubs eget repository.

I en Docker Compose fil kan man angive Workingdir, Hostname samt

command. Disse er oplysninger der bruges til at fortælle hvordan docker

containeren skal afvikles. I dette tilfælde anvendes det til at angive et dir den

skal pege på, samt java –jar til at starte applikationen i containeren.

Derudover kan man mappe porte, dette gøres med parameteren Ports som

består af to værdier. Den første værdi er den port som applikationen skal

bruge til at få kontakt ud af docker containeren, og den næste værdi er den

port som man kan bruge udefra til at kommunikere ind i docker-containeren.

Til at forbinde sine containere, hvis de skal kommunikere med hinanden kan

man anvende Links. De angiver en dynamisk forbindelse imellem de enkelte

containere, hvilket gør at man ikke behøver at koncentrere sig om ip adresse,

når der skal refereres til de andre docker containere. Dette gøres ved at der

oprettes en mapping i /etc/hosts på source containeren, hvor der laves en

mapping mellem linknavnet og ip-adressen.

Links er dog legacy, det anbefales at man bruger networks i stedet. I vores

Page 30: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

30

tilfælde ville det dog kræve at der blev opsat et specifikt network i Docker, i

stedet for at anvende default bridge network.

Dette skyldes at bridge netværket ikke understøtter automatisk service

discovery, som beskrevet sidst i afsnittet af dokumentationen der er

refereret. [Docker Networks]

For enkelthedens skyld er der derfor anvendt links.

Den monolitiske applikation har fx link til mongoDB da den benytter

mongoDB til persistering af data.

Testdriveren har link til RabbitMQ da den laver requests til denne.

Her er et eksempel fra test driveren, hvor man i stedet for at kende ip

adressen på RabbitMQ blot kan anvende linknavnet i stedet.

Derved skal der ikke hardcodes nogle værdier.

String uri = "http://rabbitmq”;

Testdriver har også et link til mongoDB da vi har lavet et par hjælpeværktøjer

der læser og skriver direkte i mongoDB, deleteAll der sletter alle data i

databasen, samt readAll der læser alt hvad der ligger i databasen.

Derudover kan man angive miljøvariable, med parameteren Environment.

For at kunne kalde mongoDB i Spring Boot skal der tilføjes en miljøvariabel

der angiver ip adressen, samt hvilken database der skal benyttes, ved at

bruge links kan der angives container navn, i stedet for den statiske ip

adresse.

SPRING_DATA_MONGODB_URI: mongodb://mongodb/mydb

Fremgangsmåden der bruges i forbindelse med performance test kan derfor

gøres på følgende måde nu:

Tilretning af koden til applikationen, i den editor man foretrækker.

Ændringerne testes lokalt ved at afvikle kode i f.eks. Eclipse, og har Docker

kørende lokalt.

Når resultatet er tilfredsstillende køres det buildtarget ved navn buildDocker i

Gradle.

På testmaskinen er der kun behov for at der er installeret docker samt

docker-compose, og at docker-compose filen er tilstede.

Hele ens multi container setup startes ved at udføre kommandoen:

docker-compose up

Page 31: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

31

4.4 JMeter Da vi er interesserede I at sammenligne responstid og throughput mellem de

to arkitekturer er typen af performance test der bliver anvendt loadtests.

Hver test bliver kørt i 30 minutter i JMeter, alt efter hvilken type af test er der

et variabelt antal readers og writers.

For at alle tråde ikke sender forespørgsler samme tid, men distribuerer

forespørgslerne mere realistisk er JMeter konfigureret med en think time på

1000ms. Derved venter hver reader vilkårligt op til 1000ms, før næste

forespørgsel sendes.

En vigtig ting at bemærke er at når der anvendes flere instanser af JMeter til

at udføre load test, er at antallet af readers/writers der bliver konfigureret i

JMeter bliver propageret til hver instans af JMeter Engine.

Derfor er det ikke en konfiguration af antallet af max readers/writers, men

bliver til antallet af readers/writers pr instans af JMeter.

Konfiguration af distribueret performance testing

Da der indgår flere instanser af JMeter i testen, skal disse konfigures til at

udføre en distribueret test.

De instanser af JMeter der udfører testen afvikles på Amazons servere, men

selve testen startes, samt resultater opsamles fra en computer hos os.

Derfor skal det sikres at der må kommunikeres ind/ud til serverne ved

Amazon, det vil sige at de korrekte porte er åbne.

Instansen af JMeter der starter testen skal også have kendskab til hvilke

andre instanser af JMeter den skal starte testen på, dette skal også

konfigureres.

Hvordan dette er konfigureret til denne performance test, er beskrevet i bilag

9.5.

Testplan

Testplanen i JMeter består af en thread group, som simulerer antallet af

brugere der indgår i testen.

For at requests fra disse brugere skal virke naturligt, er der indsat en tilfældig

forsinkelse mellem deres requests.

Da der er flere requests der skal udføres er hver af disse defineret i JMeter.

Til visualisering af målingerne anvendes et plugin kaldet Blaze Meter.

Opsætning af testplan er beskrevet i detaljer i bilag 9.6.

Page 32: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

32

4.5 Test af den monolitiske applikation Følgende QAS er opsat for tests af den monolitiske applikation

Trin i scenarie

Beskrivelse

Source of stimulus

Eksternt

Stimulus Stokastisk

Environment Normal drift

Artifact Account, Query og Transaktion

Response Requests bliver processeret uden tab/timeouts

Response Measure

Responstiden er under 200ms, minimum 50 transaktioner per sekund.

Amazon serveren der afvikler applikation og database fandt vi nødvendig, at

den skulle være en medium instans, da der ikke var nok ressourcer med en

micro instans til at afvikle både applikation samt database, og samtidigt

opfylde response measure i QAS.

En interessant observation ved denne test er at performance falder drastisk

over tid, hvor man kan se at antallet af transaktioner falder samtidigt med at

responstiden stiger.

Den monolitiske applikation har således en rigtig god responstid i starten,

men efterhånden som utilization af serveren stiger, falder ydelsen, hvilket er

naturligt, responstiden i første del af testen er mellem 50 og 75ms.

Da databasen og applikationen er på samme server, giver det den gode

responstid indledningsvis, men gør at cpu utilization hurtigt når et kritisk

niveau.

Nedenfor ses en graf over responstider samt transaktioner pr sekund

Page 33: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

33

Denne test understreger vigtigheden af at udføre sin test i en længere

periode, i starten udførte vi performancetesten i 10 minutter for at

kontrollere at alle porte og services fungerede. Som man kan se på den

grafen, ville man ikke have opdaget den faldende performance ved blot at

måle i 10 minutter.

Det gennemsnitlige antal transaktioner pr sekund er 100, med en

gennemsnits responstid på 215ms, 90% linjen ligger ved 671 ms.

Derfor opfylder den ikke response measure i det opstillede QAS.

Page 34: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

34

4.6 Test af microservice applikation Test med 1 instans pr service

Samme QAS kan opstilles for tests af microservices:

Trin i scenarie

Beskrivelse

Source of stimulus

Eksternt

Stimulus Stokastisk

Environment Normal drift

Artifact Account, Query og Transaktion

Response Requests bliver processeret uden tab/timeouts

Response Measure

Responstiden er under 200ms, minimum 50 transaktioner per sekund.

Hver instans af de 3 services afvikles på hver deres Amazon micro instans.

Her kan man se at applikationen formår at beholde en nogenlunde konstant

responstid og throughput. I midten af testen er der dog en afvigelse, hvor

applikationerne svarer langsomt. Dette kan skyldes baggrundsprocesser eller

netværk. Mange af de requests vil ligge uden for 90% linjen da de afviger.

Nedenfor ses en graf og responstid og throughput:

Det gennemsnitlige antal transaktioner pr sekund er 111, 90% linjen ligger

ved 96 ms, selvom man kan se på grafen at enkelte requests tager længere

tid end normalt, så holder de sig stadigt inden for response measure i QAS.

Page 35: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

35

Sammenlignet med den monolitiske applikation formår den microservice

baserede applikation at holde transaktioner pr sekund på et konstant niveau,

som svarer til samme throughput den monolitiske applikation ydede i første

del af testen.

90% linjen er også lavere for den microservice baserede applikation, men

hvor dette igen skyldes den faldende performance senere i testen, af den

monolitiske applikation.

En sammenligning af responstid ses nedenfor, den blå linje er den

monolitiske applikation, og den grønne den microservice baserede:

Transaktioner pr sekund af de 2 tests er vist i nedenstående graf:

Havde den monolitiske applikation haft mere ydelse så den kunne fastholde

den performance der blev leveret i starten, havde den været overlegen, den

har ca 10ms hurtigere responstid i første del af testen.

Derfor er testen udført igen for microservice arkitekturen, hvor der

eksekveres 3 instanser af hver service.

Page 36: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

36

3 instanser af hver service

En microservice arkitektur begynder for alvor at vise positive indvirkninger på

performance, når man afvikler flere instanser af hver service.

Derfor er samme test udført, hvor der afvikles 3 instanser af hver service, på

hver sin Amazon micro instans.

En oversigt over serverne der anvendes til denne test er vist herunder.

Der er således 9 servere til at afvikle services, dertil kommer MongoDB,

RabbitMQ og servere til JMeter.

Her blev antallet af brugere opjusteret til 300, da der ellers ikke var nok

belastning på serverne.

Responstiden og throughput er nogenlunde konstant gennem hele testen,

som vist nedenfor:

Page 37: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

37

90% linjen for responstid er på 98ms, og et gennemsnitligt antal

transaktioner pr sekund er 288, der er dog et udfald i starten af testen, der

gør at nogle få requests ikke overholder response measure for QAS, dette

kunne dog skyldes en eventuel baggrundsproces eller andet med netværket.

Responstiden har ikke ændret sig synderligt, fra da der blev afviklet 1 instans

af hver microservice. Men da netværkstrafikken skal gennem samme antal

punkter som før, havde vi ikke forventet en forbedring her. Nedenfor kan

man se responstiderne mellem de to tests, den blå linje er testen med 3

instanser af hver service, og den grønne med 1:

Derimod er transaktioner pr sekund væsentligt forbedret. Det svarer dog ikke

til en 3 dobling, selvom der afvikles 3 gange så mange instanser.

En sammenligning af transaktioner pr sekund med henholdsvis 1 og 3

instanser af hver service er vist nedenfor, den blå linje er for testen med 3

instanser og den grønne med 1:

Page 38: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

38

5 Diskussion I forbindelse med at udføre performance test af de to applikationer, har vi

haft nogle udfordringer som har krævet noget tid, vi har beskrevet de større

udfordringer vi er stødt på nedenunder.

Der gik meget tid med at gøre testmiljøet klar før performance målingerne

kunne udføres.

Der blev anvendt en del Amazon instanser, disse skulle også konfigureres så

de kunne afvikle docker containers, og da der indgår mange af disse instanser

har det været tidskrævende.

Hvordan Amazon instanserne er opsat er beskrevet i bilag 9.7.

Vi havde iterativ tilgang til opsætningen af testmiljøet og udviklingen af

testdriveren.

Testdriveren startede med at baserede sig på REST kald, som den monolitiske

applikation allerede kunne modtage, og denne var den simpleste applikation

at deploye.

Herefter udviklede vi en testdriver til test af microservice på 1 server. Det

viste sig dog at overheaded ved at køre samme applikation som microservice,

var så stort, at det ikke var muligt at udføre en valid test.

Dernæst fik vi deployed microservice applikationen på hver sin server, som

har dannet grundlag for den ene test.

For at kunne teste flere instanser af hver microservice, opstod behovet for at

implementere RabbitMQ. Derfor ændrede vi testdriveren, til at gøre brug af

RabbitMQ.

Der har været anvendt en del forskellige teknologier i forbindelse med

opgaven, hvor nogle har været nye for os, især at skulle sætte sig ind i Spring

Boot har taget noget tid.

Der findes mange eksempler og dokumentation til Spring, men at overføre

dette til Spring Boot er ikke trivielt, da der er forskel på de to teknologier.

Warstory med Eventuate

Performance testen blev udført med flere forskellige konfigurationer, og over

flere gange.

Derfor var det nødvendigt at initiere testen flere gange, efter første gang

undrede vi os over at når applikationen blev initieret, så kunne vi se at

databasen begyndte at få flere requests og indsætte dokumenter.

Applikationen og database blev startet lokalt på vores egen PC, for at

fejlsøge, også her kom der en del trafik, så meget at vores egen internet linje

blev maxet ud ved 100mbit downstream.

Efter noget tid stoppede applikationen med at virke.

Page 39: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

39

Lidt tid efter skrev Chris Richardson, som har udviklet Eventuate til den email

vi havde registreret os med:

Hi,

Because of the excessive load on the server I have temporarily suspended

your account.

At some point I plan to implement per-user quotas but until I can do that I

just need you limit the number of requests.

Please let me know when you have resolved this issue.

Thanks.

Chris

Vi skrev tilbage til ham og undskyldte naturligvis, og forklarede samtidig at vi

var i gang med en hovedopgave hvor vi blandt andet kiggede på performance

i microservice sammenhæng, og derfor lavede den mængde forespørgsler.

Vi fortalte at vi bruger hans eksempel applikation til at teste med.

Da vi havde haft problemer med at hver gang vi startede applikationen op

igen, startede den med at opdatere mongoDB med alle de tidligere

forespørgsler der har været lavet, efterspurgte vi en løsning til dette

problem, som vi var i gang med at fejlsøge lokalt.

Vi troede det var i forbindelse med en fejl vi havde lavet, og skrev samtidig til

Chris om hvad der kunne være galt, og fik følgende svar :

Thanks for getting back to me.

Very interesting.

It is great that you are using Eventuate.

A few points:

One of the features of event-driven architectures is that you need to process

the events you generate.

However, to make development easier we are working on a way to allow you

to "reset" a subscription to mark events as having been read.

In the meantime, there is an experimental feature known as a space that is

associated with your account.

Think of it as a namespace.

Page 40: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

40

You should be able to "forget" about everything you have done so far but

specifying a different space.

The configuration property is eventuate.space (like eventuate.api.key.id) so

you can, for example, specify it using the environment variable

EVENTUATE_SPACE=space2

Please let me know whether this solves the problem.

Thanks.

Chris

Meget positivt svar, der i den grad var med til at hjælpe os videre. Vi har

efterfølgende fået lov til at køre tests i perioden indtil vi skal aflevere

opgaven.

RabbitMQ og Spring Boot

Vi havde brug for at benytte en asynkron forbindelse i applikationen for at

kunne skalere yderligere. Valget blev RabbitMQ, men det viste sig at

dokumentationen for RabbitMQ i Spring Boot var utrolig mangelfuld.

Efter utallige søgninger på nettet, har vi fundet én tutorial på nettet

omhandlende Spring Boot og RabbitMQ.

Denne tutorial viste sig også at være utrolig mangelfuld da den viser et kode

eksempel og langtfra forklarer alt hvad der er gjort i kode eksemplet, derfor

har vi været nødt til at eksperimentere en del, hvilket var enormt

tidskrævende.

Desuden var eksemplet skrevet således at alt koden for både producer og

consumer lå samlet så man ikke havde nogen idé om hvad der skulle bruges

hvor, for at gøre forvirringen komplet var eksemplet også baseret på at

RabbitMQ var installeret og kørte lokalt. Måske for nemheds skyld, men

bidrog absolut ikke til forståelsen, og næppe sådan det ville skulle benyttes i

et rigtigt setup.

Vi havde kigget de tutorials igennem der ligger på RabbitMQ´s hjemmeside,

og der er flere forskellige komponenter som blandt andet connectionfactory,

connection, Channel som vi ikke kunne finde i Spring Boot.

Vi fandt ud af at i Spring Boot får man en connectionfactory, og en

rabbittemplate foræret ved at definere at man har en dependency til ampq.

Det gør at man ikke selv skal tænke på at lave sådanne når man skal benytte

RabbitMQ, men når man ikke er vant til at de ting er abstraheret væk,

forvirrer det.

Page 41: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

41

Der er flere forskellige metoder der kan benyttes for at angive adressen på

den RabbitMQ server man ønsker at benytte. Angiver man ikke noget er

<localhost> default.

Man kan i koden i configurationen få fat i den connectionfactory der er

default, og benytte de setmetoder der er på host og port.

Man kan også angive parameteren rabbitmq_server_adress : <ip adresse> i

en application.properties fil.

Da vi bruger docker containere, og docker-compose er der også muligheden

for at bruge den samme parameter rabbitmq_server_adress <ip-adresse>

som env properties i docker-compose filen. Det har den fordel at det afkobler

fuldstændig RabbitMQ server adressen fra koden, og gør at vi ikke skal til at

rette kode, og lave nye docker images når vi ændrer ip adressen på en

RabbitMQ server.

Gradle og Eclipse

Vi har brugt Eclipse og gradle i forbindelse med udvikling og tilretning af

kode. Da vi skulle tilføje RabbitMQ til applikationen blev det gjort ved at vi

tog udgangspunkt i én enkelt af de 3 services, fik rettet build.gradle filen til

med den nødvendige dependency, og rettede koden til, og efterfølgende

testet af. Som tidligere beskrevet i afsnittet omkring RabbitMQ i Spring Boot,

var der en del vi skulle have prøvet af og rettet til før det kom til at virke, men

det lykkedes for den ene service. Derefter gik vi i gang, måske for hovedløst,

med at kopiere alle de samme rettelser ud til de andre services. Det krævede

selvfølgelig en del rettelser i gradle build filerne, samt kode, og da alle

rettelserne var på plads, prøvede vi at bygge projektet med henblik på at

teste det af.

Det kunne ikke bygge overhovedet, og efterfølgende skete der en del

underlige fejl, blandt andet hvor JRE var fjernet, så den ikke kunne kompilere,

der var ændringer i build path, og en del andre. Vi brugte en del tid på at få

fundet ud af hvad der var galt, og søgninger på blandt andet stackoverflow

hjalp ikke meget, idet at mange skrev at det muligvis var en bug i eclipse.

Et par af fejlene var blandt andet:

The type java.lang.Object cannot be resolved. It is indirectly referenced from

required .class files

Build path contains duplicate entry:

'org.eclipse.jdt.launching.JRE_CONTAINER'

Page 42: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

42

Vi læste at man kunne slette alle eclipse filerne, og bygge forfra ved at skrive

gradle cleanEclipse, efterfulgt af gradle buildEclipse, men det hjalp desværre

heller ikke.

Efter at have brugt rigtig meget tid på fejlsøgning, tog vi beslutningen om at

starte fuldstændigt forfra for at være sikker på at vi havde en ren brugbar

version.

Eclipse blev installeret forfra i en ny version, koden blev hentet ned, lavet

versionsstyring i GIT, og så blev rettelserne tilføjet små skridt af gangen, og

testet af hver gang der var lavet tilføjelser, og efterfølgende opdateret

versionen. Det tog noget tid, men så havde vi en version vi var sikre på

virkede.

Konklusionen må være at vi desværre ”glemte” de dicipliner vi lærte i

fagpakken ”Programmering af Store Objektorienterede Systemer” med at

tage små skridt, refaktorisere, og bruge versionsstyring mere aktivt, en vigtig

lektie lært på den hårde måde.

Warstory med gamle Docker images

Vi valgte at bruge docker containere i forbindelse med deployment, for ikke

at skulle koncentrere os om at køre med forkerte konfigurationer i

forbindelse med afvikling af kode i amazon cloud, hvilket dog ikke helt viste

sig at være sandt hver gang.

I forbindelse med en tilretning af koden, var vores normale procedure at vi

rettede koden lokalt, testede lokalt at rettelserne var ok, hvorefter vi

byggede et nyt docker image, og samtidigt uploadede det til dockerhub.

På den måde skulle vi så kun tilrette docker-compose filen på den givne

instans som det eneste, og derefter starte den op, eller genstarte den.

Det vil sige at vi ubesværet kunne stoppe de/den docker containere på den

givne instans der var startet med docker-compose ved ctrl-c, og derefter

starte den/de op igen med kommandoen docker-compose up.

Docker-compose skulle så sammenligne den/de docker images der lå på

instansen, med dem som var refereret i docker-compose filen, og downloade

fra dockerhub hvis der var en nyere version af docker imaget i repositoriet.

Det virker som det skal når vi prøvede det af lokalt på vores egne maskiner,

men vi kunne observere at ændringerne ikke kom med når vi benyttede

samme fremgangsmåde i Amazon instanserne, og det voldte os en del

problemer i forbindelse med testene.

Page 43: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

43

Vi har søgt efter en forklaring på nettet, men er ikke blevet meget klogere på

hvad årsagen kan være, et bud kunne være et problem med en cache som

ikke er opdateret, og derfor ikke ser at der findes en ny version af det image.

I stedet fandt vi en måde at slette alt vedr Docker images, og dermed tvinge

den til at hente nye images, så rettelserne kommer med.

Fremgangsmåden er:

docker-compose rm – for at slette de referede docker images i

docker-compose filen.

rm <folder navn ex. Account-command-service> -r – sletter de fysiske

filer.

Docker images – for at få vist de docker images der er hentet.

Kopier image id på docker instansen.

Docker rmi -f <image id> - sletter det pågælde docker image.

Start op igen ved at skrive: docker-compose up.

Page 44: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

44

6 Relateret arbejde I fagpakken Software Arkitektur i Praksis, lavede vi som projekt en

performance evaluering af MongoDB.

Værktøjerne til udførelsen af performance test har taget udgangspunkt i Jens

Edlef Møllers guide til Performance Engineering [Møller, 2012], som blev

præsenteret ved fagpakken Software Arkitektur i Praksis.

Dog er der anvendt nyere versioner end der blev præsenteret dengang, samt

efterfølgere til det plugin som Jens henviste til.

Page 45: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

45

7 Konklusion Hypotesen

Applikationen opbygget over en microservice arkitektur, har en højere

responstid end den monolitisk opbygget webside, ved en kontinuerlig

mængde service kald igennem 30 minutter.

Responstiden er højere for applikationen med microservices ved de første 10

minutter af testen, sammenlignet med den monolitiske applikation.

Throughput er på samme niveau som den microservice baserede applikation

de første 10 minutter af den monolitiske applikation.

Applikationen med microservices har også samlet set 4 Amazon micro

instanser, mod den monolitiske der har 1 medium instans.

At have MongoDB databasen på samme server som den monolitiske

applikation, har givet både fordele og ulemper.

Fordelen er en lavere responstid, da man slipper for et netværkskald.

I første omgang kan det virke som et unfair setup set ud fra et

sammenligningsgrundlag. Men den monolitiske applikation har blot fået

optimale betingelser for performance. En arkitektur på microservices giver

ikke mulighed for denne optimering.

Ulempen var som man kunne se i løbet af testen at utilization af serveren

steg, hvilket gjorde løsningen langsommere ved kontinuerlig høj belastning.

Kraftigere hardware kunne naturligvis have udsat tidspunktet for hvor meget

load der skulle genereres før dette indtræffer.

Antallet af threads JMeter havde kørende kunne også være sænket, men var

bevidst ikke sat ned til et punkt hvor denne degradering i performance ville

være skjult.

Større applikationer har ofte databasen på en anden server end

applikationen. Dette vil naturligvis øge responstiden, vi valgte derfor de

optimale betingelser.

Kigger man isoleret på de første 10 minutter af testen, har den monolitiske

applikation således lavere responstid end microservice.

Måler man efter 90% linjen over hele testen er microservice applikationen

hurtigere.

Derfor er konklusionen at den microservice baserede applikation kan have

højere responstid end den monolitiske applikation.

Dog er en af fordelene i en microservice arkitektur, at der er lettere mulighed

for at skalere ens services, derfor finder vi næste del af hypotesen

interessant.

Page 46: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

46

Hypotesen

Applikationen opbygget over en microservice arkitektur med 3 instanser af

hver service, har en lavere responstid og højere throughput end den

monolitisk opbyggede webside, ved en kontinuerlig mængde service kald

igennem 30 minutter.

Testen med 3 instanser af hver service viste et højere throughput.

Responstiden var nærmest uændret fra testen med 1 instans af hver service,

dog set over hele testen er den lavere end den monolitiske applikation.

Når man ser på allocation viewpoint for denne opsætning, er der en del

netværkskald mellem servere. Derfor kan det være vanskeligt at opnå en

markant lavere responstid.

Responstid og throughput var tilfredsstillende i forhold til den opstillede QAS,

og konklusionen er at med 3 instanser af hver service opnår den microservice

baserede applikation højere throughput, men at responstiden nødvendigvis

ikke er forbedret.

En afledt effekt vi bemærkede under vores tests, var at microservices har en

negativ indvirkning på kvalitetsattributten testability.

Der skulle bruges betydelig ekstra tid på at opsætte et testmiljø med

microservices, end der skulle med den monolitiske.

Selvom Amazons web interface fungerer godt, så tager det alligevel noget tid

at starte fx 9 servere, ssh til dem og starte applikationen.

Page 47: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

47

8 Referencer Martin Fowler, Microservices:

http://martinfowler.com/articles/microservices.html

Abbott et. al., Scale Cube:

http://akfpartners.com/techblog/2008/05/08/splitting-applications-or-

services-for-scale/

Chris Richardson, Scale Cube:

http://microservices.io/articles/scalecube.html

Microservices.io: http://microservices.io/

Eventuate: http://eventuate.io/

Martin Fowler, CQRS: http://martinfowler.com/bliki/CQRS.html

microxchg 2015: http://microxchg.io/2015/index.html

Martin Fowler, Event Sourcing:

http://martinfowler.com/eaaDev/EventSourcing.html

Gilbert et al., 2002: http://dl.acm.org/citation.cfm?id=564585.564601

Spring Boot: http://projects.spring.io/spring-boot/

Chris Richardson, Money transfer: https://github.com/cer/event-

sourcing-examples

Docker Compose: https://docs.docker.com/compose/

Docker networks:

https://docs.docker.com/engine/userguide/networking/work-with-

networks/#connect-containers

Apache JMeter: http://jmeter.apache.org/

JMeter FAQ: http://wiki.apache.org/jmeter/JMeterFAQ

Amazon EBS: https://aws.amazon.com/ebs/

BlazeMeter Sense: https://sense.blazemeter.com/features/

Bass et al., 2003: Bass, L., Clements, P., and Kazman, R. (2003). Software

Architecture in Practice, 2nd Edition, Addison Wesley, 2003. ISBN:

0321154959

Gradle: http://gradle.org/

Elastic Load Balancing: https://aws.amazon.com/elasticloadbalancing/

Møller, 2012: https://cs.au.dk/~baerbak/c/saip/resource/pe-tools.pdf

Debian Aptitude:

http://packages.debian.org/search?keywords=aptitude

Christensen et al., 2012:

https://cs.au.dk/~baerbak/c/saip/notes/christensen2012.pdf

Page 48: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

48

9 Bilag

9.1 Docker compose - microservice Her er 5 Docker-compose filer. En til hver server.

Links i Docker compose filer virker ikke på tværs af servere. Derfor er

parameteren extra_hosts sat ind, som på samme måde som link indsætter en

mapping i /etc/hosts. Denne værdi skal dog sikres har den rette IP adresse

inden containerne startes.

accountscommandside: image: birkholm/accounts-command-side-service working_dir: /app volumes: - ./accounts-command-side-service/build/libs:/app command: java -jar /app/accounts-command-side-service.jar ports: - "8080:8080" environment: EVENTUATE_API_KEY_ID: 62BB0DU84C3YXAM79KKC9I21E EVENTUATE_API_KEY_SECRET: EVENTUATE_SPACE: space5 SPRING_RABBITMQ_HOST: 52.19.168.215

transactionscommandside: image: birkholm/transactions-command-side-service working_dir: /app volumes: - ./transactions-command-side-service/build/libs:/app command: java -jar /app/transactions-command-side-service.jar ports: - "8080:8080" environment: EVENTUATE_API_KEY_ID: 62BB0DU84C3YXAM79KKC9I21E EVENTUATE_API_KEY_SECRET: EVENTUATE_SPACE: space2 SPRING_RABBITMQ_HOST: 52.19.168.215

accountsqueryside: image: birkholm/accounts-query-side-service working_dir: /app volumes: - ./accounts-query-side-service/build/libs:/app command: java -jar /app/accounts-query-side-service.jar ports:

Page 49: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

49

- "8080:8080" extra_hosts: - "mongodb:52.50.56.169" environment: EVENTUATE_API_KEY_ID: 62BB0DU84C3YXAM79KKC9I21E EVENTUATE_API_KEY_SECRET: EVENTUATE_SPACE: space2 SPRING_DATA_MONGODB_URI: mongodb://mongodb/mydb SPRING_RABBITMQ_HOST: 52.19.168.215

rabbitmq:

image: rabbitmq:3-management

hostname: rabbitmq

ports:

- "5672:5672"

- "15672:15672"

testdriverrabbitmq:

image: birkholm/test-driver-rabbitmq

working_dir: /app

hostname: testdriver

command: java -jar /app/test-driver-rabbitmq.jar

ports:

- "8090:8090"

extra_hosts:

- "mongodb:52.50.56.169"

environment:

SPRING_DATA_MONGODB_URI: mongodb://52.50.56.169/mydb

mongodb: image: mongo:3.0.4 hostname: mongodb command: mongod ports: - "27017:27017"

Page 50: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

50

9.2 Docker compose – monolitiske Der er to Docker compose filer, da applikationerne skal afvikles fra to

servere.

monolithic:

image: birkholm/monolithic-service

working_dir: /app

hostname: monolithic

command: java -jar /app/java-mono.jar

ports:

- "8080:8080"

links:

- mongodb

environment:

SPRING_DATA_MONGODB_URI: mongodb://mongodb/mydb

SPRING_RABBITMQ_HOST: 52.19.168.215

mongodb:

image: mongo:3.0.4

hostname: mongodb

command: mongod

ports:

"27017:27017"

rabbitmq:

image: rabbitmq:3-management

hostname: rabbitmq

ports:

- "5672:5672"

- "15672:15672"

testdriverrabbitmq:

image: birkholm/test-driver-rabbitmq

working_dir: /app

hostname: testdriver

command: java -jar /app/test-driver-rabbitmq.jar

ports:

- "8090:8090"

extra_hosts:

- "mongodb:52.50.56.169"

environment:

SPRING_DATA_MONGODB_URI: mongodb://52.50.56.169/mydb

Page 51: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

51

9.3 Gradle Integration med docker

I hver applikation der skal deployes, hvor der er en tilhørende gradle build fil,

skal der laves ændringer i gradle build scriptet.

I dependencies skal der tilføjes en dependency til docker librariet, hvilket gør

det muligt at udnytte docker relaterede elementer i koden, og i forbindelse

med bygge processen.

Ex. Fra Test-driver applikationen

buildscript {

repositories {

mavenCentral()

}

dependencies {

classpath("org.springframework.boot:spring-boot-gradle-

plugin:1.3.2.RELEASE")

classpath('se.transmode.gradle:gradle-docker:1.2')

}

}

Der tilføjes en group, som er navnet på det docker repository der skal bruges

i applikationen til f.eks. push, pull osv.

group = 'birkholm'

Der skal tilføjes et plugin, så det er muligt at bruge docker specifikke

kommandoer i gradle scriptet.

apply plugin: 'docker'

Og til sidst skal selve der konstrueres selve den task der skal bruges til at lave

arbejdet med at referere til en Dockerfile med oplysninger om

konstruktionen af docker containeren, samt hvad der skal gøres med den

Page 52: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

52

konstruerede docker container. I det her tilfælde skal der laves en push til

dockerhub repositoriet.

task buildDocker(type: Docker, dependsOn: build) {

push = true

applicationName = jar.baseName

dockerfile = file('build/libs/Dockerfile')

doFirst {

copy {

from jar

into stageDir

}

}

}

Den nye build.gradle script vil efter ændringerne så se sådan ud for Test-

driver applikationen.

buildscript {

repositories {

mavenCentral()

}

dependencies {

classpath("org.springframework.boot:spring-boot-gradle-

plugin:1.3.2.RELEASE")

classpath('se.transmode.gradle:gradle-docker:1.2')

}

}

group = 'birkholm'

apply plugin: 'java'

apply plugin: 'eclipse'

apply plugin: 'idea'

apply plugin: 'spring-boot'

apply plugin: 'docker'

jar {

baseName = 'test-driver'

}

Page 53: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

53

repositories {

mavenCentral()

}

sourceCompatibility = 1.8

targetCompatibility = 1.8

dependencies {

compile("org.springframework.boot:spring-boot-starter-web") {

}

compile("org.springframework.boot:spring-boot-starter-data-mongodb")

compile ("org.apache.commons:commons-collections4:4.0")

compile ("org.apache.httpcomponents:httpcore:4.4.1")

compile ("org.apache.httpcomponents:httpclient:4.5")

compile("org.springframework.boot:spring-boot-starter-actuator")

testCompile("junit:junit")

}

task wrapper(type: Wrapper) {

gradleVersion = '2.3'

}

task buildDocker(type: Docker, dependsOn: build) {

push = true

applicationName = jar.baseName

dockerfile = file('build/libs/Dockerfile')

doFirst {

copy {

from jar

into stageDir

}

}

}

I den task er der blandt andet en reference til en dockerfile, i det her tilfælde

ligger den placeret i build/libs/ netop fordi det er der jar filen med selve

applikationen ligger placeret.

Page 54: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

54

For at afvikle det nye gradle task skrives der :

gradle buildDocker

I det task der hedder buildDocker er der en dependency til build, så ved

kørsel vil den først kompilere og samle selve projektet, og ved succes, dvs

ingen fejl vil den lave en push til det angivne repository i Docker Hub.

Page 55: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

55

9.4 Implementering af RabbitMQ På producer siden skal der gøres følgende for at kreere og sende en besked

til en RabbitMQ server, der er taget udgangspunkt i en basal type

messagequeue med én producer, og én eller flere consumere:

Produceren i dette tilfælde er vores testdriver der sender til RabbitMQ i

stedet for at lave rest kald, som oprindeligt i Chris’ applikation.

For overhovedet at kunne benytte RabbitMQ i Spring Boot skal der angives

en dependency i gradle build filen, til amqp frameworket hvor RabbitMQ er

inkluderet i.

compile("org.springframework.boot:spring-boot-starter-amqp")

Alt omkring configurationen af RabbitMQ laves i en konfigurationsfil i Spring

Boot.

Vi har kaldt vores RabbitConfiguration, og den skal annoteres med

@Configuration.

Der skal angives en instansvariabel for hver af de køer man ønsker at benytte,

ex:

final static String queueNameAccountCommand =

"accountCommand";

En Bean der laver en ny Queue instans udfra navnet og returnerer den, vi har

valgt at sætte durability til false, hvilket betyder at den pågældende kø ikke

overlever en server restart, for at vi ikke skulle risikere at gamle beskeder

påvirker vores test, derudover har det også en negativ indvirkning på

performance at skulle persistere disse beskeder.

@Bean

Queue queueAccountCommand() {

return new Queue(queueNameAccountCommand, false);

}

En Bean der definerer navnet på den Exchange man ønsker at benytte samt

returnerer en ny instans af den. I ampq modellen skriver man ikke direkte til

en kø, men i stedet til en exchange der sørger for at distribuere beskederne

til den kø der er lavet en binding til.

Page 56: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

56

Der er flere forskellige typer af exchanges der hver har deres eget formål

efter hvilken model man ønsker at benytte. Vi har valgt at bruge en Topic

Exchange, da den giver os de muligheder vi har brug for.

@Bean

TopicExchange accountExchange() {

return new TopicExchange("accountcommand-exchange");

}

Derudover skal der laves en Bean der laver en binding, imellem kø navn og

instans.

@Bean

Binding bindingAccountCommand(Queue queueAccountCommand,

TopicExchange accountExchange) {

return BindingBuilder.bind(queueAccountCommand)

.to(accountExchange)

.with(queueNameAccountCommand);

}

Derefter er selve integrationen til RabbitMQ på plads, og der vil kunne

produceres beskeder kan sendes.

Til at generere beskederne har vi de enkelte rest controllere i testdriveren

der modtager et request, og omdanner det til en besked til RabbitMQ hvor

den sender det til den tilhørende exchange.

For eksempelvis CreateAccountController, har følgende implementering for

at sende til RabbitMQ.

Først en instansvariabel der angiver det kø navn man ønsker at benytte.

final static String queueNameAccountCommand = "accountCommand";

En autowire på rabbitTemplate, der findes en default rabbitTemplate i Spring

Boot man kan bruge til at arbejde med de forskellige køer.

@Autowired

RabbitTemplate rabbitTemplate;

I metoden kan der så benyttes den rabbitTemplate til at sende en besked til

køen ”accountCommand” med en BigDecimal værdi på 100000, som vi har

angivet som initial værdi ved oprettelse af en konto.

Page 57: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

57

rabbitTemplate.convertAndSend(queueNameAccountCommand,

new BigDecimal(1000000) );

På consumer siden som er vores applikation under test, skal der laves den

samme konfiguration som på producer siden, det vil sige en kø, en exchange

samt en binding i mellem.

Ud over skal der og laves en Receiver. En receiver er en klasse man laver der

modtager den pågældende besked fra MQ, der er intet specielt over klassen,

det er en regulær POJO.

I konfigurationsfilen laves der en Bean, der laver en instans af den

ovennævnte receiver.

@Bean

TransferReceiver receiver() {

return new TransferReceiver();

}

Der skal laves en ListenerAdapter der har til formål at lave en Listener, hvor

man definerer hvilken klasse der er receiver, samt hvilken metode der skal

kaldes når der modtages en besked på køen.

I det her eksempel har vi en klasse der hedder TransferReceiver, og det er i

metoden receiveMessage beskeden bliver modtaget i.

@Bean

MessageListenerAdapter listenerAdapter(TransferReceiver receiver) {

return new MessageListenerAdapter(receiver, "receiveMessage");

}

Slutteligt skal der laves en container der lytter efter beskeder på den kø der

skal lyttes på, ud fra den definerede listener, samt binder listener sammen

med den default connectionFactory der er indbygget i Spring Boot.

Page 58: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

58

@Bean

SimpleMessageListenerContainer container(ConnectionFactory

connectionFactory, MessageListenerAdapter listenerAdapter) {

SimpleMessageListenerContainer container =

new SimpleMessageListenerContainer();

container.setConnectionFactory(connectionFactory);

container.setQueueNames(requestQueueName);

container.setMessageListener(listenerAdapter);

return container;

}

Nu kan der etableres kontakt fra Consumer siden til MQ exchange. For at

kanalisere beskederne videre i applikationen benyttes de samme kald som er

i de eksisterende rest controllere, ex for klassen AccountController, har vi

lavet en ny klasse i samme pakke kaldet AccountReceiver, der laver et kald til

samme metode som AccountController gør når den modtager et rest kald.

public class AccountReceiver {

@Autowired

private AccountService accountService;

public AccountReceiver() {

}

public void receiveMessage(BigDecimal message) {

accountService.openAccount(message);

}

}

Page 59: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

59

9.5 Konfiguration af performance test Klienten forbinder til JMeter Engine på port 1099.

Derudover bruges Java RMI til at forbinde fra JMeter Engine tilbage til JMeter

til at sende resultaterne.

RMI anvender som standard en dynamisk port til at forbinde.

Da JMeter Engine afvikles på Amazons servere, der som standard ikke tillader

indgående trafik, skal der åbnes en port i Amazons administrations interface,

som vist herunder ved at gå ind og ændre security group.

Derefter skal RMI anvende en statisk port, dette opsættes i

konfigurationsfilen jmeter.properties, hvor følgende linjer normalt er

udkommenteret, i den sidste linje fjernes kommentaren som vist herunder,

hvorefter port 4000 vil blive anvendt.

# Parameter that controls the RMI port used by the

RemoteSampleListenerImpl (The Controler)

# Default value is 0 which means port is randomly assigned

# You may need to open Firewall port on the Controller machine

client.rmi.localport=4000

For hver server hvor JMeter skal afvikles på startes JMeter i server mode med

følgende kommando efterfølgende, hvor IP-adressen i parameteren svarer til

den public IP adresse Amazon serveren har:

JMETER_HOME/bin/jmeter-server -Djava.rmi.server.hostname=52.51.147.37

Page 60: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

60

Grunden til at serverens public IP adresse skal medsendes som parameter, er

at måden Amazons netværk fungerer på, da JMeter ellers får serverens

interne IP adresse, og dermed ikke kan forbinde med RMI.

Herefter skal JMeter klienten opsættes, først skal den konfigures med IP

adresser på de Amazon servere hvor JMeter Engine kører, dette gøres også i

jmeter.properties.

Her angives ip-adresserne på hver server kommasepareret

# Remote Hosts - comma delimited

remote_hosts= 52.50.241.119,52.51.147.37,52.51.193.142

Ip-adresserne findes ligeledes I Amazons administrations interface, som vist

herunder:

Derudover skal man sikre at indgående trafik på port 4000 er åbnet såfremt

der kører en firewall på denne computer, så resultater fra JMeter Engine kan

modtages.

Ligeledes erfarede vi gennem længere tids fejlsøgning, at såfremt

computeren hvorfra JMeter skal opsamle resultater er bag NAT, er det

nødvendigt at starte JMeter på følgende måde, her vist hvor computeren

kører Windows:

jmeter.bat -Djava.rmi.server.hostname=80.162.197.54

Slutteligt startes testen i JMeter hvor der vælges Remote Start All som vist

herunder, vælges der kun Start, enten i menuen eller på den tilhørende knap,

så får man ikke et retvisende billede af sin performance test da det kun er

den ene instans af JMeter som starter:

Page 61: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

61

Page 62: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

62

9.6 JMeter opsætning af testplan Der skal konfigureres en del I JMeter for at opsætte en fornuftig testplan.

Først er der indsat en Thread group, den er af typen Concurrency thread

group, hvor man kan opsætte et vedvarende load, som vist herunder:

For at give det load der genereres et mere realistisk scenarie konfigureres der

think time for hver thread, som er en tilfældig pause der ventes indtil næste

forespørgsel sendes, dette gøres ved at tilføje en timer som vist her:

Page 63: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

63

Da der er flere REST endpoints i vores applikationer, er det ikke muligt blot at

sende en forespørgsel til samme adresse konstant, der skal veksles mellem

de forskellige endpoints, det gøres med en logic controller. Nedenfor er vidst

en logic controller af typen bzm – weighted switch controller, hvor man kan

konfigurere vægtningen af de forskellige requests der foretages:

Når man har flere requests i sin test, skal der opsættes IP adresse og port for

hver, dog vil de i de fleste tilfælde være ens, og det vil være path der i stedet

er forskellig. For ikke at indtaste IP adresse og port flere steder, men blot

have et samlet sted at konfigurere dette er der tilføjet et konfigurations

element til testplanen af typen HTTP Requests Defaults:

Page 64: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

64

Slutteligt er hver HTTP request opsat, ved at tilføje en sampler af typen HTTP

Request. Bemærk at her ikke er indtastet IP-adresse eller port, da den

anvender indstilingerne fra HTTP Requests Defaults:

Page 65: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

65

Visualisering af resultater

Til at visualisere responstid og throughput af loadtests anvendes et plugin til

JMeter kaldet BM.Sense Uploader.

Den uploader resultaterne efter endt test til BlazeMeter Sense [BlazeMeter

Sense], hvor målingerne analyseres og derefter kan ses i en graf.

Pluginet kræver man opretter en konto på sense.blazemeter.com, hvor man

får en upload token som indtastes i det pågældende plugin. Derved ved

den hvilken bruger de pågældende målinger hører til.

Nedenunder kan man se hvor upload token skal indtastes. Man skal tilføje

en listener af typen bzm – BlazeMeter Sense Uploader, hvori det skal

indtastes:

Page 66: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

66

Pluginet er en del af en større samling plugins til JMeter kaldet Standard Set

som findes her: http://jmeter-plugins.org/wiki/StandardSet/

Installationen er simpel, man downloader en zip fil som skal udpakkes i

JMeter biblioteket, derefter skal JMeter genstartes.

Dette skal kun gøres på den instans af JMeter som fungerer som master, og

opsamler data fra de andre instanser af JMeter, da den så vil være ansvarlig

for at uploade resultaterne efter endt test.

Page 67: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

67

9.7 Opsætning af Amazon instanser Her en beskrivelse af fremgangsmåden på hvordan Amazon EC2 er blevet

brugt til at konfigurere instanserne i testmiljøet.

Inden der blev begyndt at oprette instanser blev der lavet en VPC, som er et

privat virtuelt cloud, hvor instanserne kommer til at køre.

I VPC dashboardet vælges der ’Create VPC’

Der er et par forberedende ting der skal være på plads inden der laves

instanser, de behøver ikke nødvendigvis at gælde alle instanser, men til vores

brug har vi brugt samme key pair og security group til alle instanser vi har

kørt.

Der skal først laves et key pair der kan tilknyttes en given instans, således at

sikkerheden med hensyn til adgang via SSH er på plads til en instans.

Det gøres i EC2 dashboardet under menupunktet Network and Security ->

Key Pairs og vælg ’Create Key Pair’

Dernæst skal der laves en security group der ligeledes bliver tilknyttet en

instans. En security group definerer hvordan adgangen skal være til

instansen, dvs. hvilke porte der skal være åbne.

Vælg Network and Security -> Security Groups og vælg ’Create Security

Group’.

Page 68: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

68

Her angiver man de porte der skal åbnes, og for hvilken protokol.

VPC sættes til den VPC vi tidligere har lavet.

Base instans

Vi har valgt at lave en base instans af den type instans vi vil bruge til alle

vores servere, denne blev der taget et snapshot af, så man hurtigt og enkelt

kan starte nye instanser op med den samme grund konfiguration.

Måden base instansen blev lavet, var ved først at starte en ny Ubuntu instans

som vist nedenfor:

Vælg ’Launch Instance’

Efterfølgende blev der tilknyttes den security group samt key pair som der

blev lavet tidligere.

Når instansen er startet op, er der blevet installeret docker-compose, så der

kan startes docker containere op, og dermed ikke er afhængig af andre

programmer som java, mongoDB, rabbitMQ mv.

Følgende guide er blevet brugt for at installere docker compose hvor der

anvendes Debian Aptitude, som er en pakkemanager [Debian Aptitude]:

(https://docs.docker.com/engine/installation/linux/ubuntulinux/ )

Nu er den overordnede base lavet og der kan laves et snapshot.

Nedenstående er mest relevant hvis man har flere instanser, da man skal

bruge volume ID på den instans man vil lave et snapshot af.

Vælg menupuktet Elastic Block Store -> Volumes

Her vises en oversigt over de volumes der er tilknyttet de enkelte instanser,

under attachment Information står instans navnet.

Page 69: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

69

Vælg menupunktet Elastic Block Store – Snapshots, og tryk ’Create Snapshot’

Der skal indtastes det Volume ID fra tidligere.

Klik på ’Create’ og der bliver dannet et snapshot.

Højreklik efterfølgende på det dannede snapshot og vælg ’Create Image’, i

Virtualization type skal der vælges Hardware-assisted virtualization.

Under menupunktet Images -> AMIs vil der nu ligge det image der lige er

blevet lavet.

Når der skal startes en ny instans udfra det givne image, vælges der en af de

AMI images, og trykkes ’Launch’.

Efter det basale microservice setup var lavet, med 1 server med mongoDB, 1

server med testdriveren, samt 1 server hver til henholdsvis de 3

komponenter i applikationen, er der taget et snapshot og image af hver af de

instanser som vi forventer skulle replikeres.

Page 70: Performanceevaluering af en microservice og monolitisk ...cs.au.dk/fileadmin/user_upload/Michael_og_Jesper-master-F16.pdf · 4.4 JMeter ... JMeter Engine http http:Docker container

70

Fast ip-adresse

For henholdsvis mongoDB, testdriveren, samt RabbitMQ har det været mest

hensigtsmæssigt at have en fast ip adresse, så vi ikke skal rette i samtlige

docker-compose filer på hver enkelt instans hver gang vi har skulle starte en

ny test, og instanserne har været stoppet.

Derfor er der tilknyttet en række ip adresser til de pågældende instanser.

I VPC dashboardet vælges menupunktet Virtual Private Cloud, og ’Allocate

New Adress’

Når ip adressen er allokeret, og den fremgår i oversigten højreklikkes og

vælges ’associate adress’

Ved næste dialog kan der vælges den instans, hvor ip adressen skal tilknyttes.