Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Först lite teori. Vad har hänt Tolvfaktorappen?

Med enkla ord är det här dokumentet utformat för att förenkla utvecklingen av SaaS-applikationer, genom att informera utvecklare och DevOps-ingenjörer om de problem och tillvägagångssätt som oftast stöter på vid utvecklingen av moderna applikationer.

Dokumentet skapades av utvecklarna av Heroku-plattformen.

Tolvfaktorsappen kan appliceras på applikationer som är skrivna på vilket programmeringsspråk som helst och med vilken kombination av stödtjänster som helst (databaser, meddelandeköer, cachar, etc.).

Kortfattat om de faktorer som denna metod bygger på:

  1. Kodbas – En kodbas spårad i versionskontroll – flera distributioner
  2. Beroenden – Deklarera och isolera beroenden uttryckligen
  3. konfiguration – Spara konfigurationen under körning
  4. Uppbackningstjänster – Överväg stödtjänster som plugin-resurser
  5. Bygg, släpp, spring – Separera monterings- och utförandestegen strikt
  6. Processerna – Kör applikationen som en eller flera tillståndslösa processer
  7. Portbindning – Exporttjänster via hamnbindning
  8. Parallellism – Skala din ansökan med hjälp av processer
  9. Disponibilitet – Maximera tillförlitligheten med snabb start och ren avstängning
  10. Applikationsutveckling/driftsparitet – Håll dina utvecklings-, iscensättnings- och produktionsmiljöer så lika som möjligt
  11. Skogsavverkning – Se loggen som en ström av händelser
  12. Administrationsuppgifter – Utföra administrations-/ledningsuppgifter med hjälp av ad hoc-processer

Du kan få mer information om de 12 faktorerna från följande resurser:

Vad är Blue-Green-distribution?

Blue-Green distribution är en metod för att leverera en applikation till produktion på ett sådant sätt att slutkunden inte ser några förändringar från sin sida. Med andra ord, distribuera en applikation med noll stilleståndstid.

Det klassiska BG Deploy-schemat ser ut som det som visas i bilden nedan.

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

  • I början finns det 2 fysiska servrar med absolut samma kod, applikation, projekt, och det finns en router (balanserare).
  • Routern riktar initialt alla förfrågningar till en av servrarna (grön).
  • I det ögonblick du behöver släppa igen uppdateras hela projektet på en annan server (blå), som för närvarande inte behandlar några förfrågningar.
  • Efter att koden är på blå servern är helt uppdaterad får routern ett kommando att byta från grönblå server.
  • Nu ser alla klienter resultatet av koden som körs med blå server.
  • För en tid, grön servern fungerar som en säkerhetskopia i händelse av misslyckad distribution till blå server och vid fel och buggar växlar routern tillbaka användarflödet till grön server med den gamla stabila versionen, och den nya koden skickas för revision och testning.
  • Och i slutet av processen uppdateras den på samma sätt grön server. Och efter att ha uppdaterat den växlar routern tillbaka förfrågningsflödet till grön server.

Det hela ser väldigt bra ut och vid första anblicken borde det inte vara några problem med det.
Men eftersom vi lever i den moderna världen, passar inte alternativet med fysisk omkoppling som anges i det klassiska schemat oss. Anteckna informationen tills vidare, vi återkommer till den senare.

Dåliga och bra råd

Villkor: Exemplen nedan visar de verktyg/metoder som jag använder, du kan använda absolut alla alternativ med liknande funktioner.

De flesta av exemplen kommer på ett eller annat sätt att korsa webbutveckling (detta är en överraskning), med PHP och Docker.

Styckena nedan ger en enkel praktisk beskrivning av användningen av faktorer med hjälp av specifika exempel; om du vill få mer teori om detta ämne, följ länkarna ovan till originalkällan.

1. Kodbas

Använd FTP och FileZilla för att ladda upp filer till servrarna en i taget, lagra inte koden någon annanstans än på produktionsservern.

Projektet ska alltid ha en enda kodbas, det vill säga all kod kommer från en förvaret. Servrar (produktion, iscensättning, test1, test2...) använder kod från grenar av ett gemensamt arkiv. På så sätt uppnår vi kodkonsistens.

2. Beroenden

