플러그 가능한 Golang 애플리케이션을 구축하고 AWS Lambda Layers의 이점을 활용하는 방법.

골랑 — 왜 주목할 가치가 있습니까?

Golang은 Google이 설계하고 구현 한 오픈 소스 프로그래밍 언어입니다. 특히 클라우드에서 최신 애플리케이션에 매우 널리 사용됩니다. 가장 특징적인 기능은 다음과 같습니다.

  • Golang은 정적으로 형식이 지정되어 유연성이 떨어지지 만 실수하지 않도록 보호합니다.
  • 객체 지향이 아닙니다. 그러나 구조와 인터페이스를 만들 수 있으며 데이터 추상화, 캡슐화 및 다형성이라는 3 가지 4 가지 OOP 원칙을 제공합니다. 상속은 유일하게 누락 된 것입니다.
  • 고 루틴 즈! — 내가 사용해 본 가벼운 스레드의 가장 큰 구현. 이동 연산자를 사용하여 매우 쉬운 방법으로 새 ​​스레드를 생성하고 채널을 사용하여 다른 고 루틴간에 통신 할 수 있습니다.
  • 더 이상 패키지 충돌없이 모든 종속성을 가진 단일 바이너리로 컴파일합니다!

개인적으로 저는 Golang을 매일 사용하는 가장 큰 언어로 생각합니다. 그러나이 기사는 첫 번째 기능을 만들거나 "Hello World"를 인쇄하는 것에 관한 것이 아닙니다. 좀 더 고급스러운 것들을 보여 드리겠습니다. 초보자이고 Golang에 대한 자세한 내용을 보려면 기본 페이지를 방문하십시오.

AWS Lambda & Golang

AWS Lambda는 퍼블릭 클라우드에서 가장 널리 사용되는 서버리스 컴퓨팅 서비스 중 하나이며, 2014 년 11 월 Amazon Web Services에서 릴리스했습니다. 서버를 프로비저닝하거나 관리하지 않고도 DynamoDB, SNS 또는 HTTP 트리거와 같은 이벤트에 응답하여 코드를 실행할 수 있습니다! 정말로 위대한 것이 무엇인지 아십니까? 2018 년 1 월부터 Golang 런타임을 지원합니다. AWS Lambda를 사용한 작업은 매우 간단합니다. 코드와 모든 종속성 (Golang 사용시 단일 바이너리)으로 압축 된 패키지를 업로드하기 만하면됩니다.

4 년 후 2018 년 re : Invent AWS는 단일 또는 여러 AWS 계정에서 서로 다른 기능간에 공유되는 데이터를 저장하고 관리 할 수있는 Lambda 레이어를 출시합니다! 예를 들어, Python을 사용하는 동안 나중에 다른 Lambdas가 사용할 수있는 추가 계층에 모든 종속성을 둘 수 있습니다. 더 이상 각 압축 패키지에 서로 다른 종속성을 둘 필요가 없습니다! Golang 세계에서는 AWS Lambda에서 컴파일 된 바이너리를 업로드해야하므로 상황이 다릅니다. AWS Lambda Layer의 이점은 무엇입니까? 대답은 간단합니다. Golang 플러그인을 사용하여 모듈 식 애플리케이션을 구축하십시오!

Golang 플러그인 — 모듈 식 애플리케이션을 구축하는 방법

Golang 플러그인은 Go1.8에서 릴리스 된 기능으로 공유 라이브러리 (.so 파일)를 동적으로로드 할 수 있습니다. 코드 일부를 별도의 라이브러리로 내보내거나 다른 사람이 준비하고 컴파일 한 플러그인을 사용할 수 있습니다. 그러나 몇 가지 제한 사항이 있습니다.

  • 플러그인은 단일 메인 모듈이어야합니다.
  • ELF 심볼로 내 보낸 함수와 변수 만로드 할 수 있습니다.
  • 정적 타이핑으로 인해로드 된 모든 심볼을 올바른 유형으로 캐스팅해야합니다. 최악의 시나리오에서는 코드에서 올바른 인터페이스를 정의해야합니다.
  • Linux 및 MacOS에서만 작동합니다. 개인적으로, 나는 이것을 단점으로 생각하지 않습니다 :)

첫 번째 플러그인 빌드 및 테스트

