Hogyan telepíti a Dark a kódot 50 ms alatt

Hogyan telepíti a Dark a kódot 50 ms alatt

Minél gyorsabb a fejlesztési folyamat, annál gyorsabban növekszik a technológiai vállalat.

Sajnos a modern alkalmazások ellenünk dolgoznak - rendszereinket valós időben kell frissíteni anélkül, hogy bárkit is zavarnának, leállást vagy fennakadást okoznának. Az ilyen rendszerekre való telepítés kihívást jelent, és még kis csapatok számára is bonyolult, folyamatos szállítási folyamatokat igényel.

Ezek a csővezetékek jellemzően szűk hatókörűek, lassúak és megbízhatatlanok. A fejlesztőknek először manuálisan kell elkészíteniük, majd kezelniük kell őket, a vállalatok pedig gyakran egész DevOps-csapatokat bérelnek fel erre.

A fejlesztés sebessége ezen csővezetékek sebességétől függ. A legjobb csapatok 5-10 perc alatt bevetnek, de általában a dolgok sokkal tovább tartanak, és telepítésenként több órát is igénybe vesznek.

Sötétben ez 50 ms-t vesz igénybe. Ötven. Ezredmásodperc. Sötét – ez egy komplett megoldás programozási nyelvvel, szerkesztővel és infrastruktúrával, amely kifejezetten a folyamatos kézbesítéshez készült, és a Dark minden aspektusa, beleértve magát a nyelvet is, a biztonságos, azonnali telepítést szem előtt tartva készült.

Miért olyan lassúak a folyamatos szállítási csővezetékek?

Tegyük fel, hogy van egy Python webes alkalmazásunk, és máris létrehoztunk egy csodálatos és modern folyamatos kézbesítési folyamatot. Egy fejlesztő számára, aki minden nap ezzel a projekttel van elfoglalva, egy kisebb változtatás bevezetése a következőképpen nézne ki:

Módosítás

  • Új ág létrehozása a gitben
  • Változások végrehajtása a funkciókapcsoló mögött
  • Egységteszt a változások tesztelésére funkciókapcsolóval és anélkül

Lehúzási kérés

  • Végezze el a változtatásokat
  • Változások elküldése egy távoli github-tárolóba
  • Lehúzási kérés
  • A CI automatikusan épül a háttérben
  • Kód felülvizsgálata
  • Szükség esetén még néhány vélemény
  • Változások egyesítése git mesterbe.

A CI masteren fut

  • Frontend függőségek telepítése npm-en keresztül
  • HTML+CSS+JS erőforrások összeállítása és optimalizálása
  • Futó egység és funkcionális tesztek a frontendben
  • Python-függőségek telepítése PyPI-ből
  • Futó egység és funkcionális tesztek a háttérben
  • Az integráció tesztelése mindkét oldalon
  • Frontend erőforrások küldése a CDN-nek
  • Konténer készítése Python programhoz
  • Tároló beküldése a rendszerleíró adatbázisba
  • Frissítse a Kubernetes jegyzéket

A régi kód cseréje újjal

  • A Kubernetes egy új tároló több példányát is felpörgeti
  • A Kubernetes arra vár, hogy az esetek egészségesek legyenek
  • A Kubernetes példányokat ad hozzá a HTTP terheléselosztóhoz
  • A Kubernetes megvárja, amíg a régebbi példányok már nincsenek használatban
  • A Kubernetes leállítja a régi példányokat
  • A Kubernetes addig ismétli ezeket a műveleteket, amíg új példányok nem váltják fel az összes régi példányt

Új funkciókapcsoló engedélyezése

  • Az új kódot csak az Ön számára tartalmazza, hogy megbizonyosodjon arról, hogy minden rendben van
  • Az új kód a felhasználók 10%-a számára engedélyezve van, a működési és üzleti mutatókat nyomon követik
  • Az új kód a felhasználók 50%-a számára engedélyezve van, a működési és üzleti mutatókat nyomon követik
  • Az új kód a felhasználók 100%-a számára engedélyezve van, a működési és üzleti mutatókat nyomon követik
  • Végül ismételje meg az egész eljárást a régi kód eltávolításához és a váltáshoz

