Как да изградите прикачно приложение Golang и да се възползвате от AWS Lambda Layers.

Golang - защо си струва вниманието ви?

Golang е език за програмиране с отворен код, проектиран и внедрен от Google. Той е много широко използван в съвременните приложения, особено в облака. Най-характерните характеристики са:

  • Golang е статично набран - осигурява по-малка гъвкавост, но ви предпазва от грешки,
  • Не е обектно ориентирана. Можете обаче да създадете структури и интерфейси и това ви дава 3 от 4 принципа на OOP: абстракция на данни, капсулиране и полиморфизъм. Наследството е единственото липсващо,
  • Goroutines! - най-голямото внедряване на леките нишки, които някога съм използвал. Позволява ви да създадете нова нишка по супер лесния начин, като използвате оператор go и комуникирате между различни програми чрез канали,
  • Той се компилира в единичния двоичен файл с всички зависимости - няма повече конфликти на пакетите!

Лично аз считам Golang за най-великия език, който използвам ежедневно. Тази статия обаче няма да е за създаването на първата ви функция или отпечатването на "Hello World". Ще ви покажа малко по-модерни неща. Ако сте начинаещ и искате да научите повече за Golang, моля, посетете главната му страница.

AWS Lambda & Golang

AWS Lambda е една от най-популярните сървърни изчислителни услуги в публичния облак, издадена през ноември 2014 г. от Amazon Web Services. Тя ви позволява да стартирате вашия код в отговор на събитията като задействания на DynamoDB, SNS или HTTP без осигуряване или управление на сървъри! Знаете ли какво е наистина страхотно? От януари 2018 г. той поддържа Golang време на изпълнение. Работата с AWS Lambda е наистина проста - просто качете цип пакет с вашия код и всички зависимости (единичен двоичен код, когато използвате Golang).

Бързо напред, 4 години по-късно през 2018 г. re: Invent AWS пуска Lambda Layers, което ви позволява да съхранявате и управлявате данни, които се споделят в различни функции в единичните или дори множество акаунти в AWS! Например, докато използвате Python, можете да поставите всички зависимости в допълнителен слой, който по-късно да бъде използван от други Lambdas. Вече няма нужда да поставяте различни зависимости във всеки пакет с цип! В света Golang ситуацията е различна, тъй като AWS Lambda изисква да качите компилиран двоичен файл. Как можем да се възползваме от ламбдайните слоеве AWS? Отговорът е прост - изградете модулно приложение с помощта на Golang Plugins!

Golang Plugins - начин за изграждане на модулно приложение

Golang Plugins е функцията, пусната в Go1.8, която ви позволява динамично да зареждате споделени библиотеки (.so файлове). Дава ви възможност да експортирате част от кода си в отделната библиотека или да използвате приставката, подготвена и компилирана от някой друг. Обещаващо е обаче, че има няколко ограничения:

  • Вашият Plugin трябва да бъде един основен модул,
  • Можете да зареждате само функции и променливи, които се експортират като ELF символи,
  • Поради статичното въвеждане трябва да прехвърлите всеки зареден символ до правилния тип. В най-лошия сценарий трябва да определите правилния интерфейс във вашия код,
  • Работи само за Linux и MacOS. Лично аз не считам това за недостатък :)

Изграждане и тестване на първия ви плъгин

Сега нека създадем първия си плъгин Като пример ще създадем прост модул за криптиране на низове. Да се ​​върнем към основите и да приложим 2 прости алгоритма за криптиране - Ceasar и Verman.

  • Цезарният шифър е алгоритъмът, използван първо от Юлий Цез. Той измества всяка буква в текста от фиксирания брой позиции. Например, ако искате да шифровате думата golang с ключа 4, ще получите ktpek. Дешифрирането работи по същия начин. Просто трябва да преместите буквите в обратна посока.
  • Verman шифърът е подобен на Ceaser, базиран на една и съща идея за изместване, разликата е, че измествате всяка буква от различния брой позиции. За да дешифрирате текста, трябва да имате ключ, съдържащ позициите, използвани за криптиране на текста. Например, ако искате да шифровате думата golang с ключа [-1, 4, 7, 20, 4, -2], ще получите бъдеще.

Пълното изпълнение на този пример е достъпно тук.

Изпълнение на приставки

Следващият фрагмент съдържа изпълнението на двата алгоритъма, споменати по-горе. За всеки от тях реализираме 2 метода за криптиране и дешифриране на нашия текст:

Както можете да видите, ние изнесохме тук 3 различни символа (Golang изнася само тези идентификатори, които започват с горната буква):

  • EncryptCeasar - func (int, string) низ, който криптира текст с помощта на алгоритъм Ceasar,
  • DecryptCeaser - func (int, string) низ, който дешифрира текст с помощта на алгоритъм Caeser,
  • VermanCipher - променлива от типа vermanCipher, осъществяваща 2 метода: Шифроване: func (string) низ и Дешифриране: func () (* низ, грешка)

За да компилирате тази приставка, трябва да изпълните следната команда:

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

Засега няма нищо специално - бяха създадени няколко прости функции и модул беше съставен като плъгин чрез добавяне на аргумента -buildmode = плъгин.

Заредете и тествайте плъгин

Забавлението започва, когато искаме да използваме компилиран плъгин в нашето приложение. Нека създадем прост пример:

Първо, трябва да импортирате пакета с плъгини golang. Той съдържа само две функции - първата е за зареждане на споделена библиотека, а втората е за намиране на експортиран символ. За да заредите библиотеката си, трябва да използвате Open функция, която изисква предоставяне на пътя към вашия споделен плъгин и връща променлива от тип Plugin. Ако зареждането на библиотеката не е възможно (напр. Неправилен път или повреден файл), тази функция връща грешката, която трябва да бъде обработена.

