
Čím rychleji probíhá vývoj, tím rychleji se technologická společnost rozvíjí.
Bohužel moderní aplikace pracují proti nám — naše systémy se musí aktualizovat v reálném čase a zároveň nesmí nikomu překážet ani způsobovat výpadky. Nasazení v takových systémech se stává složitým úkolem a vyžaduje komplikované pipeline kontinuální dodávky, i v malých týmech.
Tyto pipeline obvykle mají omezené využití, pracují pomalu a nevyznačují se spolehlivostí. Vývojáři je musí nejprve vytvořit ručně a poté je spravovat, a společnosti často najímají celé týmy DevOps pro tuto činnost.
Rychlost těchto pipeline ovlivňuje rychlost vývoje. U nejlepších týmů trvá nasazení 5–10 minut, ale obvykle to trvá mnohem déle, a pro jedno nasazení jsou potřeba i několik hodin.
V Dark to trvá 50 ms. Padesát. Milisekund.. Dark — , vytvořené speciálně pro kontinuální dodávku, a všechny aspekty Dark, včetně samotného jazyka, jsou navrženy tak, aby umožnily bezpečné momentální nasazení.
Proč jsou pipeline kontinuální dodávky tak pomalé?
Předpokládejme, že máme webovou aplikaci v Pythonu a již jsme vytvořili skvělou a moderní pipeline kontinuální dodávky. Pro vývojáře, který se tímto projektem zabývá každý den, bude nasazení jediné drobné změny vypadat přibližně takto:
Provedení změn
- Vytvoření nové větve v git
- Provedení změn za přepínačem funkce
- Modulární testování za účelem ověření změn s přepínačem funkce a bez něj
Pull request
- Commit změn
- Odeslání změn do vzdáleného repozitáře na github
- Pull request
- Automatická CI sestava se provádí na pozadí
- Kontrola kódu
- Další několik recenzí, pokud je to nutné
- Slučování změn s masterem git.
CI běží na masteru
- Instalace frontendových závislostí pomocí npm
- Sestavení a optimalizace prostředků HTML+CSS+JS
- Běh modulárních a funkčních testů na frontendu
- Instalace Python závislostí z PyPI
- Běh modulárních a funkčních testů na backendu
- Testování integrace na obou koncích
- Odeslání frontendových prostředků do CDN
- Sestavení kontejneru pro program Python
- Odesílání kontejneru do registru
- Aktualizace manifestu Kubernetes
Nahrazení starého kódu novým
- Kubernetes spouští několik instancí nového kontejneru
- Kubernetes čeká, až se instance stanou funkčními
- Kubernetes přidává instance do HTTP vyvažovače zatížení
- Kubernetes čeká, až se staré instance přestanou používat
- Kubernetes zastavuje staré instance
- Kubernetes opakuje tyto operace, dokud nové instance nenahradí všechny staré
Aktivace nového přepínače funkcí
- Nový kód se aktivuje pouze pro sebe, aby se ujistil, že vše funguje správně
- Nový kód se aktivuje pro 10 % uživatelů, sledují se operační a obchodní metriky
- Nový kód se aktivuje pro 50 % uživatelů, sledují se operační a obchodní metriky
- Nový kód se aktivuje pro 100 % uživatelů, sledují se operační a obchodní metriky
- Nakonec opakujete celý proces, abyste odstranili starý kód a přepínač
Proces závisí na nástrojích, jazyce a využívání architektur zaměřených na služby, ale obecně vypadá takto. Nezmiňoval jsem nasazení s migrací databází, protože to vyžaduje pečlivé plánování, ale níže vysvětlím, jak se s tím vypořádává Dark.
Existuje zde mnoho komponentů a mnohé z nich mohou snadno způsobit zpomalení, selhání, dočasnou konkurenci nebo zhroucení pracovního systému.
A protože jsou tyto pipeline téměř vždy vytvořeny na míru, nelze na ně spolehnout. Mnozí mají dny, kdy není možné nasadit kód, protože Dockerfile má problémy, jeden z desítek služeb selhal nebo potřebný specialista je na dovolené.
Co je horší, mnoho z těchto kroků ve skutečnosti nedělá nic užitečného. Byly potřeba dříve, když jsme nasazovali kód okamžitě pro uživatele, ale nyní máme přepínače pro nový kód a tyto procesy se rozdělily. Výsledkem je, že krok, na kterém se kód nasazuje (starý je nahrazen novým), se nyní stal pouhým zbytečným rizikem.
Samozřejmě, že je to velmi promyšlená pipeline. Tým, který ji vytvořil, nešetřil časem a penězi na rychlé nasazení. Obvykle jsou nasazovací pipeline mnohem pomalejší a méně spolehlivé.
Implementace kontinuální dodávky v Dark
Nepřetržité dodávání je pro Dark tolik důležité, že jsme se od začátku zaměřili na čas méně než sekundu. Prošli jsme všechny kroky v pipeline, abychom odstranili veškeré nadbytečné úkony, a zbývající krok jsme vyladili. Takto jsme odstraňovali kroky.
Jesse Frazelle () vymyslela nové slovo 'deployless' na konferenci Future of Software Development v Reykjavíku.
Hned jsme se rozhodli, že Dark bude založen na konceptu 'deployless' (děkujeme za neologismus). Deployless znamená, že jakýkoli kód se okamžitě nasazuje a je připraven k použití v produkci. Samozřejmě nezapomínáme na chybný nebo neúplný kód (principy bezpečnosti popíšu níže).
Na prezentaci Dark se nás často ptali, jak jsme dokázali tak urychlit nasazení. Podivná otázka. Lidé si asi myslí, že jsme vymysleli nějakou supertechnologii, která porovnává kód, kompiluje ho, balí do kontejneru, spouští virtuální stroj, spouští kontejner na studeno a to všechno za 50 ms. To asi není možné. Ale vytvořili jsme speciální nasazovací engine, kterému to všechno ani není potřeba.
Dark spouští interpretry v cloudu. Představte si, že píšete kód ve funkci nebo HTTP či události. Odesíláme diff do abstraktního syntaktického stromu (implementace kódu, kterou interně používá náš editor a servery) na naše servery a poté spouštíme tento kód, když přicházejí požadavky. Takže nasazení vypadá jako skromný záznam v databázi — okamžité a elementární. Nasazení probíhá tak rychle, protože zahrnuje to nejnutnější.
V budoucnu plánujeme učinit z Dark kompilátor infrastruktury, který vytvoří a spustí dokonalou infrastrukturu pro vysoký výkon a spolehlivost aplikací. Okamžité nasazení samozřejmě nikam nezmizí.
Bezpečné nasazení
Strukturovaný editor
Kód v Dark se píše ve editoru Dark. Strukturovaný editor neumožňuje syntaktické chyby. V podstatě, v Dark vlastně ani nemáme analyzátor. Dokud zadáváte text, přímo pracujeme s abstraktním syntaktickým stromem (AST), jako , , , a .
Jakýkoli nedokončený kód v Dark má platnou semantiku provádění, přibližně jako . Například, pokud měníte volání funkce, uchováváme starou funkci, dokud nová nebude připravena.
Každý program v Dark má svůj význam, takže nedokončený kód nebrání dokončenému v jeho fungování.
Režimy úprav
Kód v Dark píšete ve dvou případech. První: píšete nový kód a jste jediný uživatel. Například, je to v REPL, a ostatní uživatelé k němu nikdy nemají přístup, nebo je to nový HTTP route, na který nikde neodkazujete. Zde můžete pracovat bez jakýchkoli bezpečnostních opatření, a přesně tak nyní pracujete v prostředí vývoje.
Druhá situace: kód je již používán. Pokud kódem prochází provoz (funkce, obslužné rutiny událostí, databáze apod.), je třeba být opatrný. K tomu blokujeme veškerý používaný kód a vyžadujeme použití strukturovanějších nástrojů pro jeho úpravu. O strukturovaných nástrojích se zmíním níže: přepínače funkcí pro HTTP obslužné rutiny a události, výkonná migrační platforma pro databáze a nový způsob správy verzí pro funkce a typy.
Přepínače funkcí
Jedním ze způsobů v Dark je odstranit několik problémů jedním řešením. Přepínače funkcí vykonávají různé úkoly: nahrazují místní vývojové prostředí, větve gitu, nasazení kódu a samozřejmě tradičně pomalé a kontrolované uvolňování nového kódu.
Vytvoření a nasazení přepínače funkce se provádí v našem editoru v jedné operaci. Vytváří prázdný prostor pro nový kód a poskytuje ovládací prvky pro přístup ke starému a novému kódu, stejně jako tlačítka a příkazy pro postupný přechod na nový kód nebo jeho vyloučení.
Přepínače funkcí jsou zabudovány do jazyka Dark, a dokonce i nedokončené přepínače plní svou funkci — pokud není podmínka v přepínači splněna, bude vykonáván starý zablokovaný kód.
Vývojové prostředí
Přepínače funkcí nahrazují místní vývojové prostředí. Dnes je pro týmy těžké zajistit, aby všichni používali stejné verze nástrojů a knihoven (nástroje pro formátování kódu, lintry, správce balíčků, kompilátory, preprocesory, testovací nástroje atd.). S Dark není třeba instalovat závislosti lokálně, spravovat místní instalaci Dockeru nebo přijímat další opatření, aby se zajistila alespoň nějaká rovnost mezi vývojovým a produkčním prostředím. , ani se nebudeme tvářit, že se o ni snažíme.
Místo vytváření klonovaného místního prostředí přepínače v Dark vytvářejí nový píseček v produkci, který nahrazuje vývojové prostředí. V budoucnu plánujeme také vytvářet píseček pro další části aplikace (například okamžité klony databáze), i když to zatím nevypadá jako příliš důležité.
Větve a nasazení
V současnosti existuje několik způsobů, jak zavést nový kód do systémů: větve git, fáze nasazení a přepínače funkcí. Tyto metody řeší stejný problém v různých částech pracovního procesu: git – v etapách před nasazením, nasazení – při přechodu ze starého kódu na nový, a přepínače funkcí – pro kontrolované vydání nového kódu.
Nejefektivnější metodou jsou přepínače funkcí (zároveň nejjednodušší na pochopení a použití). S nimi lze plně upustit od ostatních dvou metod. Zvláště užitečné je odstranit nasazení – pokud přece jen používáme přepínače funkcí k aktivaci kódu, pak krok přechodu serverů na nový kód vytváří pouze zbytečná rizika.
Git je obtížné používat, zejména pro nováčky, což ho značně omezuje, ale má pohodlné větve. Mnoho nedostatků gitu jsme ulehčili. Dark se editoval v reálném čase a umožňuje spolupráci ve stylu Google Dokumentů, takže není třeba posílat kód a mohou se provádět merge a rebasy méně často.
Přepínače funkcí jsou základem bezpečného nasazení. Spolu s okamžitými nasazeními umožňují rychle testovat koncepty v malých fragmentech s nízkým rizikem, místo aby se aplikovala jedna velká změna, která by mohla systém zhroutit.
Verzování
Pro změnu funkcí a typů používáme verzování. Pokud chcete změnit funkci, Dark vytvoří novou verzi této funkce. Poté můžete tuto verzi zavolat pomocí přepínače ve zpracovateli HTTP nebo událostí. (Pokud je to funkce hluboko ve stromě volání, během toho se vytváří nová verze každé funkce. Může se to zdát nadměrné, ale funkce se neskládají, pokud je nepoužíváte, takže si toho ani nevšimnete.)
Z těchto stejných důvodů verzujeme i typy. Naši systém typů jsme podrobně popsali. .
Díky verzování funkcí a typů můžete provádět změny v aplikaci postupně. Můžete zkontrolovat, zda každý jednotlivý zpracovatel funguje s novou verzí, aniž byste museli provádět všechny změny v aplikacích najednou (ale máme nástroje pro rychlé provedení, pokud budete chtít).
Je to mnohem bezpečnější než okamžité nasazení všeho najednou, jak to funguje nyní.
Nové verze balíčků a standardní knihovna
Když aktualizujete balíček v Dark, okamžitě nenahrazujeme použití každé funkce nebo typu v celém kódu. To není bezpečné. Kód nadále používá stejnou verzi, kterou používal, a vy aktualizujete použití funkcí a typů na novou verzi pro každý jednotlivý případ pomocí přepínačů.
Screenshot části automatizovaného procesu v Dark, který ukazuje dvě verze funkce Dict::get. Dict::get_v0 vracel typ Any (od kterého se vzdáváme), zatímco Dict::get_v1 vrací typ Option.
Často poskytujeme nové funkce standardní knihovny a vyřazujeme staré verze. Uživatelé se starými verzemi v kódu si je zachovají, ale noví uživatelé je nebudou moci získat. Chystáme se poskytnout nástroje, jak přenést uživatele ze starých verzí na nové v jednom kroku, opět s pomocí přepínačů funkcí.
Dark také poskytuje jedinečnou příležitost: jelikož vykonáváme váš pracovní kód, můžeme sami testovat nové verze a porovnávat výstupy pro nové a staré dotazy, abychom vás informovali o změnách. Výsledkem je, že aktualizace balíčků, která se často provádí naslepo (nebo vyžaduje pečlivé testování kvůli bezpečnosti), představuje mnohem menší rizika a může probíhat automaticky.
Nové verze Dark
Přechod z Pythonu 2 na Python 3 trval celou dekádu a stále je to problém. Jelikož vytváříme Dark pro kontinuální dodávku, musíme brát v úvahu tyto změny jazyka.
Když provedeme malé změny v jazyce, vytváříme novou verzi Dark. Starý kód zůstává ve staré verzi Dark, zatímco nový kód se používá v nové verzi. Pro přechod na novou verzi Dark lze použít přepínače nebo verze funkcí.
To je obzvlášť užitečné, vzhledem k tomu, že Dark byl vytvořen teprve nedávno. Mnohé změny v jazyce nebo knihovně se mohou ukázat jako neúspěšné. Postupné verzování jazyka nám umožňuje provádět drobné aktualizace, což znamená, že si můžeme dát na čas a odložit mnohá rozhodnutí ohledně jazyka, dokud nemáme více uživatelů, tedy i více informací.
Migrace databází
Pro bezpečnou migraci databáze existuje :
- Přepsat kód pro podporu nových a starých formátů
- Převedení všech dat do nového formátu
- Odstranit starý přístup k datům
Výsledkem je, že migrace databáze se prodlužuje a vyžaduje mnoho zdrojů. A tak se nám hromadí zastaralé schéma, protože i jednoduché úkoly, jako je oprava názvu tabulky nebo sloupce, nestojí za vynaložené úsilí.
Dark má efektivní platformu pro migraci databází, která (doufáme) proces natolik zjednoduší, že se ho přestanete bát. Všechna datová úložiště v Dark (úložiště pár „klíč-hodnota“ nebo trvalé hash tabulky) mají typ. Chcete-li přesunout datové úložiště, jednoduše mu přiřadíte nový typ a funkci pro převod a návrat hodnot mezi oběma typy.
Přístup k datovým úložištím v Dark se provádí pomocí verzionovaných názvů proměnných. Například datové úložiště Users bude zpočátku nazváno Users-v0. Když je vytvořena nová verze s jiným typem, název se změní na Users-v1. Pokud jsou data uložena přes Users-v0 a přistupujete k nim přes Users-v1, použije se funkce návratu. Pokud jsou data uložena přes Users-v1 a přistupujete k nim přes Users-v0, použije se funkce návratu zpět.
Obrazovka migrace databáze s názvy polí staré databáze, výrazy návratu a návratu zpět a pokyny pro aktivaci migrace.
Používejte přepínače funkcí k nasměrování volání na Users-v0 na verzi Users-v1. To lze provést po jednom HTTP zpracovateli, aby se snížila rizika, a přepínače fungují pro jednotlivé uživatele, takže si můžete ověřit, že všechno funguje, jak bylo očekáváno. Jakmile uživatelé Users-v0 nebudou, Dark automaticky převede všechna zbývající data na pozadí ze starého formátu do nového. To si ani nevšimnete.
Testování
Dark je a neměnnými hodnotami, proto má výrazně menší plochu testování ve srovnání s objektově orientovanými jazyky s dynamickou typizací. Ale testovat se stejně musí.
V Dark editor automaticky spouští modulární testy na pozadí pro upravovaný kód a ve výchozím nastavení provádí tyto testy pro všechny přepínače funkcí. V budoucnu chceme pomocí statických typů automaticky provádět fuzzing kódu, aby se našly chyby.
Kromě toho Dark provádí vaši infrastrukturu v produkci, což otevírá nové možnosti. Automaticky ukládáme HTTP požadavky v infrastruktuře Dark (zatím ukládáme všechny požadavky, ale později se chceme posunout k výběru). Testujeme na nich nový kód a provádíme modulární testy, a pokud chcete, můžete snadno převést zajímavé požadavky na modulární testy.
Od čeho jsme se zbavili
Jelikož nemáme nasazení, ale máme přepínače funkcí, asi 60% nasazovacího pipeline zůstává mimo. Nepotřebujeme větve git nebo pull requesty, sestavování backendových zdrojů a kontejnerů, odesílání zdrojů a kontejnerů do registrů nebo kroky nasazení v Kubernetes.
Srovnání standardního pipeline pro kontinuální doručování (vlevo) a kontinuální doručení Dark (vpravo). V Dark se doručení skládá z 6 kroků a jednoho cyklu, zatímco tradiční verze zahrnuje 35 kroků a 3 cykly.
V Dark jsou v nasazení jen 4 kroky a 1 cyklus (kroky, které se opakují vícekrát), zatímco moderní pipeline pro kontinuální doručování se skládá z 35 kroků a 3 cyklů. V Dark se testy spouští automaticky a vy si toho ani nevšimnete; závislosti se instalují automaticky; vše, co se týká gitu nebo Githubu, už není potřeba; shromažďování, testování a odesílání kontejnerů Docker není potřeba; nasazení v Kubernetes už není potřeba.
I zbývající kroky v Dark se staly jednoduššími. Protože lze spravovat přepínače funkcí jednou akcí, není třeba znovu procházet celý nasazovací pipeline, abyste odstranili starý kód.
Snažili jsme se co nejvíce zjednodušit doručení kódu, zkrátit čas a rizika spojená s kontinuálním doručováním. Také jsme výrazně zjednodušili aktualizaci balíčků, migrace databází, testování, správu verzí, instalaci závislostí, rovnost mezi vývojovým a produkčním prostředím a rychlé a bezpečné upgrade verzí jazyka.
Na otázky k tomu odpovídám na .
Chcete-li se dozvědět více o zařízení Dark, přečtěte si , (nebo ke ) nebo . Pokud jedete na StrangeLoop v září, .
Zdroj: habr.com