A folyamat az eszközöktől, a nyelvtől és a szolgáltatás-orientált architektúrák használatától függ, de általánosságban így néz ki. Nem említettem az adatbázis-áttelepítési telepítéseket, mert sok tervezést igényelnek, de az alábbiakban megmutatom, hogyan kezeli ezt a Dark.

Számos összetevő található itt, és sok közülük könnyen lelassulhat, összeomolhat, átmeneti vitát okozhat, vagy összeomolhatja a működő rendszert.

És mivel ezeket a csővezetékeket szinte mindig speciális esetekre hozták létre, nehéz rájuk hagyatkozni. Sokan vannak olyan napok, amikor a kód nem telepíthető, mert problémák vannak a Dockerfile-ban, a több tucat szolgáltatás egyike lefagy, vagy a szükséges szakember szabadságon van.

Még ennél is rosszabb, hogy ezeknek a lépéseknek a többsége egyáltalán nem tesz semmi hasznosat. Ezekre korábban is szükség volt, amikor a kódot közvetlenül a felhasználókhoz telepítettük, de most már van kapcsolóink ​​az új kódhoz, és ezeket a folyamatokat szétválasztottuk. Ennek eredményeként az a lépés, ahol a kódot telepítik (a régit lecserélik az újra), mára egyszerűen szükségtelen kockázattá vált.

Természetesen ez egy nagyon átgondolt csővezeték. A csapat, aki létrehozta, időt és pénzt nem kímélt a gyors üzembe helyezésére. A telepítési folyamatok jellemzően sokkal lassabbak és megbízhatatlanabbak.

Folyamatos szállítás megvalósítása sötétben

A folyamatos kézbesítés annyira fontos a Dark számára, hogy a kezdetektől a másodperc alatti időkre törekedtünk. Végigmentünk a csővezeték minden lépésén, hogy eltávolítsunk minden feleslegeset, a többit pedig kifényesítettük. Így távolítottuk el a lépéseket.

Jesse Frazel (Jessie Frazelle) megalkotta a deployless szót (nem igényel telepítést) a Future of Software Development konferencián Reykjavikban.

Azonnal úgy döntöttünk, hogy a Dark a „bevetés nélküli” koncepción fog alapulni (köszönjük Jesse Frazel neologizmushoz). A deployless azt jelenti, hogy bármely kód azonnal üzembe helyezésre kerül, és készen áll az éles használatra. Természetesen nem engedjük át a törött vagy hiányos kódot (a biztonsági elveket alább ismertetem).

A Dark demónál gyakran kérdezték tőlünk, hogyan tudtuk ilyen gyorsan telepíteni. Furcsa kérdés. Valószínűleg az emberek azt hiszik, hogy kitaláltunk valami szuper technológiát, amely összehasonlítja a kódot, lefordítja, konténerbe csomagolja, elindít egy virtuális gépet, hidegen indít egy konténert, és minden hasonlót - mindezt 50 ms alatt. Aligha lehetséges. De létrehoztunk egy speciális telepítési motort, amelynek nincs szüksége mindezekre.

Sötét fut tolmácsok a felhőben. Tegyük fel, hogy egy függvény- vagy HTTP- vagy eseménykezelőben ír kódot. Elküldjük az absztrakt szintaxisfához (a szerkesztőnk és a szervereink által belsőleg használt kódmegvalósítás) a különbséget a szervereinkhez, majd lefuttatjuk ezt a kódot, amikor beérkeznek a kérések. Tehát az üzembe helyezés csak egy szerény belépésnek tűnik az adatbázisba - azonnali és elemi. A telepítés azért olyan gyors, mert magában foglalja a minimumot.