이제 첫 번째 플러그인을 만들어 봅시다. 예를 들어, 문자열 암호화를위한 간단한 모듈을 만들 것입니다. 기본으로 돌아가서 Ceasar와 Verman의 두 가지 간단한 암호화 알고리즘을 구현해 봅시다.

  • 시저 암호는 Julius Ceases가 처음 사용하는 알고리즘입니다. 텍스트의 모든 문자를 고정 된 위치 수만큼 이동합니다. 예를 들어, 키 4로 golang이라는 단어를 암호화하려면 ktpek을 얻게됩니다. 암호 해독도 같은 방식으로 작동합니다. 글자를 반대 방향으로 이동하면됩니다.
  • Verman 암호는 동일한 이동 아이디어를 기반으로 Ceaser와 유사하지만 차이점은 모든 문자를 다른 위치 수만큼 이동한다는 것입니다. 텍스트를 해독하려면 텍스트를 암호화하는 데 사용되는 위치가 포함 된 키가 있어야합니다. 예를 들어, 키 [-1, 4, 7, 20, 4, -2]를 사용하여 golang이라는 단어를 암호화하려면 미래가 나옵니다.

이 예제의 전체 구현은 여기에서 제공됩니다.

플러그인 구현

다음 스 니펫에는 위에서 언급 한 두 가지 알고리즘의 구현이 포함되어 있습니다. 각각에 대해 텍스트를 암호화하고 해독하는 두 가지 방법을 구현합니다.

보시다시피, 우리는 여기에 3 개의 다른 기호를 내보냈습니다 (Golang은 대문자로 시작하는 이러한 식별자 만 내 보냅니다).

  • EncryptCeasar-Ceasar 알고리즘을 사용하여 텍스트를 암호화하는 func (int, string) 문자열
  • DecryptCeaser-Caeser 알고리즘을 사용하여 텍스트를 해독하는 func (int, string) 문자열
  • VermanCipher-2 가지 메소드를 구현하는 vermanCipher 유형의 변수 : 암호화 : func (문자열) 문자열 및 암호 해독 : func () (* 문자열, 오류)

이 플러그인을 컴파일하려면 다음 명령을 실행해야합니다.

빌드로 이동 -buildmode = plugin -o plugin / cipher.so plugin / cipher.go

현재로서는 특별한 것이 없습니다. -buildmode = plugin 인수를 추가하여 간단한 함수가 거의 생성되지 않고 모듈이 플러그인으로 컴파일되었습니다.

플러그인로드 및 테스트

앱에서 컴파일 된 플러그인을 사용하고 싶을 때 재미가 시작됩니다. 간단한 예를 만들어 봅시다 :

먼저 golang 플러그인 패키지를 가져와야합니다. 여기에는 두 가지 기능 만 포함됩니다. 첫 번째 기능은 공유 라이브러리를로드하기위한 것이고 두 번째 기능은 내 보낸 심볼을 찾기위한 것입니다. 라이브러리를로드하려면 공유 플러그인에 대한 경로를 제공해야하고 Plugin 유형의 변수를 반환하는 Open 함수를 사용해야합니다. 라이브러리를로드 할 수없는 경우 (예 : 잘못된 경로 또는 손상된 파일)이 함수는 처리해야하는 오류를 반환합니다.

다음 단계는 조회 방법을 사용하여 내 보낸 모든 심볼을로드하는 것입니다. 약간의 불편 함은 내 보낸 모든 함수를 개별적으로로드해야한다는 것입니다. 그러나 VermanCipher 기호와 동일한 방식으로 여러 기능을 결합 할 수 있습니다. 사용하려는 모든 심볼을로드 한 후에는 올바른 유형으로 캐스트해야합니다. Golang은 정적으로 입력 된 언어이므로 이러한 기호를 캐스팅하지 않고 사용할 수있는 다른 방법은 없습니다. 몇 가지 메소드를 구현하는 변수를 내보낼 때 올바른 인터페이스 유형으로 캐스트해야합니다 (이를 처리하기 위해 encryptionEngine 인터페이스를 정의해야 함). \ newline \ newline

앱을 컴파일하고 실행하려면 다음 명령을 사용하십시오.

app.go를 빌드하십시오.
./앱

출력에서 알고리즘이 올바르게 작동한다는 증거로 암호화 및 해독 된 텍스트를 볼 수 있습니다.

AWS Lambda에서 플러그인 사용

AWS Lambda에서 플러그인을 사용하려면 애플리케이션에서 몇 가지 사항을 수정해야합니다.

  • AWS Lambda는 람다 컨테이너의 / opt 디렉토리에 레이어를 마운트하므로이 디렉토리에서 플러그인을로드해야합니다.
  • 테스트 이벤트를 처리하기 위해 Lambda 엔진에서 사용할 핸들러 함수를 작성해야합니다.

다음 스 니펫에는 Lambda에서 사용하도록 조정 된 애플리케이션이 포함되어 있습니다.

보시다시피 구현은 이전 구현과 매우 유사합니다. 플러그인을로드 한 디렉토리 만 변경하고 값을 인쇄하는 대신 함수 응답을 추가했습니다. golang에서 Lambdas를 작성하는 방법에 대한 자세한 내용은 AWS 설명서를 확인하십시오.

