Ako zostaviť zásuvnú aplikáciu Golang a využívať výhody AWS Lambda Layers.

Golang - prečo to stojí za pozornosť?

Golang je programovací jazyk s otvoreným zdrojovým kódom navrhnutý a implementovaný spoločnosťou Google. Je veľmi široko používaný v moderných aplikáciách, najmä v cloude. Najcharakteristickejšie vlastnosti sú:

  • Golang je staticky napísaný - poskytuje menšiu flexibilitu, ale chráni vás pred chybami,
  • Nie je objektovo orientovaný. Môžete však vytvárať štruktúry a rozhrania, ktoré vám poskytujú 3 zo 4 zásad OOP: abstrakcia údajov, zapuzdrenie a polymorfizmus. Dedičstvo chýba iba,
  • Goroutines! - najväčšia implementácia ľahkých vlákien, aké som kedy použil. Umožňuje vám jednoduchým spôsobom vytvárať nové vlákno pomocou operátora go a komunikovať medzi rôznymi goroutinami pomocou kanálov,
  • Kompiluje sa do jedného binárneho súboru so všetkými závislosťami - žiadne konflikty ďalších balíkov!

Osobne považujem Golang za najväčší jazyk, ktorý denne používam. Tento článok sa však nebude týkať vytvorenia prvej funkcie alebo tlače „Hello World“. Ukážem ti trochu pokročilejšie veci. Ak ste začiatočník a chcete sa dozvedieť viac o Golang, navštívte jeho hlavnú stránku.

AWS Lambda & Golang

AWS Lambda je jednou z najpopulárnejších výpočtových služieb bez serverov vo verejnom cloude, ktorú v novembri 2014 uviedla spoločnosť Amazon Web Services. To vám umožní spustiť váš kód v reakcii na udalosti, ako sú dynamoDB, SNS alebo HTTP triggery bez zaistenia alebo správy serverov! Viete, čo je skutočne skvelé? Od januára 2018 podporuje runtime Golang. Práca s AWS Lambda je skutočne jednoduchá - stačí nahrať balíček so zipsom so svojím kódom a všetkými závislosťami (pri použití Golangu je jeden binárny súbor).

Rýchly posun vpred, o 4 roky neskôr v roku 2018: Invent AWS vydáva vrstvy Lambda, ktoré vám umožňujú ukladať a spravovať údaje, ktoré sú zdieľané medzi rôznymi funkciami v jednom alebo viacerých účtoch AWS! Napríklad, keď používate Python, môžete dať všetky závislosti do ďalšej vrstvy, ktorú môžu neskôr použiť aj iné Lambdy. V každom balení so zipsom už nemusíte uvádzať rôzne závislosti! Vo svete Golang je situácia iná, pretože spoločnosť AWS Lambda vyžaduje, aby ste odovzdali skompilovaný binárny súbor. Ako môžeme profitovať z vrstiev AWS Lambda Layers? Odpoveď je jednoduchá - vytvorte modulárnu aplikáciu pomocou doplnkov Golang!

Golang Pluginy - spôsob, ako zostaviť modulárnu aplikáciu

Golang Plugins je funkcia vydaná v Go1.8, ktorá vám umožňuje dynamicky načítať zdieľané knižnice (.so súbory). Poskytuje vám možnosť exportovať časť kódu do samostatnej knižnice alebo použiť doplnok pripravený a zostavený niekým iným. Sľubné je však niekoľko obmedzení:

  • Váš doplnok musí byť jedným hlavným modulom,
  • Môžete načítať iba funkcie a premenné, ktoré sa exportujú ako symboly ELF,
  • Kvôli statickému písaniu musíte každý načítaný symbol prenášať na správny typ. V najhoršom prípade musíte v kóde definovať správne rozhranie,
  • Funguje to iba pre systémy Linux a MacOS. Osobne to nepovažujem za nevýhodu :)

Vytvorenie a testovanie prvého doplnku

Teraz vytvorme náš prvý doplnok. Ako príklad vytvoríme jednoduchý modul pre šifrovanie reťazcov. Vráťme sa k základom a implementujeme 2 jednoduché šifrovacie algoritmy - Ceasar a Verman.

  • Caesarova šifra je algoritmus, ktorý prvýkrát použil Julius Ceases. Posúva každé písmeno v texte o pevný počet pozícií. Napríklad, ak chcete zašifrovať slovo golang pomocou kľúča 4, dostanete ktpek. Dešifrovanie funguje rovnakým spôsobom. Potrebujete iba posunúť písmená opačným smerom.
  • Vermanova šifra je podobná Ceaserovej, na základe rovnakej myšlienky posunu je rozdiel v tom, že posuniete každé písmeno o iný počet pozícií. Na dešifrovanie textu musíte mať kľúč obsahujúci pozície použité na šifrovanie textu. Napríklad, ak chcete zašifrovať slovo golang pomocou kľúča [-1, 4, 7, 20, 4, -2], dostanete budúcnosť.