A jövőben azt tervezzük, hogy a Darkot olyan infrastruktúra-fordítóvá tesszük, amely ideális infrastruktúrát hoz létre és futtat az alkalmazások nagy teljesítményéhez és megbízhatóságához. Az azonnali telepítés természetesen itt marad.

Biztonságos telepítés

Strukturált szerkesztő

A Sötétben kódot a Dark szerkesztőben írjuk. A strukturált szerkesztő nem engedélyezi a szintaktikai hibákat. Valójában a Darknak nincs is elemzője. Gépelés közben közvetlenül az Abstract Syntax Tree (AST) segítségével dolgozunk, mint pl Paredit, Sketch-n-Sketch, Tofu, Aszalt szilva и MPS.

A Dark minden befejezetlen kódjának érvényes végrehajtási szemantikája van, valami ilyesmi lyukakat gépelt Hazelbe. Például, ha módosít egy függvényhívást, addig tároljuk a régi függvényt, amíg az új használhatóvá nem válik.

A Dark minden programjának megvan a maga jelentése, így a befejezetlen kód nem akadályozza meg a kész kód működését.

Szerkesztési módok

Két helyzetben írsz kódot sötétben. Először is: új kódot írsz, és te vagy az egyetlen felhasználó. Például egy REPL-ben van, és más felhasználók soha nem fogják elérni, vagy ez egy új HTTP-útvonal, amelyre nem hivatkozik sehol. Itt minden óvintézkedés nélkül dolgozhat, és most nagyjából így működik a fejlesztői környezetben.

Második helyzet: a kód már használatban van. Ha forgalom halad át a kódon (függvények, eseménykezelők, adatbázisok, típusok), akkor óvatosnak kell lennie. Ehhez letiltjuk az összes használt kódot, és strukturáltabb eszközök használatát követeljük meg annak szerkesztéséhez. Az alábbiakban ismertetem a szerkezeti eszközöket: funkciókapcsolók HTTP- és eseménykezelőkhöz, hatékony migrációs platform adatbázisokhoz, valamint új verziószámítási módszer a függvényekhez és típusokhoz.

Funkciókapcsolók

Az egyik módszer távolítsa el a szükségtelen bonyolultságot sötétben – több probléma megoldása egyetlen megoldással. A szolgáltatáskapcsolók sokféle feladatot látnak el: a helyi fejlesztői környezet cseréjét, a git-elágazásokat, a kód telepítését, és természetesen az új kódok hagyományos lassú és ellenőrzött kiadását.

A szolgáltatáskapcsoló létrehozása és üzembe helyezése egyetlen műveletben történik szerkesztőnkkel. Helyet hoz létre az új kód számára, és hozzáférés-vezérlést biztosít a régi és az új kódhoz, valamint gombokat és parancsokat biztosít az új kód fokozatos bevezetéséhez vagy eltávolításához.

A funkciókapcsolók be vannak építve a Dark nyelvbe, és még a hiányos kapcsolók is megfelelnek a céljuknak - ha a kapcsolóban lévő feltétel nem teljesül, akkor a régi blokkolt kód kerül végrehajtásra.

Fejlesztőkörnyezet

A funkciókapcsolók helyettesítik a helyi fejlesztési környezetet. Manapság a csapatok nehezen tudják biztosítani, hogy mindenki ugyanazt az eszköz- és könyvtárverziót használja (kódformázók, linterek, csomagkezelők, fordítók, előfeldolgozók, tesztelőeszközök stb.). A Dark segítségével nincs szükség a függőségek helyi telepítésére, kezelni egy helyi Docker-telepítést, vagy más intézkedéseket tenni a fejlesztési és a termelési környezet legalább látszólagos egyenlőségének biztosítására. Figyelembe véve, hogy ez az egyenlőség még mindig lehetetlen, még csak nem is teszünk úgy, mintha arra törekszünk.