AWS Lambda 배포

AWS Lambda 함수 및 레이어를 배포하는 방법에는 두 가지가 있습니다. 압축 된 패키지를 수동으로 생성 및 업로드하거나 고급 프레임 워크를 사용하면 훨씬 쉽고 빠릅니다. 대부분의 프로젝트에서 Serverless 프레임 워크를 사용하므로이 도구를 사용하여 간단한 serverless.yml 구성 파일을 이미 준비했습니다.

서비스 : cipherService
frameworkVersion : "> = 1.28.0 <2.0.0"
공급자:
  이름 : aws
  런타임 : go1.x
층 :
  cipherLayer :
    경로 : bin / plugin
    compatibleRuntimes :
      -go1.x
기능 :
  엔진:
    핸들러 : bin / cipherEngine
    꾸러미:
      들어오지 못하게 하다:
        -./**
      포함:
        -./bin/cipherEngine
    층 :
      -{참조 : CipherLayerLambdaLayer}

레이어 섹션에서 우리는 이미 생성 된 플러그인에 대한 경로를 가진 단일 레이어를 정의했습니다. 람다 함수와 함께 배포됩니다. 순서가 정말로 중요한 최대 5 개의 다른 레이어를 정의 할 수 있습니다. 동일한 / opt 디렉토리에 마운트되므로 번호가 더 많은 계층은 이전에 마운트 된 계층의 파일을 대체 할 수 있습니다. 모든 계층에 대해 최소 2 개의 매개 변수를 제공해야합니다. 계층 소스를 포함하는 디렉토리 경로 (필요한 경우 플러그인 2 진 경로) 및 호환 가능한 런타임 목록.

다음 기능 섹션은 배포 할 기능 목록을 정의하는 위치입니다. 모든 기능에 대해 최소한 컴파일 된 응용 프로그램의 경로를 제공해야합니다. 또한, 위에서 정의한 레이어를 참조하여 레이어 매개 변수를 정의해야합니다. 배포 중에 레이어를 Lambda 함수에 자동으로 연결합니다. 재미있는 것은 람다 레이어 이름을 TitleCased로 변환하고 해당 리소스를 참조하려면 LambdaLayer 접미사를 추가해야한다는 것입니다. 서버리스 팀은 다른 유형의 자원에 대한 갈등을 해결하기 위해 이러한 방식으로 구현 한 것 같습니다.

serverless.yml 구성 파일이 준비되면 마지막으로 할 일은 앱을 컴파일하고 플러그인하여 배포하는 것입니다. 이를 위해 간단한 Makefile을 사용할 수 있습니다.

.PHONY : buildPlugin 클린 배포 빌드
짓다:
 dep ensure -v
 env GOOS = linux go 빌드 -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 ./ 공급 업체 Gopkg.lock
배포 : 깨끗한 buildPlugin 빌드
 sls deploy-자세한

다음 명령을 실행하여 함수를 빌드하고 배치 할 수 있습니다.

배포하다

AWS Lambda 테스트

앞서 언급했듯이 AWS Lambda는 이벤트에 대한 응답으로 코드를 실행합니다. 그러나 이벤트 트리거를 구성하지 않았으므로 도움 없이는 호출되지 않습니다. 서버리스 프레임 워크 또는 awscli 도구를 사용하여 수동으로 수행해야합니다.

sls는 -f function_name을 호출합니다.
aws lambda invoke — 함수 이름 function_name output_file

응답에서 이전과 동일한 출력을 볼 수 있습니다. 이는 람다 함수가 올바르게 작동하고 추가 계층에서 플러그인을로드 함을 나타냅니다. 이제 동일한 계층을 사용하거나 다른 AWS 계정과 공유 할 다른 기능을 생성 할 수 있습니다.

개요

Golang 모듈을 사용하고 새로 출시 된 AWS Lambda Layer와 통합하는 방법을 테스트하는 것은 많은 재미였습니다. 플러그인 라이브러리는 정말 훌륭하지만 제한 사항과 Golang 사양으로 인해 일부 특수 시나리오에서만 사용할 수 있습니다. 표준 프로젝트를 수행하는 대부분의 개발자에게는 플러그인을 사용할 필요가 없으며 심지어는 사용할 수도 없다고 생각합니다. 내 생각에는 두 가지 이유 만 있습니다.

  • 다른 응용 프로그램에서 사용할 수있는 복잡한 알고리즘 구현 ex. 비디오 코딩 또는 암호화 알고리즘.
  • 코드를 게시하지 않고 알고리즘을 다른 사람과 공유