Com es crea una aplicació Golang connectable i es pot beneficiar de les capes AWS Lambda.

Golang: per què val la vostra atenció?

Golang és un llenguatge de programació de codi obert desenvolupat i implementat per Google. S'utilitza molt àmpliament en aplicacions modernes, especialment al núvol. Són els trets més característics:

  • Golang està escrit estàticament: ofereix menys flexibilitat però us protegeix dels errors,
  • No està orientat a objectes. Tanmateix, podeu crear estructures i interfícies, cosa que dóna lloc a 3 de cada 4 principis OOP: abstracció de dades, encapsulació i polimorfisme. Tot el que falta és l’herència
  • Goroutines! - La millor implementació dels filaments de llum que he utilitzat mai. Amb l’operador go podeu crear fàcilment un nou fil i comunicar-vos mitjançant canals entre diferents goroutines.
  • Es compila al fitxer binari únic amb totes les dependències; no hi ha més conflictes de paquets.

Personalment, considero que Golang és el millor idioma que faig servir cada dia. Tanmateix, aquest article no tracta de crear la primera funció ni d'imprimir "Hello World". Us mostraré coses més avançades. Si sou principiant i voleu obtenir més informació sobre Golang, visiteu la pàgina principal.

AWS Lambda & Golang

AWS Lambda és un dels serveis informàtics sense servidor més populars al núvol públic, llançat per Amazon Web Services el novembre de 2014. Podeu executar el vostre codi en resposta a esdeveniments com els activadors de DynamoDB, SNS o HTTP sense haver de configurar ni gestionar servidors. Saps què és realment fantàstic? Des del gener del 2018 dóna suport al terme Golang. Treballar amb AWS Lambda és molt senzill: només cal carregar un paquet comprimit amb el codi i totes les dependències (binari únic si utilitzeu Golang).

Avanç ràpid, 4 anys després, 2018 re: Invent AWS llança capes Lambda que us permeten emmagatzemar i gestionar dades que es comparteixen per a diverses funcions en un o fins i tot diversos comptes AWS. Per exemple, si utilitzeu Python, podeu posar totes les dependències en una capa addicional que posteriorment puguin utilitzar altres lambdas. Ja no cal posar dependències diferents a cada paquet comprimit. La situació és diferent al món Golang, ja que AWS Lambda requereix la càrrega de binaris compilats. Com podem beneficiar-nos de les capes AWS Lambda? La resposta és senzilla: creeu una aplicació modular amb connectors Golang.

Connectors Golang: una manera de construir una aplicació modular

Els connectors Golang són la característica publicada a Go1.8 que us permet carregar dinàmicament biblioteques compartides (fitxers .so). Podeu exportar part del vostre codi a la biblioteca independent o fer servir el connector que algú ha creat i compilat. No obstant això, és encoratjador que hi hagi algunes limitacions:

  • El vostre connector ha de ser un mòdul principal únic,
  • Només podeu carregar funcions i variables que s’exportin com a símbols ELF.
  • A causa de l’escriptura estàtica, heu de convertir tots els símbols carregats al tipus correcte. En el pitjor dels casos, haureu de definir la interfície correcta al codi,
  • Només funciona a Linux i MacOS. Personalment, no ho veig com un desavantatge :)

Creeu i proveu el vostre primer complement

Ara anem a crear el nostre primer complement. Com a exemple, crearem un mòdul senzill per al xifratge de cadenes. Tornem als conceptes bàsics i implementem dos algoritmes de xifratge simples: Ceasar i Verman.

  • El xifratge Cèsar és l'algorisme utilitzat per primera vegada per Julius Ceases. Canvia cada lletra del text pel nombre especificat de llocs. Per exemple, si voleu xifrar la paraula golang amb la clau 4, obtindreu etc. La desencriptació funciona de la mateixa manera. Tot el que heu de fer és moure les lletres en direcció contrària.
  • El xifratge Verman és similar al xifratge Ceaser, basat en la mateixa idea canviant. La diferència és que moveu cada lletra pel nombre de posicions diferents. Per desxifrar el text, necessiteu la clau amb les posicions on s’ha encriptat el text. Per exemple, si voleu xifrar la paraula golang amb la clau [-1, 4, 7, 20, 4, -2], obtindreu futur.

La implementació completa d’aquest exemple es pot trobar aquí.

Implementació de connectors

El fragment següent conté la implementació dels dos algorismes esmentats anteriorment. Per a cadascun, implementem dos mètodes per xifrar i desxifrar el nostre text:

Com podeu veure, hem exportat tres símbols diferents aquí (Golang només exporta aquests identificadors que comencen per la lletra anterior):

  • EncryptCeasar - func (int, string) Cadena que xifra el text mitjançant l'algorisme Ceasar.
  • DecryptCeaser - func (int, string) Cadena que descodifica el text mitjançant l'algorisme de Caeser,
  • VermanCipher: variable del tipus vermanCipher, que implementa 2 mètodes: Encrypt: func (string) string i Decrypt: func () (* string, error)

Per compilar aquest connector heu d'executar l'ordre següent:

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

En aquest moment no hi ha res d'especial: només s'han creat algunes funcions simples i s'ha compilat un mòdul com a complement afegint l'argument -buildmode = plugin.

Carregueu i proveu el connector

La diversió comença quan volem utilitzar el complement compilat a la nostra aplicació. Creem un exemple senzill:

Primer cal importar el paquet de complements Golang. Només conté dues funcions: la primera és carregar una biblioteca compartida i la segona és trobar un símbol exportat. Per carregar la biblioteca, heu d'utilitzar la funció Obre, per a la qual cal especificar el camí d'accés al vostre connector compartit i la variable de retorn del connector de tipus. Si no es pot carregar la biblioteca (per exemple, un camí erroni o un fitxer danyat), aquesta funció retorna l'error que cal gestionar.