Ahelyett, hogy klónozott helyi környezetet hoznának létre, a Dark kapcsolói egy új homokozót hoznak létre az éles környezetben, amely felváltja a fejlesztői környezetet. A jövőben az alkalmazás más részeit (pl. azonnali adatbázis-klónok) is sandboxba helyezzük, bár ez most nem tűnik olyan fontosnak.

Elágazások és telepítések

Mostantól többféle módon is bevezethető az új kód a rendszerekbe: git-ágak, üzembe helyezési fázis és funkciókapcsolók. Ugyanazt a problémát oldják meg a munkafolyamat különböző részein: a git a telepítés előtti szakaszokban, a telepítés a régi kódról az újra való áttéréskor, és funkciókapcsolók az új kód szabályozott kiadásához.

A leghatékonyabb módja a funkciókapcsolók (egyben a legkönnyebben érthető és használható). Velük teljesen elhagyhatja a másik két módszert. Különösen hasznos a telepítés eltávolítása – ha egyébként is funkciókapcsolókkal engedélyezzük a kódot, akkor a szerverek új kódra való áttelepítése csak felesleges kockázatokat jelent.

A Git használata nehéz, különösen a kezdők számára, és nagyon korlátozó, de vannak kényelmes ágai. Kisimítottuk a git számos hiányosságát. A Dark valós időben szerkeszthető, és lehetővé teszi a Google Dokumentumok-stílusú együttműködést, így nem kell kódot beküldenie, és ritkábban lehet újrabázisolni és egyesíteni.

A funkciókapcsolók a biztonságos telepítés középpontjában állnak. Az azonnali üzembe helyezésekkel együtt lehetővé teszik a koncepciók gyors tesztelését kis, alacsony kockázatú darabokban, ahelyett, hogy elkötelezné magát egy nagy változtatás mellett, amely lerombolhatja a rendszert.

Verziószámítás

Verziószámítást használunk a funkciók és típusok megváltoztatására. Ha módosítani szeretne egy függvényt, a Dark létrehozza a függvény új verzióját. Ezt a verziót ezután a HTTP vagy az eseménykezelő kapcsolójával hívhatja meg. (Ha ez egy függvény a hívási grafikon mélyén van, akkor minden függvényből új verzió jön létre. Ez túlzásnak tűnhet, de a függvények nem akadályozzák, hacsak nem használja őket, így nem is fog értesítés.)

Ugyanezen okokból mi is verziótípusokat készítünk. Típusrendszerünkről részletesen beszéltünk az előző bejegyzésben.

A funkciók és típusok verziózásával fokozatosan módosíthatja az alkalmazást. Ellenőrizheti, hogy minden egyes kezelő működik-e az új verzióval, anélkül, hogy egyszerre kellene végrehajtania az összes módosítást az alkalmazásokon (de van eszközünk, amellyel ezt gyorsan megteheti, ha akarja).

Ez sokkal biztonságosabb, mint mindent egyszerre teljesen üzembe helyezni, ahogy ez most történik.

Új csomagverziók és szabványos könyvtár

Amikor Sötétben frissít egy csomagot, nem cseréljük le azonnal a teljes kódbázis minden függvényének vagy típusának használatát. Nem biztonságos. A kód továbbra is ugyanazt a verziót használja, mint korábban, és Ön eseti alapon kapcsolók segítségével frissíti a funkciók és típusok használatát az új verzióra.

Hogyan telepíti a Dark a kódot 50 ms alatt
Képernyőkép az automatikus folyamat egy részéről sötétben, amely a Dict::get függvény két verzióját mutatja. A Dict::get_v0 bármilyen típusút adott vissza (amelyet elvetünk), a Dict::get_v1 pedig egy Option típust adott vissza.

