Si të krijoni një aplikacion pluglable Golang dhe të përfitoni nga AWS Lambda Layers.

Golang - pse ia vlen vëmendja juaj?

Golang është një gjuhë programimi me burim të hapur të zhvilluar dhe zbatuar nga Google. Përdoret shumë gjerësisht në aplikimet moderne, veçanërisht në re. Ato janë tiparet më karakteristike:

  • Golang është shkruar statikisht - ofron më pak fleksibilitet por ju mbron nga gabimet,
  • Nuk është e orientuar drejt objektit. Sidoqoftë, ju mund të krijoni struktura dhe ndërfaqe, dhe kjo jep 3 nga 4 parimet e OOP: abstragimi i të dhënave, kapsulimi dhe polimorfizmi. E tëra që mungon është trashëgimia
  • Goroutines! - Zbatimi më i mirë i fijeve të lehta që kam përdorur ndonjëherë. Me operatorin go ju lehtë mund të krijoni një fije të re dhe të komunikoni përmes kanaleve midis gorineve të ndryshme.
  • Isshtë përpiluar në skedarin binar të vetëm me të gjitha varësitë - jo më konflikte të paketave!

Personalisht, unë e konsideroj Golang si gjuhën më të mirë që përdor çdo ditë. Sidoqoftë, ky artikull nuk ka të bëjë me krijimin e funksionit tuaj të parë ose shtypjen e "Hello World". Do t'ju tregoj gjëra më të avancuara. Nëse jeni fillestar dhe dëshironi të mësoni më shumë rreth Golang, ju lutemi vizitoni faqen kryesore.

AWS Lambda & Golang

AWS Lambda është një nga shërbimet më të njohura të kompjuterave pa server në cloud publik, lëshuar nga Amazon Web Services në nëntor 2014. Mund ta ekzekutoni kodin tuaj në përgjigje të ngjarjeve si DynamoDB, SNS ose HTTP shkaktarët pa pasur nevojë të konfiguroni ose menaxhoni serverat! A e dini se çfarë është vërtet e mrekullueshme? Ajo ka mbështetur termin Golang që nga janari 2018. Puna me AWS Lambda është me të vërtetë e thjeshtë - thjesht ngarkoni një paketë të kompresuar me kodin tuaj dhe të gjitha varësitë (binar i vetëm nëse jeni duke përdorur Golang).

Shpejt përpara, 4 vjet më vonë, 2018 ri: Shpik AWS lëshon Lambda Layers që ju lejojnë të ruani dhe menaxhoni të dhëna që ndahen për funksione të ndryshme në një apo edhe shumë llogari AWS! Për shembull, nëse jeni duke përdorur Python, ju mund të vendosni të gjitha varësitë në një shtresë shtesë që mund të përdoret më vonë nga lambdas të tjerë. Nuk është më e nevojshme të vendosni varësi të ndryshme në secilën paketë zipped! Situata është e ndryshme në botën Golang pasi AWS Lambda kërkon ngarkimin e binareve të përpiluar. Si mund të përfitojmë nga shtresat AWS Lambda? Përgjigja është e thjeshtë - ndërtoni një aplikacion modular me shtojcat Golang!

Shtojcat Golang - një mënyrë për të ndërtuar një aplikacion modular

Golang Plugins është tipari i lëshuar në Go1.8 që ju lejon të ngarkoni në mënyrë dinamike bibliotekat e ndara (skedarët .so). Ju keni mundësinë të eksportoni një pjesë të kodit tuaj në bibliotekë të veçantë ose të përdorni shtojcën që është krijuar dhe përpiluar nga dikush tjetër. Sidoqoftë, është inkurajuese që ekzistojnë disa kufizime:

  • Shtojca juaj duhet të jetë një modul i vetëm kryesor,
  • Mund të ngarkoni vetëm funksione dhe variabla që eksportohen si simbole ELF.
  • Për shkak të shtypjes statike, duhet të shndërroni çdo simbol të ngarkuar në llojin e duhur. Në skenarin më të keq, duhet të përcaktoni ndërfaqen e saktë në kodin tuaj,
  • Punon vetëm në Linux dhe MacOS. Personalisht, unë nuk e shoh këtë si një disavantazh :)

Krijoni dhe provoni shtojcën tuaj të parë

Tani le të krijojmë shtojcën tonë të parë. Si shembull do të krijojmë një modul të thjeshtë për kriptimin e vargut. Le të kthehemi te bazat dhe të zbatojmë dy algoritme të thjeshtë të kriptimit - Ceasar dhe Verman.

  • Shifra e Cezarit është algoritmi i përdorur për herë të parë nga Julius Ceases. Ai zhvendos çdo shkronjë në tekst numrin e specifikuar të vendeve. Për shembull, nëse doni të kriptoni fjalën golang me tastin 4, do të merrni ktpek. Dekriptimi funksionon në të njëjtën mënyrë. E vetmja gjë që duhet të bësh është të lëvizësh shkronjat në drejtim të kundërt.
  • Shifra e Verman është e ngjashme me shifrën e Ceaser, bazuar në të njëjtën ide zhvendosëse. Dallimi është se ju lëvizni çdo letër me numrin e ndryshëm të pozicioneve. Për të deshifruar tekstin, ju duhet çelësi me pozicionet ku është kodifikuar teksti. Për shembull, nëse doni të kriptoni fjalën golang me tastin [-1, 4, 7, 20, 4, -2], do të merrni të ardhmen.