Úplná implementácia tohto príkladu je k dispozícii tu.

Implementácia doplnku

Nasledujúci úryvok obsahuje implementáciu vyššie uvedených dvoch algoritmov. Pre každú z nich implementujeme 2 metódy šifrovania a dešifrovania nášho textu:

Ako vidíte, exportovali sme tu 3 rôzne symboly (Golang exportuje iba tieto identifikátory, ktoré začínajú horným písmenom):

  • EncryptCeasar - func (int, string) reťazec, ktorý šifruje text pomocou algoritmu Ceasar,
  • DecryptCeaser - func (int, string) reťazec, ktorý dešifruje text pomocou Caeserovho algoritmu,
  • VermanCipher - premenná typu vermanCipher implementujúca 2 metódy: Encrypt: func (string) string a Decrypt: func () (* string, error)

Ak chcete zostaviť tento doplnok, musíte spustiť nasledujúci príkaz:

go build -buildmode = plugin -o plugin / cipher.so plugin / cipher.go

Zatiaľ nie je nič zvláštne - bolo vytvorených niekoľko jednoduchých funkcií a modul bol zostavený ako doplnok pridaním argumentu -buildmode = plugin.

Načítať a testovať doplnok

Zábava začína, keď chceme v našej aplikácii použiť zostavený doplnok. Vytvorme jednoduchý príklad:

Najprv musíte importovať balík doplnkov golang. Obsahuje iba dve funkcie - prvá slúži na načítanie zdieľanej knižnice a druhá na nájdenie exportovaného symbolu. Na načítanie knižnice musíte použiť funkciu Open, ktorá vyžaduje poskytnutie cesty k zdieľanému doplnku a vráti premennú typu Plugin. Ak načítanie knižnice nie je možné (napr. Nesprávna cesta alebo poškodený súbor), táto funkcia vráti chybu, ktorá sa musí vyriešiť.

Ďalším krokom je načítanie každého exportovaného symbolu pomocou metódy vyhľadávania. Miernou nepríjemnosťou je, že musíte každú exportovanú funkciu načítať osobitne. Môžete však kombinovať viacero funkcií rovnakým spôsobom, ako sa to stalo pre symbol VermanCipher. Po načítaní všetkých symbolov, ktoré chcete použiť, ich musíte preniesť na správny typ. Golang je staticky napísaný jazyk, takže neexistuje žiadny iný spôsob použitia týchto symbolov bez obsadenia. Pamätajte, že keď exportujete premennú, ktorá implementuje niekoľko metód, musíte ju preniesť na správny typ rozhrania (na to som musel definovať rozhranie šifrovaniaEngine). \ Newline \ newline

Na zostavenie a spustenie aplikácie použite nasledujúci príkaz:

choďte zostaviť app.go
./app

Vo výstupe by ste mali vidieť šifrovaný a dešifrovaný text ako dôkaz, že algoritmus funguje správne.

Použite doplnok v AWS lambda

Ak chcete použiť náš doplnok v AWS Lambda, musíme urobiť niekoľko úprav v našej aplikácii:

  • AWS Lambda pripojí vrstvy do adresára / opt v kontajneri lambda, takže musíme načítať náš doplnok z tohto adresára.
  • Potrebujeme vytvoriť funkciu obsluhy, ktorú bude používať motor Lambda na zvládnutie našej testovacej udalosti.

Nasledujúci úryvok obsahuje našu aplikáciu upravenú na používanie v Lambde:

Ako vidíte, implementácia je veľmi podobná predchádzajúcej. Zmenili sme iba adresár, z ktorého sme načítali náš doplnok, a namiesto tlačených hodnôt sme pridali odpoveď na funkciu. Ak sa chcete dozvedieť viac o písaní Lambdas v golang, prečítajte si dokumentáciu AWS.

Nasadenie AWS Lambda