Ladda ner alla bibliotek i mappar direkt till projektets rot. Gör uppdateringar helt enkelt genom att överföra den nya koden till mappen med den aktuella versionen av biblioteket. Installera alla nödvändiga verktyg direkt på värdservern där ytterligare 20 tjänster körs.

Ett projekt ska alltid ha en klart begriplig lista över beroenden (med beroende menar jag också miljön). Alla beroenden måste vara explicit definierade och isolerade.
Låt oss ta som exempel Samman и Hamnarbetare.

Samman — en pakethanterare som låter dig installera bibliotek i PHP. Composer låter dig specificera versioner strikt eller löst och uttryckligen definiera dem. Det kan finnas 20 olika projekt på servern och varje kommer att ha en personlig lista med paket och bibliotek oberoende av varandra.

Hamnarbetare — ett verktyg som låter dig definiera och isolera miljön där applikationen ska köras. Följaktligen, precis som med kompositör, men mer ingående, kan vi avgöra vad applikationen fungerar med. Välj en specifik version av PHP, installera bara de paket som krävs för att projektet ska fungera, utan att lägga till något extra. Och viktigast av allt, utan att störa paketen och miljön för värddatorn och andra projekt. Det vill säga att alla projekt på servern som körs genom Docker kan använda absolut vilken uppsättning paket som helst och en helt annan miljö.

3. Konfiguration

Lagra konfigurationer som konstanter direkt i koden. Separata konstanter för testservern, separata för produktion. Koppla in applikationens drift beroende på miljön direkt i projektets affärslogik med hjälp av if else-konstruktioner.

konfigurationer - Detta är det enda sättet som projektutbyggnaderna bör skilja sig åt. Helst bör konfigurationer skickas genom miljövariabler (env vars).

Det vill säga, även om du lagrar flera konfigurationsfiler .config.prod .config.local och byter namn på dem vid tidpunkten för distributionen till .config (huvudkonfigurationen från vilken applikationen läser data) - kommer detta inte att vara rätt tillvägagångssätt, eftersom i detta fall kommer informationen från konfigurationerna att vara allmänt tillgänglig för alla applikationsutvecklare och data från produktionsservern kommer att äventyras. Alla konfigurationer måste lagras direkt i distributionssystemet (CI/CD) och genereras för olika miljöer med olika värden som är nödvändiga för en specifik miljö vid tidpunkten för driftsättningen.

4. Tredjepartstjänster

Var strikt knuten till miljön, använd olika anslutningar för samma tjänster i vissa miljöer.

Faktum är att denna punkt kraftigt överlappar punkten om konfigurationer, eftersom utan denna punkt inte kan normala konfigurationsdata göras och i allmänhet sjunker förmågan att konfigurera till ingenting.

Alla anslutningar till externa tjänster, såsom köservrar, databaser, cachningstjänster, måste vara desamma för både den lokala miljön och tredjeparts-/produktionsmiljön. Med andra ord, när som helst, genom att ändra anslutningssträngen, kan jag ersätta anrop till bas #1 med bas #2 utan att ändra applikationskoden. Eller om du ser framåt, som ett exempel, när du skalar tjänsten, behöver du inte ange anslutningen på något speciellt sätt för en extra cacheserver.

5. Bygg, släpp, exekvera

Ha bara den slutliga versionen av koden på servern, utan chans att återställa versionen. Inget behov av att fylla upp diskutrymme. Alla som tror att de kan släppa kod i produktion med ett fel är en dålig programmerare!

Alla steg i utbyggnaden måste separeras från varandra.

Har en chans att rulla tillbaka. Gör utgåvor med gamla kopior av applikationen (redan monterad och redo för strid) sparad i snabb åtkomst, så att du i händelse av fel kan återställa den gamla versionen. Det vill säga, villkorligt finns det en mapp utgåvor och mapp ström, och efter framgångsrik distribution och sammansättning mappen ström länkad av en symbolisk länk till den nya releasen som ligger inuti utgåvor med det konventionella namnet på releasenumret.

Det är här vi minns Blue-Green-distributionen, som gör att du inte bara kan växla mellan kod, utan också att växla mellan alla resurser och även miljöer med möjligheten att rulla tillbaka allt.

