Cara membangun aplikasi Golang yang dapat dicolokkan dan manfaat dari AWS Lambda Layers.

Golang - mengapa itu patut Anda perhatikan?

Golang adalah bahasa pemrograman open source yang dirancang dan diimplementasikan oleh Google. Ini sangat banyak digunakan dalam aplikasi modern terutama di cloud. Ini fitur yang paling khas adalah:

  • Golang diketik secara statis - ia kurang fleksibel, tetapi melindungi Anda dari kesalahan,
  • Itu tidak berorientasi objek. Namun, Anda dapat membuat struktur dan antarmuka dan itu memberi Anda 3 dari 4 prinsip OOP: abstraksi data, enkapsulasi, dan polimorfisme. Warisan adalah satu-satunya yang hilang,
  • Goroutin! - implementasi utas benang terbesar yang pernah saya gunakan. Ini memungkinkan Anda untuk membuat utas baru dengan cara yang sangat mudah menggunakan operator go dan berkomunikasi antara goroutine yang berbeda menggunakan saluran,
  • Itu mengkompilasi ke biner tunggal dengan semua dependensi - tidak ada lagi konflik paket!

Secara pribadi, saya menganggap Golang sebagai bahasa terbesar yang saya gunakan setiap hari. Namun, artikel ini tidak akan tentang membuat fungsi pertama Anda atau mencetak "Hello World". Saya akan menunjukkan kepada Anda sedikit hal yang lebih maju. Jika Anda seorang pemula dan ingin mempelajari lebih lanjut tentang Golang, silakan kunjungi halaman utamanya.

AWS Lambda & Golang

AWS Lambda adalah salah satu layanan komputasi tanpa server yang paling populer di cloud publik, dirilis pada November 2014 oleh Amazon Web Services. Ini memungkinkan Anda untuk menjalankan kode Anda sebagai respons terhadap peristiwa seperti pemicu DynamoDB, SNS atau HTTP tanpa menyediakan atau mengelola server! Tahukah Anda apa yang benar-benar hebat? Sejak Januari 2018 mendukung runtime Golang. Bekerja dengan AWS Lambda sangat sederhana - cukup unggah paket zip dengan kode Anda dan semua dependensi (biner tunggal saat menggunakan Golang).

Maju cepat, 4 tahun kemudian pada 2018 re: Inventasikan AWS merilis Lambda Layers yang memungkinkan Anda untuk menyimpan dan mengelola data yang dibagikan di berbagai fungsi dalam satu atau bahkan beberapa akun AWS! Sebagai contoh, Saat menggunakan Python Anda dapat menempatkan semua dependensi di lapisan tambahan yang nantinya dapat digunakan oleh Lambdas lainnya. Tidak perlu lagi meletakkan dependensi yang berbeda di setiap paket zip! Dalam situasi dunia Golang berbeda karena AWS Lambda mengharuskan Anda untuk mengunggah biner yang dikompilasi. Bagaimana kita bisa mendapat manfaat dari AWS Lambda Layers? Jawabannya sederhana - buat aplikasi modular menggunakan Golang Plugins!

Plugin Golang - cara untuk membangun aplikasi modular

Plugin Golang adalah fitur yang dirilis di Go1.8 yang memungkinkan Anda untuk memuat pustaka bersama (file .so) secara dinamis. Ini memberi Anda kesempatan untuk mengekspor beberapa kode Anda ke perpustakaan terpisah atau menggunakan plugin yang disiapkan dan dikompilasi oleh orang lain. Namun menjanjikan, ada beberapa batasan:

  • Plugin Anda harus modul utama tunggal,
  • Anda hanya dapat memuat fungsi dan variabel yang diekspor sebagai simbol ELF,
  • Karena pengetikan statis, Anda harus membuang setiap simbol yang dimuat ke jenis yang benar. Dalam skenario terburuk, Anda perlu mendefinisikan antarmuka yang benar dalam kode Anda,
  • Ini hanya berfungsi untuk Linux dan MacOS. Secara pribadi, saya tidak menganggap ini sebagai kerugian :)

Membangun dan menguji plugin pertama Anda

