Paano Lumikha ng isang Pluggable Golang Application at Pakinabang mula sa AWS Lambda Layers.

Golang - bakit sulit ang iyong pansin?

Ang Golang ay isang bukas na mapagkukunan ng wika ng programa na binuo at ipinatupad ng Google. Ginagamit ito ng napakalawak sa mga modernong application, lalo na sa cloud. Ang mga ito ang pinaka tampok na tampok:

  • Statikong nakasulat ang Golang - nag-aalok ito ng mas kaunting kakayahang umangkop ngunit pinoprotektahan ka mula sa mga pagkakamali,
  • Hindi ito nakatuon sa object. Gayunpaman, maaari kang lumikha ng mga istraktura at interface, at magbubunga ng 3 sa 4 na mga prinsipyo ng OOP: abstraction ng data, encapsulation at polymorphism. Ang nawawala lang ay mana
  • Mga Goroutine! - Ang pinakamahusay na pagpapatupad ng mga filament ng ilaw na ginamit ko kailanman. Sa pamamagitan ng go operator madali kang makakalikha ng isang bagong thread at makipag-usap sa pamamagitan ng mga channel sa pagitan ng iba't ibang mga goroutine.
  • Pinagsama-sama ito sa solong binary file kasama ang lahat ng mga dependency - wala nang mga salungatan sa package!

Sa personal, isinasaalang-alang ko ang Golang na pinakadakilang wika na ginagamit ko araw-araw. Gayunpaman, ang artikulong ito ay hindi tungkol sa paglikha ng iyong unang pag-andar o pag-print ng "Hello World". Ipapakita ko sa iyo ang medyo mas advanced na bagay. Kung ikaw ay isang nagsisimula at nais na malaman ang tungkol sa Golang, mangyaring bisitahin ang pangunahing pahina.

AWS Lambda & Golang

Ang AWS Lambda ay isa sa pinakatanyag na mga serbisyo ng compute ng serverless sa pampublikong ulap, na inilabas ng Amazon Web Services noong Nobyembre 2014. Maaari mong patakbuhin ang iyong code bilang tugon sa mga kaganapan tulad ng mga pag-trigger ng DynamoDB, SNS, o HTTP nang hindi kinakailangang i-set up o pamahalaan ang mga server! Alam mo ba kung ano ang talagang mahusay? Sinusuportahan nito ang term na Golang mula Enero 2018. Ang pagtatrabaho sa AWS Lambda ay talagang madali - mag-upload lamang ng isang naka-compress na package sa iyong code at lahat ng mga dependency (solong binary kung gumagamit ka ng Golang).

Mabilis, 4 na taon na ang lumipas, ang muling 2018 Invent ang AWS ay naglabas ng Lambda Layers na nagbibigay-daan sa iyo upang mag-imbak at mamahala ng data na ibinabahagi para sa iba't ibang mga pag-andar sa isa o kahit maraming mga AWS account! Halimbawa, kung gumagamit ka ng Python, maaari mong ilagay ang lahat ng mga dependency sa isang karagdagang layer na maaaring magamit ng ibang lambdas sa paglaon. Hindi na kinakailangan na maglagay ng iba't ibang mga dependency sa bawat naka-zip na pakete! Ang sitwasyon ay naiiba sa mundo ng Golang dahil ang AWS Lambda ay nangangailangan ng pag-upload ng pinagsamang mga binary. Paano tayo makikinabang sa AWS Lambda Layers? Ang sagot ay simple - bumuo ng isang modular application gamit ang mga Golang plugin!

Golang plugins - isang paraan upang bumuo ng isang modular application

Ang Golang Plugins ay ang tampok na inilabas sa Go1.8 na nagbibigay-daan sa iyo upang ma-dynamically i-load ang mga nakabahaging library (.so mga file). Mayroon kang pagpipilian upang i-export ang bahagi ng iyong code sa magkakahiwalay na silid-aklatan o upang magamit ang plugin na nilikha at naipon ng ibang tao. Gayunpaman, nakapagpapatibay na mayroong ilang mga limitasyon:

  • Ang iyong plugin ay dapat na isang solong pangunahing module,
  • Maaari mo lamang mai-load ang mga pagpapaandar at variable na na-export bilang mga simbolo ng ELF.
  • Dahil sa static na pagta-type, kailangan mong i-convert ang bawat na-load na simbolo sa tamang uri. Sa pinakapangit na sitwasyon, kailangan mong tukuyin ang tamang interface sa iyong code,
  • Gumagana lamang ito sa Linux at MacOS. Sa personal, hindi ko ito nakikita bilang isang kawalan :)

Lumikha at subukan ang iyong unang plugin