6. Processer

Lagra applikationsstatusdata direkt i själva applikationen. Använd sessioner i själva applikationens RAM. Använd så mycket delning mellan tredjepartstjänster som möjligt. Lita på det faktum att applikationen bara kan ha en process och inte tillåter skalning.

När det gäller sessioner, lagra data endast i en cache som kontrolleras av tredjepartstjänster (memcached, redis), så även om du har 20 applikationsprocesser igång, kommer någon av dem, efter att ha fått åtkomst till cachen, att kunna fortsätta arbeta med klienten i samma tillstånd som användaren arbetade med programmet i en annan process. Med detta tillvägagångssätt visar det sig att oavsett hur många kopior av tredjepartstjänster du använder kommer allt att fungera normalt och utan problem med tillgång till data.

7. Portbindning

Endast webbservern ska veta hur man arbetar med tredjepartstjänster. Eller ännu bättre, installera tredjepartstjänster direkt inuti webbservern. Till exempel som PHP-modul i Apache.
Alla dina tjänster måste vara tillgängliga för varandra genom åtkomst till någon adress och port (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), det vill säga från nginx kan jag komma åt både php-fpm och till postgres, och från php-fpm till postgres och nginx och faktiskt från varje tjänst kan jag komma åt en annan tjänst. På så sätt är lönsamheten för en tjänst inte bunden till lönsamheten för en annan tjänst.

8. Parallellism

Arbeta med en process, annars kommer flera processer inte att kunna komma överens med varandra!

Lämna utrymme för skalning. Docker swarm är bra för detta.
Docker Swarm är ett verktyg för att skapa och hantera kluster av containrar både mellan olika maskiner och ett gäng containrar på samma maskin.

Med hjälp av swarm kan jag bestämma hur många resurser jag kommer att allokera till varje process och hur många processer av samma tjänst jag kommer att starta, och den interna balansören, som tar emot data på en given port, kommer automatiskt att proxys av den till processerna. När jag ser att belastningen på servern har ökat kan jag lägga till fler processer och därigenom minska belastningen på vissa processer.

9. Disponibilitet

Använd inte köer för att arbeta med processer och data. Att döda en process bör påverka hela applikationen. Om en tjänst går ner, går allt ner.

Varje process och tjänst kan stängas av när som helst och detta bör inte påverka andra tjänster (det betyder givetvis inte att tjänsten kommer att vara otillgänglig för en annan tjänst, men att en annan tjänst inte kommer att stängas av efter denna). Alla processer måste avslutas på ett elegant sätt, så att när de avslutas kommer ingen data att skadas och systemet kommer att fungera korrekt nästa gång du slår på det. Det vill säga, även i händelse av en nödavslutning bör data inte skadas (transaktionsmekanismen är lämplig här, frågor i databasen fungerar bara i grupper, och om minst en fråga från gruppen misslyckas eller exekveras med en fel, då misslyckas ingen annan fråga från gruppen i slutändan).

10. Applikationsutveckling/driftsparitet

Produktion, iscensättning och lokal version av applikationen måste vara annorlunda. I produktionen använder vi Yii Lite ramverket, och lokalt Yii, så att det fungerar snabbare i produktionen!

I verkligheten bör alla distributioner och arbete med kod vara i nästan identisk miljö (vi pratar inte om fysisk hårdvara). Dessutom ska vilken utvecklingsanställd som helst kunna distribuera koden till produktion vid behov, och inte någon specialutbildad devops-avdelning, som bara tack vare speciell styrka kan lyfta applikationen i produktion.

Docker hjälper oss också med detta. Om alla föregående punkter observeras, kommer användningen av docker att leda till att processen med att distribuera miljön både i produktion och på den lokala maskinen matas in ett eller två kommandon.

11. Loggar

Vi skriver loggar till filer och databaser! Vi rensar inte filer och databaser från loggar. Låt oss bara köpa en hårddisk med 9000 Peta byte och det är bra.