Sekarang mari kita buat plugin pertama kami. Sebagai contoh, kita akan membuat modul sederhana untuk enkripsi string. Mari kita kembali ke dasar-dasar dan menerapkan 2 algoritma enkripsi sederhana - Ceasar dan Verman.

  • Caesar cipher adalah algoritma yang pertama kali digunakan oleh Julius Ceases. Ini menggeser setiap huruf dalam teks dengan jumlah posisi tetap. Misalnya, jika Anda ingin mengenkripsi kata golang dengan kunci 4, Anda akan mendapatkan ktpek. Dekripsi bekerja dengan cara yang sama. Anda hanya perlu menggeser huruf ke arah yang berlawanan.
  • Cipher Verman mirip dengan Ceaser, berdasarkan pada ide pengalihan yang sama, perbedaannya adalah bahwa Anda menggeser setiap huruf dengan jumlah posisi yang berbeda. Untuk mendekripsi teks Anda harus memiliki kunci yang berisi posisi yang digunakan untuk mengenkripsi teks. Misalnya, jika Anda ingin mengenkripsi kata golang dengan tombol [-1, 4, 7, 20, 4, -2] Anda akan mendapatkan masa depan.

Implementasi lengkap dari contoh ini tersedia di sini.

Implementasi plugin

Cuplikan berikut berisi implementasi dari dua algoritma yang disebutkan di atas. Untuk masing-masing kami menerapkan 2 metode mengenkripsi dan mendekripsi teks kami:

Seperti yang Anda lihat, kami mengekspor 3 simbol berbeda di sini (Golang hanya mengekspor pengidentifikasi yang dimulai dengan huruf besar):

  • EncryptCeasar - func (int, string) string yang mengenkripsi teks menggunakan algoritma Ceasar,
  • DecryptCeaser - func (int, string) string yang mendekripsi teks menggunakan algoritma Caeser,
  • VermanCipher - variabel tipe vermanCipher yang menerapkan 2 metode: Mengenkripsi: string (string) func dan Mendekripsi: func () (* string, error)

Untuk mengkompilasi plugin ini Anda harus menjalankan perintah berikut:

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

Untuk saat ini, tidak ada yang istimewa - beberapa fungsi sederhana dibuat dan modul dikompilasi sebagai plugin dengan menambahkan argumen -buildmode = plugin.

Muat dan uji plugin

Kesenangan dimulai ketika kami ingin menggunakan plugin yang dikompilasi di aplikasi kami. Mari kita buat contoh sederhana:

Pertama, Anda perlu mengimpor paket plugin golang. Ini hanya berisi dua fungsi - yang pertama untuk memuat pustaka bersama dan yang kedua adalah untuk menemukan simbol yang diekspor. Untuk memuat pustaka Anda, Anda harus menggunakan fungsi Buka yang mengharuskan menyediakan jalur ke plugin Anda bersama dan mengembalikan variabel jenis Plugin. Jika memuat pustaka tidak dimungkinkan (mis. Jalur salah atau file rusak) fungsi ini mengembalikan kesalahan yang harus ditangani.

Langkah selanjutnya adalah memuat setiap simbol yang diekspor menggunakan metode Pencarian. Sedikit ketidaknyamanan adalah Anda perlu memuat setiap fungsi yang diekspor secara terpisah. Namun, Anda dapat menggabungkan beberapa fungsi bersamaan dengan cara yang sama seperti yang dilakukan untuk simbol VermanCipher. Setelah Anda memuat semua simbol yang ingin Anda gunakan, Anda harus melemparkannya ke jenis yang benar. Golang adalah bahasa yang diketik secara statis sehingga tidak ada cara lain untuk menggunakan simbol-simbol ini tanpa casting. Ingat, ketika Anda mengekspor variabel yang mengimplementasikan beberapa metode, Anda perlu melemparkannya ke jenis antarmuka yang benar (saya harus mendefinisikan antarmuka enkripsi untuk menangani ini). \ Newline \ newline

Untuk mengkompilasi dan menjalankan aplikasi gunakan perintah berikut:

pergi buat app.go
./aplikasi

Dalam output, Anda akan melihat teks yang dienkripsi dan didekripsi sebagai bukti bahwa algoritma bekerja dengan benar.

Gunakan plugin di AWS lambda

Untuk menggunakan plugin kami di AWS Lambda kita perlu membuat beberapa modifikasi dalam aplikasi kita:

  • AWS Lambda me-mount lapisan ke direktori / opt di wadah lambda, jadi kita harus memuat plugin kita dari direktori ini.
  • Kita perlu membuat fungsi handler yang akan digunakan oleh mesin Lambda untuk menangani acara pengujian kami.

Cuplikan berikut berisi aplikasi kami yang disesuaikan untuk digunakan oleh Lambda:

Seperti yang Anda lihat, implementasinya sangat mirip dengan yang sebelumnya. Kami hanya mengubah direktori tempat kami memuat plugin kami dan menambahkan respons fungsi alih-alih mencetak nilai. Jika Anda ingin mempelajari lebih lanjut tentang cara menulis Lambdas di golang, silakan periksa dokumentasi AWS.

