Takılabilir Golang uygulaması nasıl inşa edilir ve AWS Lambda Layers'dan faydalanın.

Golang - neden dikkat etmeye değer?

Golang, Google tarafından tasarlanan ve uygulanan açık kaynaklı bir programlama dilidir. Özellikle buluttaki modern uygulamalarda çok yaygın olarak kullanılır. En karakteristik özellikleri:

  • Golang statik olarak yazılmıştır - daha az esneklik sağlar, ancak sizi hata yapmaktan korur,
  • Nesne yönelimli değil. Bununla birlikte, yapıları ve arayüzleri oluşturabilirsiniz ve bu size 4 OOP prensibinin 3'ünü verir: veri soyutlama, kapsülleme ve polimorfizm. Kalıtım tek eksiktir,
  • Goroutines! - Şimdiye kadar kullandığım hafif ipliklerin en büyük uygulaması. Go operatörünü kullanarak süper kolay yolla yeni bir iş parçacığı oluşturmanıza ve kanalları kullanarak farklı goroinler arasında iletişim kurmanıza olanak sağlar,
  • Tüm bağımlılıklara sahip tekli ikili dosyaya derlenir - artık paket çatışması olmaz!

Şahsen, Golang'ı günlük olarak kullandığım en mükemmel dil olarak görüyorum. Ancak, bu makale ilk işlevinizi oluşturmak veya “Merhaba Dünya” ya yazdırmakla ilgili olmayacak. Size biraz daha gelişmiş şeyler göstereceğim. Eğer başlangıç ​​seviyesindeyseniz ve Golang hakkında daha fazla bilgi edinmek istiyorsanız, lütfen ana sayfasını ziyaret edin.

AWS Lambda ve Golang

AWS Lambda, Kasım 2014'te Amazon İnternet Servisleri tarafından yayınlanan, genel buluttaki en popüler sunucusuz bilgi işlem hizmetlerinden biridir. Sunucuları sağlamadan veya yönetmeden DynamoDB, SNS veya HTTP tetikleyicileri gibi olaylara yanıt olarak kodunuzu çalıştırmanıza olanak tanır! Gerçekten harika olan ne biliyor musun? Ocak 2018'den beri Golang çalışma zamanını destekliyor. AWS Lambda ile çalışmak gerçekten basittir - sadece kodunuz ve tüm bağımlılıklarınızla sıkıştırılmış bir paket yükleyin (Golang kullanırken tekli ikili).

Hızlı ileri, 4 yıl sonra 2018'de yeniden: Invent AWS, tek ve hatta birçok AWS hesabında farklı fonksiyonlar arasında paylaşılan verileri saklamanıza ve yönetmenize olanak sağlayan Lambda Katmanlarını sunar! Örneğin, Python'u kullanırken tüm bağımlılıkları daha sonra diğer Lambda'lar tarafından kullanılabilecek ek bir katmana koyabilirsiniz. Artık her sıkıştırılmış pakete farklı bağımlılıklar koymaya gerek yok! Golang dünyasında AWS Lambda derlenmiş ikilik yüklemenizi gerektirdiğinden durum farklıdır. AWS Lambda Katmanlarından nasıl faydalanabiliriz? Cevap basit - Golang Eklentileri kullanarak modüler bir uygulama oluşturmak!

Golang Eklentileri - modüler bir uygulama geliştirmenin bir yolu

Golang Eklentileri, Go1.8'de yayınlanan ve paylaşılan kütüphaneleri (.so dosyaları) dinamik olarak yüklemenizi sağlayan bir özelliktir. Kodunuzun bir bölümünü ayrı kütüphaneye verme veya başkaları tarafından hazırlanan ve derlenen eklentiyi kullanma fırsatı sunar. Ancak, umut verici, ancak birkaç sınırlama var:

  • Eklentiniz tek bir ana modül olmalı,
  • Sadece ELF sembolü olarak dışa aktarılan fonksiyonları ve değişkenleri yükleyebilirsiniz,
  • Statik yazım nedeniyle, yüklü her sembolü doğru türe atmanız gerekir. En kötü senaryoda, kodunuzdaki doğru arayüzü tanımlamanız gerekir.
  • Sadece Linux ve MacOS için çalışıyor. Şahsen ben bunu bir dezavantaj olarak görmüyorum :)

İlk eklentinizi oluşturma ve test etme

