Як створити підключається додаток Golang та скористатися AWS Lambda Layers.

Golang - чому це варто вашої уваги?

Golang - мова програмування з відкритим кодом, розроблена та впроваджена Google. Він дуже широко використовується в сучасних програмах, особливо в хмарі. Це найбільш характерні риси:

  • Golang набраний статично - він забезпечує меншу гнучкість, але захищає вас від помилок,
  • Він не є об'єктно-орієнтованим. Однак ви можете створювати структури та інтерфейси, і це дає 3 з 4 принципів OOP: абстрагування даних, інкапсуляція та поліморфізм. Спадщина є єдиною, яка відсутня,
  • Горутини! - найбільша реалізація легких ниток, які я коли-небудь використовував. Це дозволяє створити новий потік надзвичайно простим способом за допомогою оператора go і спілкуватися між різними горами за допомогою каналів,
  • Він компілюється в єдиний бінарний з усіма залежностями - більше не конфлікти пакетів!

Особисто я вважаю Голанг найбільшою мовою, якою я користуюся щодня. Однак ця стаття не стосуватиметься створення вашої першої функції чи друку “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, що дозволяє зберігати та керувати даними, які обмінюються різними функціями в одному або навіть декількох акаунтах AWS! Наприклад, використовуючи Python, ви можете помістити всі залежності в додатковий шар, який згодом можуть бути використані іншими Lambdas. Більше не потрібно ставити різні залежності у кожен пакунок-блискавку! У світі Голанг ситуація інша, оскільки AWS Lambda вимагає, щоб ви завантажили складений двійковий файл. Як ми можемо отримати користь від шарів лямбда AWS? Відповідь проста - побудуйте модульну програму за допомогою плагінів Golang!

Плагіни Golang - спосіб побудови модульного додатку

Плагіни Golang - це функція, випущена в Go1.8, яка дозволяє динамічно завантажувати спільні бібліотеки (.so файли). Це дає можливість експортувати частину свого коду до окремої бібліотеки або використовувати плагін, підготовлений та складений кимось іншим. Однак багатообіцяючим є певне:

  • Ваш плагін повинен бути одним основним модулем,
  • Ви можете завантажувати лише функції та змінні, які експортуються як символи ELF,
  • Завдяки статичному набору тексту, ви повинні передавати кожен завантажений символ правильного типу. У гіршому випадку потрібно визначити правильний інтерфейс у своєму коді,
  • Він працює лише для Linux та MacOS. Особисто я не вважаю це недоліком :)

Створення та тестування вашого першого плагіна

Тепер давайте створимо наш перший плагін. Як приклад, ми створимо простий модуль для шифрування рядків. Повернемося до основ та застосуємо 2 простих алгоритму шифрування - Ceasar та Verman.

  • Шифр Цезаря - це алгоритм, вперше використаний Юлієм Чезесом. Він зміщує кожну букву в тексті на фіксовану кількість позицій. Наприклад, якщо ви хочете зашифрувати слово golang за допомогою ключа 4, ви отримаєте ktpek. Розшифровка працює аналогічно. Вам потрібно просто перенести букви в зворотному напрямку.
  • Шифр Вермана схожий на 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 () (* рядок, помилка)

Для компіляції цього плагіна необхідно виконати таку команду:

перейти на build -buildmode = плагін -o плагін / cipher.so плагін / cipher.go

Наразі немає нічого особливого - було створено кілька простих функцій, і модуль був складений як плагін, додавши аргумент -buildmode = плагін.

Завантажте та випробуйте плагін

Весело починається, коли ми хочемо використовувати складений плагін у нашому додатку. Створимо простий приклад:

Спочатку вам потрібно імпортувати пакет плагінів golang. Він містить лише дві функції - перша - для завантаження спільної бібліотеки, а друга - для пошуку експортованого символу. Для завантаження вашої бібліотеки ви повинні використовувати функцію Open, яка вимагає надання шляху до вашого спільного плагіна та повертає змінну типу Plugin. Якщо завантаження бібліотеки неможливе (наприклад, неправильний шлях або пошкоджений файл), ця функція повертає помилку, яку потрібно обробити.

Наступним кроком є ​​завантаження кожного експортованого символу методом пошуку. Невелика незручність полягає в тому, що вам потрібно завантажити кожну експортовану функцію окремо. Однак ви можете комбінувати кілька функцій разом так само, як це було зроблено для символу VermanCipher. Після завантаження всіх символів, які ви хочете використовувати, ви повинні передати їх правильному типу. Golang - це статично набрана мова, тому немає іншого способу використання цих символів без мовлення. Пам'ятайте, що коли ви експортуєте змінну, яка реалізує декілька методів, вам потрібно привести її до правильного типу інтерфейсу (я повинен був визначити інтерфейс encryptionEngine, щоб обробити це). \ Newline \ newline

Для компіляції та запуску програми використовуйте таку команду:

перейти на створення app.go
./app

У висновку ви повинні бачити зашифрований і розшифрований текст як доказ того, що алгоритм працює правильно.

Використовуйте плагін у лямбда AWS

Для використання нашого плагіна в AWS Lambda нам потрібно внести кілька змін у наше додаток:

  • AWS Lambda монтує шари до каталогу / opt в контейнері лямбда, тому нам доведеться завантажити наш плагін з цього каталогу.
  • Нам потрібно створити функцію обробника, яка буде використовуватися двигуном Lambda для обробки нашого тестового заходу.

Наступний фрагмент містить нашу програму, налаштовану для використання Lambda:

Як бачимо, реалізація дуже схожа на попередню. Ми лише змінили каталог, з якого ми завантажили свій плагін і додали відповідь функції замість друку значень. Якщо ви хочете дізнатися більше про написання лямбдасів голанг, перегляньте документацію AWS.

Розгортання AWS Lambda

Є два способи розгортання функцій та шарів AWS Lambda. Ви можете створювати та завантажувати пакунок на блискавці вручну або використовувати більш вдосконалений фреймворк, що робить його набагато простіше та швидше. Для більшості моїх проектів я використовую основу Serverless, тому я вже підготував простий файл конфігурації serverless.yml за допомогою цього інструменту:

послуга: cipherService
FrameworkVersion: "> = 1.28.0 <2.0.0"
постачальник:
  назва: авс
  час виконання: go1.x
шари:
  шифровий шар:
    шлях: бін / плагін
    сумісні режими:
      - go1.x
функції:
  двигун:
    обробник: бункер / шифрEngine
    пакет:
      виключити:
        - ./**
      включати:
        - ./bin/cipherEngine
    шари:
      - {Посилання: CipherLayerLambdaLayer}

У розділі шарів ми визначили один шар із шляхом до вже створеного плагіна - він буде розгорнутий разом із функцією лямбда. Ви можете визначити до 5 різних шарів, порядок яких дійсно важливий. Вони монтуються в той самий / opt каталог, тому шари з більшою кількістю можуть змінювати файли з попередньо змонтованих шарів. Для кожного шару потрібно вказати щонайменше 2 параметри: шлях до каталогу, що містить джерело шару (шлях до бінарного модуля у вашому випадку) та список сумісних режимів виконання.

Наступний розділ функцій - це місце, де ви визначаєте список функцій, які потрібно розгорнути. Для кожної функції потрібно надати принаймні шлях до складеної програми. Крім того, нам потрібно визначити параметр шарів із посиланням на шар, визначений вище. Це автоматично приєднає шар до нашої функції лямбда під час розгортання. Найсмішніше, що вам потрібно перетворити ім’я шару лямбда в TitleCased і додати суфікс LambdaLayer, якщо ви хочете звернутися до цього ресурсу. Схоже, що команда Serverless реалізувала його таким чином, щоб вирішити конфлікт із посиланням на різні типи ресурсів.

Після того, як наш конфігураційний файл serverless.yml буде готовий, останнє, що потрібно зробити, - це скласти наш додаток, плагін і розгорнути його. Для цього ми можемо використовувати простий Makefile:

.PHONY: побудувати buildPlugin чистий розгортання
будувати:
 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 = плагін -o bin / plugin / cipher.so ../plugin/cipher.go
чисто:
 rm -rf ./bin ./vendor Gopkg.lock
розгортання: чиста збіркаPlugin
 sls розгортати --verbose

Ви можете створити та розгорнути свою функцію, виконавши таку команду:

зробити розгортання

Тест AWS лямбда

Як я вже згадував, AWS Lambda виконує код у відповідь на подію. Однак ми не налаштували жодні тригери подій, тому їх не буде викликано без нашої допомоги. Ми повинні зробити це вручну, використовуючи серверну рамку або інструмент awscli:

sls викликають -f function_name
aws lambda invoke - назва функції функції_імен output_file

У відповіді ви повинні побачити той же вихід, що і раніше, що доводить, що наша лямбда-функція працює правильно і завантажує плагін з додаткового шару. Тепер ви можете створити інші функції, які будуть використовувати той самий рівень або навіть поділитися ним з іншими обліковими записами AWS.

Підсумок

Було дуже весело використовувати модулі Golang і перевірити, як їх інтегрувати з нещодавно випущеними AWS Lambda Layers. Бібліотека плагінів дійсно приголомшлива, проте через обмеження та специфікацію Golang її можна використовувати лише в деяких спеціальних сценаріях. Я думаю, що для більшості розробників, які працюють над типовими проектами, не буде потрібно або навіть можливо використовувати плагіни. На думку мені приходять лише дві причини:

  • Впровадження складних алгоритмів, які можуть бути використані іншими програмами, напр. алгоритми кодування відео чи шифрування.
  • Ділитися своїм алгоритмом з іншими, не публікуючи його код.