Ngayon ay lumikha tayo ng aming unang plugin. Bilang isang halimbawa lilikha kami ng isang simpleng module para sa pag-encrypt ng string. Bumalik tayo sa mga pangunahing kaalaman at ipatupad ang dalawang simpleng mga algorithm ng pag-encrypt - Ceasar at Verman.

  • Ang Caesar cipher ay ang algorithm na unang ginamit ni Julius Ceases. Inililipat nito ang bawat titik sa teksto ng tinukoy na bilang ng mga lugar. Halimbawa, kung nais mong i-encrypt ang salitang golang sa key 4, makakakuha ka ng ktpek. Gumagana ang decryption sa parehong paraan. Ang kailangan mo lang gawin ay ilipat ang mga titik sa kabaligtaran na direksyon.
  • Ang Verman cipher ay katulad ng Ceaser cipher, batay sa parehong ideya ng paglilipat. Ang pagkakaiba ay ang paglipat mo sa bawat titik ng magkakaibang bilang ng mga posisyon. Upang mai-decrypt ang teksto, kailangan mo ang susi ng mga posisyon kung saan naka-encrypt ang teksto. Halimbawa, kung nais mong i-encrypt ang salitang golang gamit ang susi na [-1, 4, 7, 20, 4, -2], makakakuha ka ng hinaharap.

Ang buong pagpapatupad ng halimbawang ito ay matatagpuan dito.

Pagpapatupad ng plugin

Naglalaman ang sumusunod na snippet ng pagpapatupad ng dalawang mga algorithm na nabanggit sa itaas. Para sa bawat isa, nagpapatupad kami ng dalawang pamamaraan ng pag-encrypt at pag-decrypt ng aming teksto:

Tulad ng nakikita mo, na-export namin dito ang 3 magkakaibang mga simbolo (i-export lamang ng Golang ang mga tagakilala na nagsisimula sa liham sa itaas):

  • EncryptCeasar - func (int, string) String na naka-encrypt ang teksto gamit ang Ceasar algorithm.
  • DecryptCeaser - func (int, string) String na nagde-decode ng teksto gamit ang Caeser algorithm,
  • VermanCipher - variable ng uri ng vermanCipher, na nagpapatupad ng 2 pamamaraan: I-encrypt: func (string) string at Decrypt: func () (* string, error)

Upang maipon ang plugin na ito kailangan mong patakbuhin ang sumusunod na utos:

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

Sa ngayon walang espesyal - ilang simpleng mga pag-andar lamang ang nagawa at isang module ay naipon bilang isang plugin sa pamamagitan ng pagdaragdag ng argument na-buildmode = plugin.

I-load at subukan ang plugin

Nagsisimula ang kasiyahan kapag nais naming gamitin ang naipon na plugin sa aming app. Lumikha tayo ng isang simpleng halimbawa:

Una kailangan mong i-import ang Golang plugin package. Naglalaman lamang ito ng dalawang mga pag-andar - ang una ay upang mag-load ng isang nakabahaging library at ang pangalawa ay upang makahanap ng isang na-export na simbolo. Upang mai-load ang iyong library, kailangan mong gamitin ang Buksan na pag-andar, kung saan ang landas sa iyong nakabahaging plug-in at ang variable ng pagbabalik ng uri ng plug-in ay dapat na tukuyin. Kung hindi mai-load ang library (hal. Maling landas o nasirang file), ibabalik ng pagpapaandar na ito ang error na kailangang hawakan.

Ang susunod na hakbang ay upang mai-load ang bawat simbolo na na-export gamit ang paraan ng paghahanap. Ang isang maliit na kawalan ay kailangan mong i-load ang bawat nai-export na function nang magkahiwalay. Gayunpaman, maaari mong pagsamahin ang maraming mga pag-andar sa parehong paraan na ginawa mo para sa simbolo ng VermanCipher. Matapos mai-load ang lahat ng mga simbolo na nais mong gamitin, kailangan mong i-convert ang mga ito sa tamang uri. Ang Golang ay isang statically typed na wika, kaya walang ibang paraan upang magamit ang mga simbolong ito nang hindi naghahagis. Tandaan, kung nag-i-export ka ng isang variable na nagpapatupad ng ilang mga pamamaraan na kailangan mo upang maihatid ito sa tamang uri ng interface (kailangan kong tukuyin ang naka-encrypt na interface ng Ingles upang mahawakan ito). \ Newline \ newline

Gamitin ang sumusunod na utos upang mag-ipon at patakbuhin ang app:

go build app.go ./app

Sa output, dapat mong makita ang naka-encrypt at na-decrypt na teksto bilang katibayan na gumagana nang maayos ang algorithm.

Gamitin ang plugin sa AWS Lambda

Upang magamit ang aming plugin sa AWS Lambda, kailangan naming gumawa ng ilang mga pagbabago sa aming application:

  • Ang AWS Lambda ay nai-mount ang mga layer sa direktoryo / opt sa lalagyan ng Lambda, kaya kailangan naming i-load ang aming plug-in mula sa direktoryong ito.
  • Kailangan naming lumikha ng isang handler function na gagamitin ng Lambda engine upang maproseso ang aming kaganapan sa pagsubok.

Naglalaman ang sumusunod na snippet ng aming application na inangkop upang magamit ng Lambda:

Tulad ng nakikita mo, ang pagpapatupad ay halos kapareho ng dati. Pinalitan lang namin ang direktoryo kung saan na-load ang aming plugin at idinagdag ang tugon sa pag-andar sa halip na i-print ang mga halaga. Para sa karagdagang impormasyon sa pagsulat ng lambdas sa Golang, tingnan ang dokumentasyon ng AWS.