Zbatimi i plotë i këtij shembulli mund të gjendet këtu.

Zbatimi i shtojcës

Fragmenti i mëposhtëm përmban zbatimin e dy algoritmeve të përmendura më lart. Për secilën, ne zbatojmë dy metoda të kriptimit dhe dekriptimit të tekstit tonë:

Siç mund ta shihni, ne kemi eksportuar 3 simbole të ndryshme këtu (Golang eksporton vetëm këto identifikues që fillojnë me shkronjën më lart):

  • EncryptCeasar - func (int, string) Varg që kripton tekstin duke përdorur algoritmin Ceasar.
  • DecryptCeaser - func (int, string) Varg që deshifron tekstin duke përdorur algoritmin Caeser,
  • VermanCipher - ndryshore e tipit vermanCipher, e cila zbaton 2 metoda: Encrypt: vargu func (vargu) dhe Decrypt: func () (* vargu, gabimi)

Për të përpiluar këtë shtojcë duhet të ekzekutoni komandën e mëposhtme:

vazhdo të ndërtojë -buildmode = plugin -o plugin / cipher.so plugin / cipher.go

Nuk ka asgjë të veçantë për momentin - vetëm disa funksione të thjeshta janë krijuar dhe një modul është përpiluar si një shtojcë duke shtuar argumentin -buildmode = plugin.

Ngarko dhe provo shtojcën

Argëtimi fillon kur duam të përdorim shtojcën e përpiluar në aplikacionin tonë. Le të krijojmë një shembull të thjeshtë:

Së pari ju duhet të importoni paketën e shtojcave Golang. Ai përmban vetëm dy funksione - e para është të ngarkosh një bibliotekë të përbashkët dhe e dyta është të gjesh një simbol të eksportuar. Për të ngarkuar bibliotekën tuaj, duhet të përdorni funksionin Open, për të cilin duhet të specifikohet rruga për në shtojcën tuaj të përbashkët dhe ndryshoren e kthimit të tipit plug-in. Nëse biblioteka nuk mund të ngarkohet (p.sh. shtegu i gabuar ose skedari i dëmtuar), ky funksion kthen gabimin që duhet trajtuar.

Hapi tjetër është të ngarkoni secilin simbol të eksportuar duke përdorur metodën e kërkimit. Një disavantazh i vogël është se duhet të ngarkoni secilin funksion të eksportuar veç e veç. Sidoqoftë, mund të kombinoni shumë funksione në të njëjtën mënyrë siç bëtë për simbolin VermanCipher. Tani që keni ngarkuar të gjithë simbolet që dëshironi të përdorni, duhet t'i ktheni ato në llojin e saktë. Golang është një gjuhë e shtypur statikisht, kështu që nuk ka asnjë mënyrë tjetër për të përdorur këto simbole pa hedhur. Mos harroni, nëse jeni duke eksportuar një variabël që zbaton disa metoda, ju nevojitet për ta hedhur atë në llojin e duhur të ndërfaqes (duhej të përcaktoja ndërfaqen encryptionEngine për ta trajtuar këtë). \ Newline \ newline

Përdorni komandën e mëposhtme për të përpiluar dhe ekzekutuar aplikacionin:

shko ndërto app.go ./app

Në dalje, ju duhet të shihni tekstin e koduar dhe të dekriptuar si dëshmi se algoritmi po punon si duhet.

Përdorni shtojcën në AWS Lambda

Për të përdorur shtojcën tonë në AWS Lambda, duhet të bëjmë disa ndryshime në aplikacionin tonë:

  • AWS Lambda monton shtresat në direktorinë / opt në kontejnerin Lambda, kështu që duhet të ngarkojmë shtojcën tonë nga ky direktori.
  • Ne duhet të krijojmë një funksion mbajtës që do të përdoret nga motori Lambda për të përpunuar ngjarjen tonë të provës.

Fragmenti i mëposhtëm përmban aplikacionin tonë i cili është përshtatur për t'u përdorur nga Lambda:

Siç mund ta shihni, zbatimi është shumë i ngjashëm me atë të mëparshëm. Ne sapo ndryshuam direktorinë nga e cila ngarkuam shtojcën tonë dhe shtuam përgjigjen e funksionit në vend që të shtypnim vlerat. Për më shumë informacion mbi shkrimin e lambdas në Golang, shihni dokumentacionin e AWS.

Vendosja e AWS Lambda