Existujú dva spôsoby nasadenia funkcií a vrstiev AWS Lambda. Balík so zipsom môžete vytvoriť a nahrať manuálne alebo použiť pokročilejší rámec, čo výrazne uľahčuje a zrýchľuje. Pre väčšinu svojich projektov používam framework Serverless, takže som už pripravil jednoduchý konfiguračný súbor serverless.yml pomocou tohto nástroja:

služba: cipherService
frameworkVersion: "> = 1.28.0 <2.0.0"
poskytovateľ:
  meno: aws
  runtime: go1.x
vrstvy:
  cipherLayer:
    cesta: bin / plugin
    compatibleRuntimes:
      - go1.x
funkcie:
  motor:
    obsluha: bin / cipherEngine
    balenie:
      vylúčenia:
        - ./**
      zahŕňajú:
        - ./bin/cipherEngine
    vrstvy:
      - {Ref: CipherLayerLambdaLayer}

V sekcii vrstiev sme definovali jednu vrstvu s cestou k už vytvorenému doplnku - bude nasadený spolu s funkciou lambda. Môžete definovať až 5 rôznych vrstiev, ktorých poradie je skutočne dôležité. Sú pripojené k rovnakému adresáru / opt, takže vrstvy s vyšším počtom môžu prepísať súbory z predtým pripojených vrstiev. Pre každú vrstvu musíte zadať najmenej 2 parametre: cestu k adresáru obsahujúcemu zdroj vrstvy (cestu k binárnemu doplnku vo vašom prípade) a zoznam kompatibilných runtime.

Ďalšia časť funkcií je miesto, kde môžete definovať zoznam funkcií, ktoré sa majú nasadiť. Pre každú funkciu musíte poskytnúť aspoň cestu k kompilovanej aplikácii. Okrem toho musíme definovať parameter vrstvy s odkazom na vrstvu definovanú vyššie. Počas nasadenia sa vrstva automaticky pripojí k našej funkcii Lambda. Legrační je, že musíte previesť názov vrstvy lambda na názov TitleCased a pridať príponu LambdaLayer, ak sa chcete na tento zdroj odvolať. Zdá sa, že tím Serverless ho implementoval týmto spôsobom, aby vyriešil konflikt s odkazom na rôzne typy zdrojov.

Akonáhle je náš konfiguračný súbor serverless.yml pripravený, poslednou vecou, ​​ktorú treba urobiť, je zostaviť našu aplikáciu, plugin a nasadiť ju. Na to môžeme použiť jednoduchý Makefile:

.PHONY: build buildPlugin čisté nasadenie
build:
 dep zaistenie -v
 env GOOS = linux go build -ldflags = "- s -w" -o bin / cipherEngine cipherEngine / main.go
buildPlugin:
 env GOOS = linux go build -ldflags = "- s -w" -buildmode = plugin -o bin / plugin / cipher.so ../plugin/cipher.go
clean:
 rm -rf ./bin ./vendor Gopkg.lock
nasadiť: čistý buildPlugin build
 sls nasadiť - verbose

Funkciu môžete zostaviť a nasadiť spustením nasledujúceho príkazu:

nasadiť

Testujte AWS Lambda

Ako som už spomenul, AWS Lambda v reakcii na udalosť vykoná kód. Nenakonfigurovali sme však žiadne spúšťače udalostí, takže nebude vyvolaná bez našej pomoci. Musíme to urobiť ručne pomocou rámca Serverless alebo nástroja awscli:

sls invoke -f function_name
aws lambda invoke - function-name function_name output_file

V odpovedi by ste mali vidieť rovnaký výstup ako predtým, čo dokazuje, že naša funkcia lambda funguje správne a načíta doplnok z ďalšej vrstvy. Teraz môžete vytvoriť ďalšie funkcie, ktoré budú používať rovnakú vrstvu alebo ich dokonca zdieľajú s inými účtami AWS.

zhrnutie

Bolo veľa zábavy používať moduly Golang a otestovať, ako ich integrovať do novo vydaných vrstiev AWS Lambda Layers. Knižnica doplnkov je naozaj úžasná, avšak kvôli svojim obmedzeniam a špecifikácii Golang ju možno použiť iba v niektorých špeciálnych scenároch. Myslím si, že pre väčšinu vývojárov, ktorí pracujú na štandardných projektoch, nebude potrebné alebo dokonca možné používať doplnky. Majú na mysli iba dva dôvody:

  • Implementácia komplikovaných algoritmov, ktoré môžu byť použité v iných aplikáciách napr. algoritmy kódovania videa alebo šifrovania.
  • Zdieľajte svoj algoritmus s ostatnými bez zverejnenia jeho kódu.