Şimdi ilk eklentimizi oluşturalım. Örnek olarak, dize şifrelemesi için basit bir modül oluşturacağız. Temellere geri dönelim ve 2 basit şifreleme algoritmasını uygulayalım - Sezar ve Verman.

  • Sezar şifresi, ilk önce Julius Ceases tarafından kullanılan algoritmadır. Metindeki her harfi sabit sayıda konumla değiştirir. Örneğin, golang kelimesini 4 tuşu ile şifrelemek istiyorsanız, ktpek'i alacaksınız. Şifre çözme aynı şekilde çalışır. Harfleri ters yönde kaydırmanız yeterlidir.
  • Verman şifresi, aynı değişim fikrine dayanarak, Ceaser'a benzer, aradaki fark, her harfi farklı konumlara göre kaydırmanızdır. Metnin şifresini çözmek için metni şifrelemek için kullanılan konumları içeren bir anahtarın olması gerekir. Örneğin, golang kelimesini [-1, 4, 7, 20, 4, -2] tuşuyla şifrelemek istiyorsanız, geleceği elde edersiniz.

Bu örneğin tam uygulaması burada mevcuttur.

Eklenti uygulaması

Aşağıdaki kod parçası yukarıda belirtilen iki algoritmanın uygulanmasını içerir. Her biri için metimizi şifrelemek ve şifresini çözmek için 2 yöntem uyguluyoruz:

Gördüğünüz gibi, buraya 3 farklı sembol verdik (Golang sadece üst harfle başlayan bu tanımlayıcıları dışa aktarır):

  • EncryptCeasar - Ceasar algoritmasını kullanarak metni şifreleyen func (int, string) dizgisini,
  • DecryptCeaser - Caeser algoritmasını kullanarak metnin şifresini çözen func (int, string) dizgisi,
  • VermanCipher - vermanCipher türündeki değişken 2 yöntemi uygular: Encrypt: func (string) string ve Decrypt: func () (* string, error)

Bu eklentiyi derlemek için aşağıdaki komutu çalıştırmanız gerekir:

build inşa -buildmode = eklenti -o eklentisi / cipher.so eklentisi / cipher.go

Şimdilik, özel bir şey yok - birkaç basit fonksiyon oluşturuldu ve -buildmode = plugin argümanı eklenerek bir modül eklenti olarak derlendi.

Yük ve test eklentisi

Bizim uygulamada derlenmiş eklentiyi kullanmak istediğimizde eğlence başlar. Basit bir örnek oluşturalım:

İlk önce, golang eklenti paketini içe aktarmanız gerekir. Yalnızca iki işlev içerir - ilki paylaşılan kitaplığı yüklemek içindir, ikincisi de dışa aktarılan bir sembol bulmak içindir. Kütüphanenizi yüklemek için, paylaşılan eklentinize yol sağlamayı gerektiren ve Plugin türünde bir değişken döndüren Open işlevini kullanmanız gerekir. Kitaplığı yüklemek mümkün değilse (ör. Yanlış yol ya da bozuk dosya) bu işlev, ele alınması gereken hatayı döndürür.

Bir sonraki adım, Dışa Aktarılan her simgeyi Arama yöntemini kullanarak yüklemek. Hafif bir rahatsızlık, dışa aktarılan her işlevi ayrı ayrı yüklemeniz gerektiğidir. Ancak, birden çok işlevi, VermanCipher sembolü için yapıldığı gibi birleştirebilirsiniz. Kullanmak istediğiniz tüm sembolleri yükledikten sonra, onları doğru türe almanız gerekir. Golang statik olarak yazılmış bir dildir, bu yüzden bu sembolleri kullanmadan kullanmanın başka yolu yoktur. Unutmayın, birkaç yöntem uygulayan bir değişkeni dışa aktardığınızda, onu doğru arabirim türüne aktarmanız gerekir (bunu işlemek için şifrelemeEngine arabirimini tanımlamak zorunda kaldım). \ Newline \ newline

Uygulamayı derlemek ve çalıştırmak için aşağıdaki komutu kullanın:

app.go inşa git
./app

Çıktıda, şifreli ve şifresi çözülmüş metni algoritmanın doğru çalıştığını gösteren bir kanıt olarak görmelisiniz.

AWS lambda'da eklenti kullan

Eklentimizi AWS Lambda’da kullanmak için uygulamada birkaç değişiklik yapmamız gerekiyor:

  • AWS Lambda katmanları lambda kabındaki / opt dizinine bağlar, bu yüzden eklentimizi bu dizinden yüklemeliyiz.
  • Test etkinliğimizi yürütmek için Lambda motoru tarafından kullanılacak bir işleyici işlevi oluşturmamız gerekiyor.

Aşağıdaki kod parçası, Lambda tarafından kullanılmak üzere ayarlanmış uygulamamızı içerir:

Gördüğünüz gibi uygulama öncekine çok benziyor. Eklentimizi yüklediğimiz dizini değiştirdik ve yazdırma değerleri yerine işlev yanıtını ekledik. Lambdas'ın golangda yazılması hakkında daha fazla bilgi edinmek istiyorsanız, lütfen AWS belgelerine bakın.

AWS Lambda dağıtımı