Следващата стъпка е да заредите всеки изнесен символ чрез метода Lookup. Леко неудобство е, че трябва да заредите всяка изнесена функция поотделно. Можете обаче да комбинирате няколко функции заедно по същия начин, както беше направено за символа VermanCipher. След като сте заредили всички символи, които искате да използвате, трябва да ги хвърлите към правилния тип. Golang е статично въведен език, така че няма друг начин за използване на тези символи без леене. Не забравяйте, че когато експортирате променлива, която реализира няколко метода, трябва да я хвърлите към правилния тип интерфейс (трябваше да дефинирам интерфейса на криптиране, за да се справя с това). \ Newline \ newline

За да компилирате и стартирате приложението, използвайте следната команда:

отидете изграждане на app.go
./app

В изхода трябва да видите криптирания и декриптиран текст като доказателство, че алгоритъмът работи правилно.

Използвайте плъгин в AWS lambda

За да използваме нашия плъгин в AWS Lambda, трябва да направим няколко модификации в нашето приложение:

  • AWS Lambda монтира слоеве в директорията / opt в контейнера lambda, така че трябва да заредим нашия плъгин от тази директория.
  • Трябва да създадем функция за обработка, която ще се използва от двигателя на Lambda за справяне с нашето тестово събитие.

Следният фрагмент съдържа нашето приложение, приспособено да се използва от Lambda:

Както можете да видите реализацията е много подобна на предишната. Променихме само директорията, от която заредихме нашия плъгин и добавихме отговора на функцията, вместо да отпечатваме стойности. Ако искате да научите повече за писането на Lambdas в golang, моля, проверете документацията на AWS.

Разгръщане на AWS Lambda

Има два начина за разгръщане на AWS Lambda функции и слоеве. Можете да създавате и качвате пакети с цип ръчно или да използвате по-модерната рамка, което го прави много по-лесно и по-бързо. За повечето от моите проекти използвам рамката без сървър, така че вече съм подготвил елементарния конфигурационен файл serverless.yml, използвайки този инструмент:

услуга: cipherService
FrameworkVersion: "> = 1.28.0 <2.0.0"
доставчик на:
  име: aws
  време на изпълнение: go1.x
слоя:
  cipherLayer:
    път: бин / плъгин
    compatibleRuntimes:
      - go1.x
функции:
  на двигателя:
    манипулатор: кошче / шифърEngine
    пакет:
      изключват:
        - ./**
      включват:
        - ./bin/cipherEngine
    слоя:
      - {Ref: CipherLayerLambdaLayer}

В секцията слоеве дефинирахме един слой с пътя към вече създадения плъгин - той ще бъде разгърнат заедно с функцията lambda. Можете да определите до 5 различни слоя кой ред е наистина важен. Те са монтирани в една и съща / opt директория, така че слоевете с по-голям брой могат да отменят файлове от преди монтираните слоеве. За всеки слой трябва да предоставите поне 2 параметъра: път до директорията, съдържаща източник на слой (път към двоичния код на плъгина във вашия случай) и списъка на съвместимите времена на изпълнение.

Следващият раздел с функции е място, където определяте списъка на функциите, които ще бъдат внедрени. За всяка функция трябва да посочите поне пътя към компилираното приложение. В допълнение към това трябва да дефинираме параметъра на слоевете с препратката към слоя, дефиниран по-горе. Това автоматично ще прикачи слоя към нашата функция Lambda по време на разполагането. Смешното е, че трябва да преобразувате името си на ламбда слой да бъде TitleCased и да добавите наставката LambdaLayer, ако искате да се обърнете към този ресурс. Изглежда, че екипът на Serverless го е приложил по този начин, за да разреши конфликта по отношение на различните видове ресурси.

След като нашият конфигурационен файл serverless.yml е готов, последното нещо, което трябва да направите, е да съставим нашето приложение, да го включим и да го разгърнем. Можем да използваме прост Makefile за това:

.PHONY: изграждане на buildPlugin clean внедряване
строеж:
 dep осигуряват -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
чисто:
 rm -rf ./bin ./vendor Gopkg.lock
внедряване: чиста buildPlugin build
 sls implementi - verbose

Можете да изградите и разгърнете функцията си, като изпълните следната команда:

направи разгръщане

Тествайте AWS Lambda

Както споменах по-рано AWS Lambda изпълнява код в отговора на събитието. Въпреки това не конфигурирахме задействания на събитията, така че няма да бъде извикан без наша помощ. Трябва да го направим ръчно, използвайки рамката Serverless или инструмента awscli:

sls извиква -f function_name
aws lambda invoke - име на функция function_name output_file

В отговора трябва да видите същия изход като преди, което доказва, че нашата ламбда функция работи правилно и зарежда приставката от допълнителния слой. Сега можете да създадете други функции, които ще използват същия слой или дори да го споделят с други AWS акаунти.

резюме

Беше много забавно да използвам Golang модули и да тестваме как да ги интегрираме с новоиздадените AWS Lambda Layers. Библиотеката с плъгини е наистина страхотна, но поради ограниченията и спецификацията на Golang може да се използва само в някои специални сценарии. Мисля, че за повечето разработчици, които работят по стандартните проекти, няма да е необходимо или дори възможно да се използват плъгини. Само две причини ми идват:

  • Внедряване на сложни алгоритми, които могат да се използват от другите приложения напр. алгоритми за кодиране или кодиране на видео.
  • Споделяне на вашия алгоритъм с други, без да публикува кода му.