El següent pas és carregar cada símbol exportat mitjançant el mètode de cerca. Un petit desavantatge és que heu de carregar cada funció exportada per separat. Tot i això, podeu combinar diverses funcions de la mateixa manera que ho vau fer amb el símbol VermanCipher. Ara que heu carregat tots els símbols que voleu utilitzar, els heu de convertir al tipus correcte. Golang és un llenguatge de tipus estàtic, de manera que no hi ha cap altra manera d’utilitzar aquests símbols sense emetre. Recordeu, si esteu exportant una variable que implementa alguns mètodes, haureu de convertir-la al tipus d’interfície correcta (havia de definir la interfície encryptionEngine per gestionar-ho). \ Newline \ newline

Utilitzeu l'ordre següent per compilar i executar l'aplicació:

ves a construir app.go ./app

A la sortida, hauríeu de veure el text xifrat i desxifrat com a prova que l'algorisme funciona correctament.

Utilitzeu el connector a AWS Lambda

Per utilitzar el nostre connector a AWS Lambda, hem de fer alguns canvis a la nostra aplicació:

  • AWS Lambda munta capes al directori / opt al contenidor Lambda, de manera que hem de carregar el nostre complement des d’aquest directori.
  • Hem de crear una funció de control que utilitzarà el motor Lambda per processar el nostre esdeveniment de prova.

El següent fragment conté la nostra aplicació que ha estat adaptada per ser utilitzada per Lambda:

Com podeu veure, la implementació és molt similar a l’anterior. Acabem de canviar el directori des del qual hem carregat el connector i hem afegit la resposta de la funció en lloc d’imprimir valors. Per obtenir més informació sobre com escriure lambdas a Golang, consulteu la documentació d’AWS.

Desplegament AWS Lambda

Hi ha dues maneres de desplegar funcions i capes d'AWS Lambda. Podeu crear i penjar un paquet comprimit manualment o utilitzar el marc avançat que el farà molt més fàcil i ràpid. Per a la majoria dels meus projectes faig servir el framework sense servidor. Per tant, ja he preparat el fitxer de configuració simple serverless.yml amb aquesta eina:

Servei: cipherService frameworkVersion: "> = 1.28.0 <2.0.0" Proveïdor: Nom: aws Temps d'execució: go1.x
Capes: cipherLayer: Camí: temps d'execució compatibles amb bin / plugin: - go1.x
Funcions: Motor: Gestor: paquet bin / cipherEngine: Exclou: - ./** Inclou: - ./bin/cipherEngine Capes: - {Ref: CipherLayerLambdaLayer}

A l'àrea de capes hem definit una sola capa amb el camí d'accés al complement que ja s'ha creat, que es proporciona juntament amb la funció Lambda. Podeu definir fins a 5 nivells diferents, l’ordre dels quals és realment important. Es munten al mateix directori / opt, de manera que les capes amb el nombre més alt poden sobreescriure fitxers de les capes muntades anteriorment. Per a cada nivell heu d'especificar com a mínim 2 paràmetres: camí d'accés al directori amb l'origen del nivell (en el vostre cas camí d'accés al fitxer binari del complement) i la llista de temps d'execució compatibles.

La següent secció de funcions és un lloc on definiu la llista de funcions a implementar. Per a cada funció, heu d'especificar com a mínim el camí d'accés a l'aplicació compilada. A més, hem de definir el paràmetre de capa fent referència a la capa definida anteriorment. Això afegirà automàticament la capa a la nostra funció Lambda durant el desplegament. El més curiós és que, si voleu fer referència a aquest recurs, heu de convertir el nom de la capa Lambda a TitleCased i afegir el sufix LambdaLayer. Sembla que l’equip sense servidor l’ha implementat d’aquesta manera per resoldre el conflicte pel que fa als diferents tipus de recursos.

Tan bon punt el nostre fitxer de configuració serverless.yml estigui llest, l'últim que heu de fer és compilar, connectar i desplegar la nostra aplicació. Per a això podem utilitzar Makefile senzill:

.PHONY: Build BuildPlugin es desplega netament
build: dep secure -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
net: rm -rf ./bin ./vendor Gopkg.lock
deploy: clean buildPlugin build sls deploy --verbose

Podeu crear i desplegar la vostra funció executant l'ordre següent:

proporcionar

Proveu AWS Lambda

Com s'ha esmentat anteriorment, AWS Lambda Code s'executa en la resposta a l'esdeveniment. Tot i això, no hem configurat cap activador d'esdeveniments, de manera que no es poden trucar sense la nostra ajuda. Hem de fer-ho manualment mitjançant Serverless Framework o l'eina awscli:

sls crida -f nom de funció aws invoca lambda - nom de funció nom de funció fitxer de sortida

A la resposta, hauríeu de veure la mateixa sortida que abans, cosa que demostra que la nostra funció lambda funciona correctament i que el connector es carrega des de la capa addicional. Ara podeu crear altres funcions que utilitzin la mateixa capa o fins i tot compartir-la amb altres comptes d’AWS.

Resum

Va ser molt divertit fer servir mòduls Golang i provar com es podrien integrar amb les AWS Lambda Layers recentment llançades. La biblioteca de connectors és realment fantàstica, però només es pot utilitzar en determinats escenaris a causa de les seves limitacions i l’especificació de Golang. Crec que per a la majoria dels desenvolupadors que treballen en projectes estàndard, els connectors no són necessaris ni tan sols possibles. Només puc pensar en dos motius:

  • Implementació d’algoritmes complicats que poden utilitzar les altres aplicacions, p. Algoritmes de codificació o xifratge de vídeo.
  • Comparteix el teu algorisme amb altres persones sense publicar el codi.