AWS Lambda işlevlerini ve katmanlarını dağıtmanın iki yolu vardır. Sıkıştırılmış paketi manuel olarak oluşturabilir ve yükleyebilir ya da çok daha kolay ve hızlı yapan daha gelişmiş çerçeveyi kullanabilirsiniz. Projelerimin çoğu için, Serverless çerçevesini kullanıyorum, bu yüzden bu aracı kullanarak basit serverless.yml yapılandırma dosyasını hazırladım:

hizmet: cipherService
frameworkVersion: "> = 1.28.0 <2.0.0"
sağlayıcı:
  adı: aws
  çalışma zamanı: go1.x
katmanlar:
  cipherLayer:
    yol: bin / eklenti
    compatibleRuntimes:
      - go1.x
fonksiyonlar:
  motor:
    işleyicisi: bin / cipherEngine
    paketlemek:
      dışlamak:
        -.
      Dahil etmek:
        - ./bin/cipherEngine
    katmanlar:
      - {Ref: CipherLayerLambdaLayer}

Katmanlar bölümünde, önceden oluşturulmuş eklentiye giden tek bir katman tanımladık - lambda işlevi ile birlikte dağıtılacak. Sıralamanın gerçekten önemli olduğu 5 farklı katman tanımlayabilirsiniz. Aynı / opt dizinine monte edilirler, böylece daha yüksek sayıdaki katmanlar önceden monte edilmiş katmanlardaki dosyaları geçersiz kılabilir. Her katman için en az 2 parametre sağlamanız gerekir: katman kaynağını içeren dizine giden yol (durumunuzdaki eklenti binaryine giden yol) ve uyumlu çalışma sürelerinin listesi.

Bir sonraki fonksiyonlar bölümü, konuşlandırılacak fonksiyonların listesini tanımladığınız yerdir. Her işlev için, en azından derlenen uygulamanın yolunu belirtmeniz gerekir. Ek olarak, bunun için yukarıda tanımlanmış olan katmana atıfta bulunarak katman parametresini tanımlamamız gerekir. Bu, dağıtım sırasında katmanı otomatik olarak Lambda fonksiyonumuza ekler. İşin komik yanı, lambda katman adınızı TitleCased olacak şekilde dönüştürmeniz ve bu kaynağa başvurmak istiyorsanız LambdaLayer sonekini eklemeniz gerektiğidir. Sunucusuz ekibin, anlaşmazlığı farklı kaynak türlerine göre çözmek için bu şekilde uyguladığı görülüyor.

Serverless.yml yapılandırma dosyamız hazır olduğunda, yapılacak son şey bizim app derlemek, eklenti ve dağıtmak etmektir. Bunun için basit Makefile kullanabiliriz:

.PHONY: buildPlugin temiz konuşlandırması oluşturun
inşa etmek:
 dep -v sağlamak
 env GOOS = linux go build -ldflags = "- s -w" -o bin / cipherEngine cipherEngine / main.go
buildPlugin:
 env GOOS = linux go build -ldflags = "- s -w" -buildmode = eklenti -o bin / eklenti / cipher.so ../plugin/cipher.go
temiz:
 rm -rf ./bin ./ventör Gopkg.lock
dağıtmak: temiz buildPlugin build
 sls konuşlandırma --verbose

Aşağıdaki komutu çalıştırarak işlevinizi oluşturabilir ve dağıtabilirsiniz:

konuşlandırmak

Test AWS Lambda

Daha önce de belirttiğim gibi AWS Lambda etkinliğe cevap olarak kod çalıştırıyor. Bununla birlikte, herhangi bir olay tetikleyicisini yapılandırmadık, bu nedenle yardımımız olmadan çağrılmayacak. Serverless çerçevesini veya awscli aracını kullanarak el ile yapmak zorundayız:

sls çağırmak -f function_name
aws lambda invoke - işlev-adı işlev_adı çıktı_dosyası

Yanıtta, lambda fonksiyonumuzun doğru çalıştığını ve eklentiyi ek katmandan yükleyen olduğunu kanıtlayan öncekiyle aynı çıktıyı görmelisiniz. Artık aynı katmanı kullanacak başka fonksiyonlar oluşturabilir veya hatta diğer AWS hesaplarıyla paylaşabilirsiniz.

özet

Golang modüllerini kullanmak ve onları yeni çıkan AWS Lambda Katmanlarına nasıl entegre edeceğinizi test etmek çok eğlenceliydi. Eklenti kütüphanesi gerçekten harika, ancak sınırlamaları ve Golang spesifikasyonu nedeniyle, sadece bazı özel senaryolarda kullanılabilir. Standart projeler üzerinde çalışan geliştiricilerin çoğu için eklentilere ihtiyaç duyulmayacağını ve hatta mümkün olamayacağını düşünüyorum. Aklıma sadece iki sebep geliyor:

  • Diğer uygulamalar tarafından kullanılabilecek karmaşık algoritmalar uygulamak, örn. video kodlama veya şifreleme algoritmaları.
  • Algoritmanızı kodunu yayınlamadan başkalarıyla paylaşmak