Pag-deploy ng AWS Lambda

Mayroong dalawang paraan upang mag-deploy ng mga pag-andar at layer ng AWS Lambda. Maaari kang lumikha at mag-upload ng isang naka-compress na package nang manu-mano o gamitin ang advanced na balangkas na gagawing mas madali at mas mabilis. Para sa karamihan ng aking mga proyekto ginagamit ko ang framework na walang server. Samakatuwid handa na ako ang simpleng pagsasaayos ng file serverless.yml gamit ang tool na ito:

Serbisyo: cipherService frameworkVersion: "> = 1.28.0 <2.0.0" Provider: Pangalan: aws Runtime: go1.x
Mga layer: cipherLayer: Path: bin / plugin na katugmang runtime: - go1.x
Mga Pag-andar: Engine: Handler: bin / cipherEngine Package: Ibukod: - ./akio Isama: - ./bin/cipherEngine Layers: - {Ref: CipherLayerLambdaLayer}

Sa lugar ng layer, tinukoy namin ang isang solong layer na may landas sa plug-in na nilikha - ito ay ibinigay kasama ang pagpapaandar ng Lambda. Maaari mong tukuyin ang hanggang sa 5 magkakaibang mga antas, ang pagkakasunud-sunod nito ay talagang mahalaga. Naka-mount ang mga ito sa pareho / direktoryo ng opt, kaya ang mga layer na may mas mataas na bilang ay maaaring mai-overlap ang mga file mula sa dating naka-mount na mga layer. Para sa bawat antas kailangan mong tukuyin ang hindi bababa sa 2 mga parameter: path sa direktoryo na may pinagmulan ng antas (sa iyong landas ng kaso sa plug-in na binary file) at ang listahan ng mga katugmang runtime.

Ang susunod na seksyon ng pag-andar ay isang lugar kung saan tinukoy mo ang listahan ng mga pagpapaandar na ipapatupad. Para sa bawat pag-andar dapat mong tukuyin man lang ang landas sa pinagsamang aplikasyon. Bilang karagdagan, kailangan naming tukuyin ang parameter ng layer na may sanggunian sa layer na tinukoy sa itaas. Awtomatiko nitong idadagdag ang layer sa aming pag-andar ng Lambda habang inilalagay. Ang nakakatawang bagay ay kung nais mong mag-refer sa mapagkukunang ito, kailangan mong i-convert ang iyong pangalan ng layer ng Lambda sa TitleCased at idagdag ang panlapi ng LambdaLayer. Tila ipinatupad ito ng walang server na server sa ganitong paraan upang malutas ang tunggalian patungkol sa iba't ibang mga uri ng mapagkukunan.

Sa sandaling handa na ang aming file ng pagsasaayos na serverless.yml, ang huling bagay na kailangan mong gawin ay mag-ipon, mag-plug in at i-deploy ang aming app. Para sa mga ito maaari naming gamitin ang simpleng Makefile:

.PHONY: Buuin nang malinis ang Build BuildPlugin
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
malinis: rm -rf ./bin ./vendor Gopkg.lock
i-deploy: malinis na buildPlugin build sls deploy --verbose

Maaari mong buuin at maipalawak ang iyong pagpapaandar sa pamamagitan ng pagpapatakbo ng sumusunod na utos:

magbigay

Subukan ang AWS Lambda

Tulad ng nabanggit kanina, tumatakbo ang AWS Lambda Code bilang tugon sa kaganapan. Gayunpaman, hindi namin na-configure ang anumang mga nag-trigger ng kaganapan kaya hindi sila maaaring tawagan nang wala ang aming tulong. Kailangan nating gawin ito nang manu-mano sa Serverless Framework o sa tool na awscli:

tawag ng sls -f function-name aws lambda invoke - function-name function-name output-file

Sa sagot, dapat mong makita ang parehong output tulad ng dati, na nagpapatunay na ang aming lambda function ay gumagana nang tama at na naglo-load ang plugin mula sa labis na layer. Ngayon ay maaari kang lumikha ng iba pang mga pagpapaandar na gumagamit ng parehong layer o kahit na ibahagi ito sa iba pang mga AWS account.

Buod

Napakasarap sa paggamit ng Golang modules at pagsubok kung paano sila maisasama sa bagong pinakawalang AWS Lambda Layers. Ang library ng plugin ay talagang mahusay, ngunit maaari lamang itong magamit sa ilang mga sitwasyon dahil sa mga limitasyon at detalye ng Golang. Sa palagay ko na para sa karamihan ng mga developer na nagtatrabaho sa karaniwang mga proyekto, hindi kinakailangan ang mga plugin o posible. Dalawang dahilan lang ang naiisip ko:

  • Pagpapatupad ng mga kumplikadong algorithm na maaaring magamit ng iba pang mga application, hal. Mga coding ng video o pag-encrypt na algorithm.
  • Ibahagi ang iyong algorithm sa iba nang hindi nai-publish ang code.