Alla loggar bör betraktas som en ström av händelser. Själva applikationen ska inte vara inblandad i att bearbeta loggar. Loggar bör matas ut antingen till stdout eller skickas via ett protokoll som udp, så att arbetet med loggar inte skapar några problem för applikationen. Graylog är bra för detta. Graylog som tar emot alla loggar via udp (det här protokollet kräver inte att man väntar på ett svar om framgångsrik mottagning av paketet) stör inte applikationen på något sätt och handlar bara om strukturering och bearbetning av loggar. Applikationslogiken ändras inte för att fungera med sådana tillvägagångssätt.

12. Administrationsuppgifter

För att uppdatera data, databaser, etc., använd en separat skapad slutpunkt i API:t, exekvering av den 2 gånger i rad kommer att resultera i att allt dupliceras. Men du är inte dum, du klickar inte två gånger, och vi behöver inte migrera.

Alla administrationsuppgifter ska utföras i samma miljö som all kod, på releasenivå. Det vill säga, om vi behöver ändra strukturen på databasen, kommer vi inte att göra det manuellt genom att ändra namnen på kolumner och lägga till nya genom några visuella databashanteringsverktyg. För sådana saker skapar vi separata skript – migrering, som exekveras överallt och i alla miljöer på samma sätt med ett gemensamt och begripligt resultat. För alla andra uppgifter, som att fylla projektet med data, bör liknande metoder användas.

Exempelimplementering i PHP, Laravel, Laradock, Docker-Compose

PS Alla exempel gjordes på MacOS. De flesta av dem är också lämpliga för Linux. Windows-användare, förlåt mig, men jag har inte arbetat med Windows på länge.

Låt oss föreställa oss en situation där vi inte har någon version av PHP installerad på vår PC och ingenting alls.
Installera de senaste versionerna av docker och docker-compose. (denna finns på internet)

docker -v && 
docker-compose -v

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

1. Sätt Laradock

git clone https://github.com/Laradock/laradock.git && 
ls

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Angående Laradock så kommer jag att säga att det är en väldigt cool grej, som innehåller många containrar och hjälpsaker. Men jag skulle inte rekommendera att använda Laradock som sådan utan modifieringar i produktionen på grund av dess redundans. Det är bättre att skapa dina egna behållare baserat på exempel i Laradock, detta kommer att vara mycket mer optimerat, eftersom ingen behöver allt som finns där samtidigt.

2. Konfigurera Laradock för att köra vår applikation.

cd laradock && 
cp env-example .env

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

2.1. Öppna habr-katalogen (föräldramappen som laradock klonas till) i någon editor. (I mitt PHPStorm-fall)

I detta skede ger vi bara projektet ett namn.

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

2.2. Starta arbetsytans bild. (I ditt fall kommer bilderna att ta lite tid att bygga)
Workspace är en speciellt förberedd bild för att arbeta med ramverket på uppdrag av utvecklaren.

Vi går in i behållaren med hjälp av

docker-compose up -d workspace && 
docker-compose exec workspace bash

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

2.3. Installerar Laravel

composer create-project --prefer-dist laravel/laravel application

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

2.4. Efter installationen kontrollerar vi om katalogen med projektet har skapats och dödar compose.

ls
exit
docker-compose down

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

2.5. Låt oss gå tillbaka till PHPStorm och ställa in rätt sökväg till vår laravel-applikation i .env-filen.

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

3. Lägg till all kod i Git.

För att göra detta kommer vi att skapa ett arkiv på Github (eller någon annanstans). Låt oss gå till habr-katalogen i terminalen och köra följande kod.

echo "# habr-12factor" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin [email protected]:nzulfigarov/habr-12factor.git # здесь будет ссылка на ваш репо
git push -u origin master
git status

Låt oss kolla om allt är i sin ordning.

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

För enkelhetens skull rekommenderar jag att du använder något visuellt gränssnitt för Git, i mitt fall är det det GitKraken. (här är en referenslänk)

4. Låt oss lansera!

Innan du börjar, se till att ingenting hänger på portarna 80 och 443.

docker-compose up -d nginx php-fpm

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Därför består vårt projekt av 3 separata tjänster:

  • nginx - webbserver
  • php-fpm - php för att ta emot förfrågningar från en webbserver
  • arbetsyta - php för utvecklare

För tillfället har vi uppnått att vi har skapat en applikation som uppfyller 4 poäng av 12, nämligen:

1. Kodbas — all kod finns i ett arkiv (liten notering: det kan vara korrekt att lägga till docker i Laravel-projektet, men detta är inte viktigt).

2. Beroenden — Alla våra beroenden är uttryckligen skrivna i application/composer.json och i varje Dockerfile i varje container.

3. Uppbackningstjänster — Var och en av tjänsterna (php-fom, nignx, workspace) lever sitt eget liv och är uppkopplade utifrån och när man arbetar med en tjänst kommer den andra inte att påverkas.

4. Processerna — varje tjänst är en process. Var och en av tjänsterna upprätthåller inte internt tillstånd.

5. Portbindning

docker ps

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Som vi kan se körs varje tjänst på sin egen port och är tillgänglig för alla andra tjänster.

6. Parallellism

Docker tillåter oss att skapa flera processer av samma tjänster med automatisk lastbalansering mellan dem.

Låt oss stoppa containrarna och köra dem genom flaggan --skala

docker-compose down && 
docker-compose up -d --scale php-fpm=3 nginx php-fpm

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Som vi kan se har kopior skapats av php-fpm-behållaren. Vi behöver inte ändra något i arbetet med den här behållaren. Vi fortsätter också att komma åt den på port 9000, och Docker reglerar lasten mellan containrar åt oss.

7. Disponibilitet - Varje behållare kan dödas utan att skada den andra. Att stoppa eller starta om behållaren kommer inte att påverka applikationens funktion under efterföljande lanseringar. Varje container kan också lyftas när som helst.

8. Applikationsutveckling/driftsparitet – alla våra miljöer är likadana. Genom att köra systemet på en server i produktion behöver du inte ändra något i dina kommandon. Allt kommer att baseras på Docker på samma sätt.

9. Skogsavverkning — alla loggar i dessa behållare går till stream och är synliga i Docker-konsolen. (i det här fallet, faktiskt, med andra hemgjorda behållare, kanske det inte är fallet om du inte tar hand om det)

 docker-compose logs -f

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Men det finns en hake i att standardvärdena i PHP och Nginx också skriver loggar till en fil. För att möta de 12 faktorerna är det nödvändigt stänga skriva loggar till en fil i konfigurationerna för varje behållare separat.

Docker ger också möjligheten att skicka loggar inte bara till stdout, utan också till sådant som graylog, som jag nämnde ovan. Och inne i graylog kan vi hantera loggarna som vi vill och vår applikation kommer inte att märka detta på något sätt.

10. Administrationsuppgifter — alla administrationsuppgifter löses av laravel tack vare hantverksverktyget precis som skaparna av 12-faktorsapplikationen skulle önska.

Som ett exempel kommer jag att visa hur vissa kommandon exekveras.
Vi går in i containern.

 
docker-compose exec workspace bash
php artisan list

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

Nu kan vi använda vilket kommando som helst. (Observera att vi inte konfigurerade databasen och cachen, så hälften av kommandona kommer inte att köras korrekt, eftersom de är designade för att fungera med cachen och databasen).

Applikationsutveckling och Blue-Green-distribution, baserad på The Twelve-Factor App-metodik med exempel i php och docker

11. konfigurationer och 12. Bygg, släpp, spring

Jag ville ägna den här delen till Blue-Green Deployment, men den visade sig vara för omfattande för den här artikeln. Jag kommer att skriva en separat artikel om detta.

I ett nötskal är konceptet baserat på CI/CD-system som Jenkins и Gitlab CI. I båda kan du ställa in miljövariabler associerade med en specifik miljö. Följaktligen kommer punkt c i denna situation att uppfyllas Konfigurationer.

Och poängen om Bygg, släpp, spring löses av inbyggda funktioner med namnet Pipeline.

Pipeline låter dig dela upp driftsättningsprocessen i många steg, och belyser stadierna av montering, release och utförande. Även i Pipeline kan du skapa säkerhetskopior, och faktiskt vad som helst. Detta är ett verktyg med obegränsad potential.

Ansökningskoden finns på Github.
Glöm inte att initiera undermodulen när du klonar detta förråd.

PS: Alla dessa metoder kan användas med alla andra verktyg och programmeringsspråk. Huvudsaken är att essensen inte skiljer sig åt.

Källa: will.com

Lägg en kommentar