Gyakran biztosítjuk a szabványos könyvtár új funkcióját, és kizárjuk a régebbi verziókat. A régebbi kóddal rendelkező felhasználók továbbra is hozzáférhetnek hozzájuk, de az új felhasználók nem férhetnek hozzá. Eszközöket fogunk biztosítani a felhasználóknak a régi verziókról az újakra 1 lépésben történő migrálásához, ismét funkciókapcsolókkal.

A Dark egy egyedülálló funkciót is biztosít: mivel mi futtatjuk az éles kódot, magunk is tesztelhetjük az új verziókat, összehasonlítva az új és a régi lekérdezések kimenetét, hogy tájékoztassuk a változásokról. Ennek eredményeként a gyakran vakon (vagy kiterjedt biztonsági tesztelést igénylő) csomagfrissítések sokkal kisebb kockázatot jelentenek, és automatikusan megtörténhetnek.

A Dark új verziói

A Python 2-ről a Python 3-ra való átállás egy évtizedet ölelt fel, és még mindig kihívást jelent. Mivel a Darkot a folyamatos kézbesítéshez hozzuk létre, figyelembe kell vennünk ezeket a nyelvi változásokat.

Amikor apró változtatásokat hajtunk végre a nyelven, létrehozzuk a Dark új verzióját. A régi kód a Dark régi verziójában marad, az új kód pedig az új verzióban kerül felhasználásra. A Dark új verziójára való frissítéshez kapcsolókat vagy funkcióverziókat használhat.

Ez különösen hasznos, ha figyelembe vesszük, hogy a Dark csak nemrégiben jelent meg. Előfordulhat, hogy a nyelven vagy a könyvtáron végrehajtott számos módosítás sikertelen lesz. A növekményes nyelvi verziók lehetővé teszik számunkra, hogy kisebb frissítéseket hajtsunk végre, ami azt jelenti, hogy időt szakíthatunk, és sok döntést elhalaszthatunk a nyelvvel kapcsolatban, amíg több felhasználónk lesz, és így több információnk lesz.

Adatbázis migráció

A biztonságos adatbázis-migrációhoz van szabványos képlet:

  • Írja át a kódot az új és a régi formátumok támogatásához
  • Konvertálja az összes adatot új formátumba
  • Távolítsa el a régi adathozzáférést

Ennek eredményeként az adatbázis-áttelepítés hosszú időt vesz igénybe, és sok erőforrást igényel. És végül felhalmozódnak az elavult sémák, mert még az olyan egyszerű feladatok sem érik meg a fáradságot, mint a tábla vagy oszlop nevének javítása.

A Dark hatékony adatbázis-migrációs platformmal rendelkezik, amely (reméljük) olyan egyszerűvé teszi a folyamatot, hogy nem kell félnie tőle. A Dark összes adattárának (kulcsérték-tárolóknak vagy állandó hash-tábláknak) van típusa. Egy adattár áttelepítéséhez egyszerűen hozzá kell rendelni egy új típust, valamint egy visszagörgetési és előregörgetési funkciót a két típus közötti értékek konvertálásához.

A Dark adattáraihoz verziószámú változóneveken keresztül lehet hozzáférni. Például a Felhasználók adattárának neve kezdetben Users-v0. Amikor egy új verziót hoz létre más típussal, a név Users-v1-re változik. Ha az adatokat a Users-v0-n keresztül menti, és a Users-v1-en keresztül éri el, akkor a görgetés előre funkció kerül alkalmazásra. Ha az adatokat a Users-v1-en keresztül menti, és a Users-v0-n keresztül éri el, akkor a visszaállítási funkció kerül alkalmazásra.

Hogyan telepíti a Dark a kódot 50 ms alatt
Adatbázis-áttelepítési képernyő, amelyen a régi adatbázismezők nevei, az átállítási és visszagörgetési kifejezések, valamint az áttelepítés engedélyezésére vonatkozó utasítások láthatók.