Ekzistojnë dy mënyra për të vendosur funksionet dhe shtresat e AWS Lambda. Ju mund të krijoni dhe ngarkoni një paketë të kompresuar manualisht ose të përdorni kornizën e përparuar e cila do ta bëjë atë shumë më të lehtë dhe më të shpejtë. Për shumicën e projekteve të mia unë përdor kornizën pa server. Prandaj, unë kam përgatitur tashmë skedarin e thjeshtë të konfigurimit serverless.yml me këtë mjet:

Shërbimi: cipherService frameVersion: "> = 1.28.0 <2.0.0" Ofruesi: Emri: aws Runtime: go1.x
Shtresat: cipherLayer: Shtegu: kohëzgjatjet e përputhshme me bin / plugin: - go1.x
Funksionet: Motori: Trajtuesi: bin / cipher Paketa e Motorit: Përjashto: - ./** Përfshi: - ./bin/cipherEngine Shtresat: - {Ref: CipherLayerLambdaLayer}

Në zonën e shtresës, ne kemi përcaktuar një shtresë të vetme me rrugën drejt shtojcës që është krijuar tashmë - kjo sigurohet së bashku me funksionin Lambda. Ju mund të përcaktoni deri në 5 nivele të ndryshme, renditja e të cilave është me të vërtetë e rëndësishme. Ata janë montuar në të njëjtën direktori / opt, kështu që shtresat me numrin më të lartë mund të mbishkruajnë skedarët nga shtresat e montuara më parë. Për secilin nivel duhet të specifikoni të paktën 2 parametra: shtegu drejt direktorisë me burimin e nivelit (në rrugën tuaj të çështjes në skedarin binar të plug-in) dhe listën e kohëzgjatjeve të pajtueshme.

Seksioni tjetër i funksionit është një vend ku ju përcaktoni listën e funksioneve që do të implementohen. Për secilin funksion duhet të paktën të specifikoni shtegun drejt aplikimit të përpiluar. Përveç kësaj, ne duhet të përcaktojmë parametrin e shtresës duke iu referuar shtresës së përcaktuar më sipër. Kjo automatikisht do të shtojë shtresën në funksionin tonë Lambda gjatë vendosjes. Gjëja qesharake është se nëse doni t'i referoheni këtij burimi, duhet të shndërroni emrin e shtresës Lambda në TitleCased dhe të shtoni prapashtesën LambdaLayer. Duket se ekipi pa server e zbatoi atë në këtë mënyrë për të zgjidhur konfliktin në lidhje me llojet e ndryshme të burimeve.

Sapo skedari ynë i konfigurimit serverless.yml të jetë gati, gjëja e fundit që duhet të bëni është të përpiloni, lidhni dhe vendosni aplikacionin tonë. Për këtë mund të përdorim një skedar të thjeshtë:

.PHONY: Ndërtoni BuildPlugin vendoseni pastër
ndërto: dep sigurt -v env GOOS = Linux shko ndërto -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
pastër: rm -rf ./bin ./vendor Gopkg.bllokohet
vendosja: ndërtimi i pastërSlugs ndërtimin e plugin vendos - vendosmëri

Ju mund të ndërtoni dhe vendosni funksionin tuaj duke ekzekutuar komandën e mëposhtme:

sigurojnë

Provoni AWS Lambda

Siç u përmend më herët, Kodi AWS Lambda funksionon në përgjigjen e ngjarjes. Sidoqoftë, ne nuk kemi konfiguruar ndonjë shkak të ngjarjeve, kështu që ata nuk mund të thirren pa ndihmën tonë. Ne duhet ta bëjmë atë manualisht duke përdorur Kornizën pa Server ose mjetin awscli:

thirrjet sls -f funksion-name aws lambda invoke - funksion-emër funksion-emër-dalje skedar

Në përgjigje, duhet të shihni të njëjtin dalje si më parë, gjë që dëshmon se funksioni ynë lambda po funksionon si duhet dhe se shtojca ngarkohet nga shtresa shtesë. Tani mund të krijoni funksione të tjera që përdorin të njëjtën shtresë ose edhe ta ndani atë me llogaritë e tjera të AWS.

Përmbledhje

Ishte kënaqësi e shkëlqyeshme duke përdorur modulet Golang dhe duke provuar se si ato mund të integrohen me AWS Lambda Layers. Biblioteka e shtojcave është me të vërtetë e shkëlqyeshme, por mund të përdoret vetëm në disa skenarë për shkak të kufizimeve të saj dhe specifikimeve Golang. Unë mendoj se për shumicën e zhvilluesve që punojnë në projektet standarde, shtojcat nuk kërkohen ose madje janë të mundshme. Unë mund të mendoj vetëm për dy arsye:

  • Zbatimi i algoritmeve të ndërlikuar që mund të përdoren nga aplikacionet e tjera, p.sh. Algoritmet e kodimit ose kriptimit të videos.
  • Ndani algoritmin tuaj me të tjerët pa botuar kodin.