Penempatan AWS Lambda

Ada dua cara untuk menyebarkan fungsi dan lapisan AWS Lambda. Anda dapat membuat dan mengunggah paket zip secara manual atau menggunakan kerangka kerja yang lebih maju, yang membuatnya lebih mudah dan lebih cepat. Untuk sebagian besar proyek saya, saya menggunakan kerangka Serverless, jadi saya sudah menyiapkan file konfigurasi serverless.yml sederhana menggunakan alat ini:

layanan: cipherService
frameworkVersion: "> = 1.28.0 <2.0.0"
pemberi:
  nama: aws
  runtime: go1.x
lapisan:
  cipherLayer:
    path: bin / plugin
    kompatibelRuntimes:
      - go1.x
fungsi:
  mesin:
    handler: bin / cipherEngine
    paket:
      mengecualikan:
        - ./**
      termasuk:
        - ./bin/cipherEngine
    lapisan:
      - {Ref: CipherLayerLambdaLayer}

Di bagian lapisan kita mendefinisikan satu lapisan dengan jalur ke plugin yang sudah dibuat - itu akan digunakan bersama dengan fungsi lambda. Anda dapat menetapkan hingga 5 lapisan berbeda urutan mana yang sangat penting. Mereka di-mount ke direktori / opt yang sama, sehingga layer dengan angka yang lebih tinggi dapat mengganti file dari layer yang sebelumnya di-mount. Untuk setiap lapisan, Anda harus menyediakan setidaknya 2 parameter: jalur ke direktori yang berisi sumber lapisan (jalur ke biner plugin dalam kasus Anda) dan daftar runtime yang kompatibel.

Bagian fungsi berikutnya adalah tempat di mana Anda menentukan daftar fungsi yang akan digunakan. Untuk setiap fungsi, Anda harus menyediakan setidaknya jalur ke aplikasi yang dikompilasi. Selain itu, untuk itu, kita perlu mendefinisikan parameter lapisan dengan referensi ke lapisan yang ditentukan di atas. Ini secara otomatis akan melampirkan layer ke fungsi Lambda kami selama penyebaran. Yang lucu adalah bahwa Anda harus mengubah nama layer lambda Anda menjadi TitleCased dan menambahkan akhiran LambdaLayer jika Anda ingin merujuk ke sumber daya itu. Tampaknya tim Serverless menerapkannya dengan cara ini untuk menyelesaikan konflik dengan merujuk pada berbagai jenis sumber daya.

Setelah file konfigurasi serverless.yml kami siap, hal terakhir yang harus dilakukan adalah mengkompilasi aplikasi, plugin, dan menyebarkannya. Kita dapat menggunakan Makefile sederhana untuk itu:

.PHONY: build buildPlugin clean deploy
membangun:
 dep pastikan -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
bersih:
 rm -rf ./bin ./vendor Gopkg.lock
deploy: clean buildPlugin build
 sls deploy --verbose

Anda dapat membangun dan menggunakan fungsi Anda dengan menjalankan perintah berikut:

melakukan penyebaran

Tes AWS Lambda

Seperti yang saya sebutkan sebelumnya AWS Lambda mengeksekusi kode dalam menanggapi acara tersebut. Namun kami tidak mengonfigurasi pemicu peristiwa apa pun, jadi pemicu itu tidak akan dipanggil tanpa bantuan kami. Kita harus melakukannya secara manual menggunakan kerangka Serverless atau alat awscli:

sls aktifkan -f function_name
aws lambda invoke - function-name function_name output_file

Dalam respons, Anda akan melihat output yang sama seperti sebelumnya, yang membuktikan bahwa fungsi lambda kami berfungsi dengan benar dan memuat plugin dari lapisan tambahan. Sekarang Anda dapat membuat fungsi lain yang akan menggunakan lapisan yang sama atau bahkan membaginya dengan akun AWS lainnya.

Ringkasan

Sangat menyenangkan menggunakan modul Golang dan menguji bagaimana mengintegrasikannya dengan AWS Lambda Layers yang baru dirilis. Pustaka plugin benar-benar hebat, namun karena keterbatasan dan spesifikasinya, hanya dapat digunakan dalam beberapa skenario khusus. Saya pikir bagi sebagian besar pengembang yang mengerjakan proyek standar itu tidak diperlukan atau bahkan mungkin untuk menggunakan plugin. Hanya dua alasan yang muncul di benak saya:

  • Menerapkan algoritma yang rumit yang dapat digunakan oleh aplikasi lain ex. pengkodean video atau algoritma enkripsi.
  • Berbagi algoritme Anda dengan orang lain tanpa menerbitkan kodenya.