Használja a funkciókapcsolókat, hogy a Users-v0-ból a Users-v1-be irányítsa a hívásokat. Ezt megteheti egyenként egy HTTP-kezelővel a kockázat csökkentése érdekében, és a kapcsolók felhasználónként működnek, így ellenőrizheti, hogy minden a várt módon működik-e. Ha már nem maradt Users-v0, a Dark a háttérben maradt összes adatot a régi formátumról az újra konvertálja. Észre sem fogod venni.

tesztelés

Sötét van funkcionális programozási nyelv statikus gépeléssel és változtathatatlan értékeket, így a tesztelési felülete lényegesen kisebb a dinamikusan tipizált objektumorientált nyelvekhez képest. De még tesztelned kell.
Sötétben a szerkesztő automatikusan egységteszteket futtat a háttérben a szerkesztett kódhoz, és alapértelmezés szerint minden funkciókapcsolónál lefutja ezeket a teszteket. A jövőben statikus típusokat szeretnénk használni a kód automatikus összemosására a hibák megtalálásához.

Ezenkívül a Dark éles üzemben működteti az infrastruktúrát, ami új lehetőségeket nyit meg. A HTTP kéréseket automatikusan mentjük a Sötét keretrendszerben (egyelőre minden kérést mentünk, de ezután át akarunk váltani a lekérésre). Új kódot tesztelünk ellenük, és egységteszteket futtatunk, és ha akarod, könnyedén konvertálhatod az érdekes lekérdezéseket egységtesztekké.

Mitől szabadultunk meg?

Mivel nincs telepítésünk, de vannak funkciókapcsolóink, a telepítési folyamat körülbelül 60%-a elmarad. Nincs szükségünk git-elágazásokra vagy lekérési kérésekre, háttér-erőforrások és tárolók létrehozására, erőforrások és tárolók rendszerleíró adatbázisokba tolására, illetve Kubernetes telepítési lépésekre.

Hogyan telepíti a Dark a kódot 50 ms alatt
A szabványos folyamatos szállítási csővezeték (balra) és a sötét folyamatos szállítás (jobbra) összehasonlítása. A Dark szállítás 6 lépésből és egy ciklusból áll, míg a hagyományos változat 35 lépésből és 3 ciklusból áll.

Sötétben a telepítés csak 6 lépésből és 1 ciklusból áll (többször ismétlődő lépések), míg a modern folyamatos szállítási folyamat 35 lépésből és 3 ciklusból áll. Sötétben a tesztek automatikusan lefutnak anélkül, hogy látnád; a függőségek automatikusan telepítésre kerülnek; már nincs szükség mindenre, ami a gittel vagy a Githubbal kapcsolatos; Nincs szükség Docker konténerek építésére, tesztelésére és szállítására; a Kubernetes-be való telepítés már nem szükséges.

Még a sötétben hátralévő lépések is könnyebbek lettek. Mivel a funkcióváltások egyetlen művelettel vezérelhetők, nem kell másodszor is végigmenni a teljes telepítési folyamaton a régi kód eltávolításához.

A lehető legjobban leegyszerűsítettük a kódküldést, csökkentve ezzel a folyamatos kézbesítés idejét és kockázatait. Sokkal egyszerűbbé tettük a csomagok frissítését, az adatbázis-áttelepítést, a tesztelést, a verziókezelést, a függőségi telepítést, a fejlesztői és éles környezetek egyenlőségét, valamint a gyors és biztonságos nyelvi verziófrissítést.

Az ezzel kapcsolatos kérdésekre itt válaszolok HackerNews.

Ha többet szeretne megtudni a Dark eszközről, olvassa el a következőt: cikk a Darkról, Kövess minket a Twitteren (vagy at nekem), vagy iratkozzon fel a bétára, és kap értesítést a közelgő bejegyzésekről. Ha szeptemberben a StrangeLoop-ra megy, gyere el a startunkra.

Forrás: will.com

Hozzászólás