Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby에서 AWS Lambda 함수 빌드, 테스트 및 배포

소프트웨어 개발은 ​​어려울 수 있지만 유지 관리는 훨씬 더 어렵습니다. 유지 관리에는 소프트웨어 패치와 서버 유지 관리가 포함됩니다. 이번 포스트에서는 서버 관리 및 유지보수에 대해 집중적으로 다룰 예정입니다.

전통적으로 서버는 물리적 하드웨어를 구매하고 유지 관리하는 온프레미스였습니다. 클라우드 컴퓨팅을 사용하면 이러한 서버를 더 이상 물리적으로 소유할 필요가 없습니다. 2006년, Amazon이 AWS를 시작하고 EC2 서비스를 도입하면서 모던 클라우드 컴퓨팅 시대가 시작되었습니다. 이러한 유형의 서비스를 사용하면 더 이상 물리적 서버를 유지 관리하거나 물리적 하드웨어를 업그레이드할 필요가 없습니다. 이것은 많은 문제를 해결했지만 서버 유지 관리 및 리소스 관리는 여전히 우리에게 달려 있습니다. 이러한 발전을 한 단계 더 발전시켜 이제 우리는 서버리스 기술을 갖게 되었습니다.

Ruby에서 AWS Lambda 함수 빌드, 테스트 및 배포

서버리스 기술이란 무엇입니까?

서버리스 기술은 서버 관리 및 프로비저닝 작업을 클라우드 제공업체에 오프로드하는 데 도움이 됩니다. 이 게시물에서는 AWS에 대해 논의할 것입니다.

서버리스라는 용어는 서버가 전혀 없다는 것을 의미하지 않습니다. 서버가 있지만 클라우드 공급자가 완전히 관리합니다. 어떤 의미에서 서버리스 기술 사용자에게는 가시적인 서버가 없습니다. 서버는 우리에게 직접적으로 보이지 않으며, 서버 관리 작업은 클라우드 공급자에 의해 자동화됩니다. 다음은 서버리스를 만드는 몇 가지 특징입니다.

  • 운영 관리 불필요 - 서버 패치 또는 고가용성을 위해 관리할 필요 없음
  • 필요에 따라 확장 - 소수의 사용자에게만 서비스를 제공하는 것에서 수백만 명의 사용자에게 서비스를 제공하는 것으로
  • 종량제 - 사용량에 따라 비용이 관리됩니다.

서버리스 기술은 다음과 같이 분류할 수 있습니다.

  • 계산 (예:Lambda 및 Fargate)
  • 저장소 (예:S3)
  • 데이터 저장소 (예:DynamoDB 및 Aurora)
  • 통합 (예:API 게이트웨이, SNS, SQS)
  • 분석 (예:Kinesis 및 Athena)

서버리스 기술을 사용하는 이유

비용

사용한 만큼 지불하는 것은 서버리스 기술 사용의 주요 이점 중 하나입니다. 트래픽 양에 예측할 수 없는 변화가 있는 경우 사용 패턴에 따라 서버를 확장하거나 축소해야 하지만 자체 관리형 자동 확장으로 확장하는 것은 어렵고 비효율적일 수 있습니다. AWS Lambda와 같은 서버리스 컴퓨팅은 유휴 시간 동안 비용을 지불할 필요가 없기 때문에 비용 절감에 쉽게 도움이 됩니다.

개발자 생산성

서버리스 컴퓨팅은 클라우드 공급자가 제공하는 완전 관리형 서비스를 의미하므로 개발자가 서버를 프로비저닝하거나 서버 애플리케이션을 개발할 필요가 없습니다. 개발자는 서버를 관리할 필요 없이 바로 코딩을 시작할 수 있습니다. 또한 이 접근 방식을 사용하면 서버에 패치를 적용하거나 자동 크기 조정을 관리할 필요가 없습니다. 이 모든 시간을 절약하면 개발자의 생산성을 높이는 데 도움이 됩니다.

탄력성

서버리스 컴퓨팅은 매우 탄력적이며 사용량에 따라 확장 또는 축소할 수 있습니다. 급증하는 사용자를 쉽게 처리할 수 있습니다. 이는 주요 이점이 될 수 있으며 개발자의 시간을 많이 절약하는 데 도움이 됩니다.

고가용성

컴퓨팅이 서버리스이고 클라우드 공급자가 관리하고 서버 가동 시간이 높으면 장애 조치가 자동으로 처리됩니다. 이러한 종류의 문제를 관리하려면 전문 기술이 필요합니다. 서버리스 접근 방식을 사용하면 운영자와 개발자의 작업을 한 사람이 수행할 수 있습니다.

Ruby에서 서버리스 기능을 구현하는 방법

AWS에 따르면 Ruby는 AWS에서 가장 널리 사용되는 언어 중 하나입니다. Lambda는 2018년 11월에 Ruby 지원을 시작했습니다. AWS에서 제공하는 서버리스 기술만을 사용하여 Ruby에서 웹 API를 구축할 예정입니다.

AWS에서 서버리스 인프라를 생성하려면 AWS 콘솔에 로그인하여 생성을 시작하면 됩니다. 그러나 우리는 쉽게 테스트할 수 있고 재해 복구를 용이하게 하는 것을 개발하고자 합니다. 서버리스 기능을 코드로 작성합니다. 이를 위해 AWS는 서버리스 애플리케이션 모델(SAM)을 제공합니다. SAM은 AWS에서 서버리스 애플리케이션을 구축하는 데 사용되는 프레임워크입니다. Lambda, 데이터베이스 및 API를 설계하기 위한 YAML 기반 구문을 제공합니다. AWS SAM 애플리케이션은 이 링크를 통해 다운로드할 수 있는 AWS SAM-CLI를 사용하여 구축할 수 있습니다.

AWS SAM CLI는 AWS Cloudformation을 기반으로 구축되었습니다. CoudFormation으로 IaC를 작성하는 데 익숙하다면 매우 간단할 것입니다. 또는 서버리스 프레임워크를 사용할 수도 있습니다. 이번 포스팅에서는 AWS SAM을 사용하겠습니다.

Ruby에서 AWS Lambda 함수 빌드, 테스트 및 배포

SAM CLI를 사용하기 전에 다음 사항이 있는지 확인하십시오.

  • AWS 프로필 설정
  • 도커 설치
  • SAM CLI 설치

우리는 서버리스 애플리케이션을 개발할 것입니다. 먼저 애플리케이션에서 DynamoDB 및 Lambda와 같은 몇 가지 서버리스 인프라를 생성합니다. 데이터베이스부터 시작하겠습니다.

DynamoDB

DynamoDB는 서버리스 AWS 관리형 데이터베이스 서비스입니다. 서버리스이기 때문에 매우 빠르고 쉽게 설정할 수 있습니다. DynamoDB를 생성하기 위해 SAM 템플릿을 다음과 같이 정의합니다.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  UsersTable:
    Type: AWS::Serverless::SimpleTable
    Properties:
      PrimaryKey:
        Name: id
        Type: String
      TableName: users

SAM CLI와 위의 템플릿을 사용하여 기본 DynamoDB 테이블을 생성할 수 있습니다. 먼저 서버리스 앱용 패키지를 빌드해야 합니다. 이를 위해 다음 명령을 실행합니다. 그러면 패키지가 빌드되고 s3로 푸시됩니다. serverless-users-bucket 이름으로 s3 버킷을 생성했는지 확인합니다. 명령을 실행하기 전에:

$ sam package --template-file sam.yaml \
              --output-template-file out.yaml \
              --s3-bucket serverless-users-bucket

s3는 이제 템플릿의 소스가 되고 서버리스 앱의 코드가 됩니다. 이에 대해 Lambda 함수를 생성하는 동안 이에 대해 설명하겠습니다.

이제 이 템플릿을 배포하여 DynamoDB를 생성할 수 있습니다.

$ sam deploy --template-file out.yaml \
             --stack-name serverless-users-app \
             --capabilities CAPABILITY_IAM

이로써 DynamoDB 설정이 완료되었습니다. 다음으로 이 테이블이 사용될 Lambda를 생성합니다.

람다

Lambda는 AWS에서 제공하는 서버리스 컴퓨팅 서비스입니다. 코드가 실행되는 실제 서버 관리 없이 필요에 따라 코드를 실행하는 데 사용할 수 있습니다. Lambda는 비동기 프로세스, REST API 또는 예약된 작업을 실행하는 데 사용할 수 있습니다. 핸들러 함수를 작성하기만 하면 됩니다. 함수를 AWS Lambda에 푸시합니다. Lambda는 이벤트를 기반으로 작업을 실행합니다. . 이벤트는 API 게이트웨이, SQS 또는 S3와 같은 다양한 소스에 의해 트리거될 수 있습니다. 다른 코드베이스에 의해 트리거될 수도 있습니다. 트리거되면 이 Lambda 함수는 이벤트 및 컨텍스트 파라미터를 수신합니다. 이러한 매개변수의 값은 트리거 소스에 따라 다릅니다. 이러한 이벤트를 핸들러에 전달하여 Lambda 함수를 수동으로 또는 프로그래밍 방식으로 트리거할 수도 있습니다. 핸들러는 두 개의 인수를 사용합니다.

이벤트 - 이벤트는 일반적으로 트리거 소스에서 전달된 키-값 해시입니다. 이러한 값은 SQS, Kinesis 또는 API 게이트웨이와 같은 다양한 소스에서 트리거될 때 자동으로 전달됩니다. 수동으로 트리거할 때 여기에서 이벤트를 전달할 수 있습니다. 이벤트에는 Lambda 함수 핸들러에 대한 입력 데이터가 포함됩니다. 예를 들어 API 게이트웨이에서 요청 본문은 이 이벤트 안에 포함됩니다.

컨텍스트 - 컨텍스트는 핸들러 함수의 두 번째 인수입니다. 여기에는 트리거 소스, Lambda 함수 이름, 버전, 요청 ID 등을 비롯한 특정 세부 정보가 포함됩니다.

핸들러의 출력은 Lambda 함수를 트리거한 서비스로 다시 전달됩니다. Lambda 함수의 출력은 핸들러 함수의 반환 값입니다.

AWS Lambda는 Ruby를 포함하여 코딩할 수 있는 7가지 언어를 지원합니다. 여기서는 AWS Ruby-sdk를 사용하여 DynamoDB에 연결합니다.

코드를 작성하기 전에 SAM 템플릿을 사용하여 Lambda용 인프라를 생성해 보겠습니다.

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: "Serverless users app"

Resources:
  CreateUserFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: users.create
      Runtime: ruby2.7
      Policies:
        - DynamoDBWritePolicy:
            TableName: !Ref UsersTable
      Environment:
        Variables:
          USERS_TABLE: !Ref UsersTable

핸들러에서 실행할 함수에 대한 참조를 Handler: <filename>.<method_name>으로 씁니다. .

Lambda가 사용하는 리소스를 기반으로 Lambda에 연결할 수 있는 정책은 서버리스 정책 템플릿을 참조하십시오. Lambda 함수가 DynamoDB에 쓰기 때문에 DynamoDBWritePolicy를 사용했습니다. 정책 섹션에서.

또한 지정된 데이터베이스에 요청을 보낼 수 있도록 환경 변수 USERS_TABLE을 Lambda 함수에 제공하고 있습니다.

이것이 Lambda 인프라에 필요한 것입니다. 이제 Lambda 함수가 실행할 DynamoDB에 사용자를 생성하는 코드를 작성해 보겠습니다.

AWS 레코드를 Gemfile에 추가:

# Gemfile
source 'https://rubygems.org' do
  gem 'aws-record', '~> 2'
end

DynamoDB에 입력을 작성하는 코드 추가:

# users.rb
require 'aws-record'

class UsersTable
  include Aws::Record
  set_table_name ENV['USERS_TABLE']
  string_attr :id, hash_key: true
  string_attr :body
end

def create(event:,context:)
  body = event["body"]
  id = SecureRandom.uuid
  user = UsersTable.new(id: id, body: body)
  user.save!
  user.to_h
end

그것은 매우 빠르고 쉽습니다. AWS는 aws-record를 제공합니다. Rails의 activerecord와 매우 유사한 DynamoDB 액세스용 gem .

그런 다음 다음 명령을 실행하여 종속성을 설치합니다.

참고:Lambda에 정의된 것과 동일한 버전의 Ruby가 있는지 확인하십시오. 여기의 예에서는 컴퓨터에 Ruby2.7이 설치되어 있어야 합니다.

# install dependencies

$ bundle install
$ bundle install --deployment

변경 사항 패키지:

$ sam package --template-file sam.yaml \
              --output-template-file out.yaml \
              --s3-bucket serverless-users-bucket

배포:

sam deploy --template-file out.yaml \
             --stack-name serverless-users-app \
             --capabilities CAPABILITY_IAM

이 코드를 사용하여 이제 데이터베이스에 입력을 쓸 수 있는 Lambda가 실행됩니다. HTTP 호출을 통해 액세스할 수 있도록 Lambda 앞에 API 게이트웨이를 추가할 수 있습니다. API 게이트웨이는 속도 제한 및 인증과 같은 많은 API 관리 기능을 제공합니다. 그러나 사용량에 따라 비용이 많이 들 수 있습니다. API 관리 없이 HTTP API만 사용하는 더 저렴한 옵션이 있습니다. 사용 사례에 따라 가장 적합한 것을 선택할 수 있습니다.

AWS Lambda에는 몇 가지 제한이 있습니다. 일부는 수정할 수 있지만 나머지는 수정되었습니다.

  • 기억 - 기본적으로 Lambda에는 실행 시간 동안 128MB의 메모리가 있습니다. 64MB 단위로 최대 3,008MB까지 늘릴 수 있습니다.
  • 시간 초과 - Lambda 함수에는 코드 실행 시간 제한이 있습니다. 기본 제한은 3초입니다. 최대 900초까지 늘릴 수 있습니다.
  • 저장소 - Lambda는 /tmp를 제공합니다. 저장을 위한 디렉토리. 이 저장용량 한도는 512MB입니다.
  • 요청 및 응답 크기 - 동기식 트리거의 경우 최대 6MB, 비동기식 트리거의 경우 최대 256MB
  • 환경 변수 - 최대 4KB

Lambda에는 이러한 제한 사항이 있으므로 이러한 제한 사항에 맞는 코드를 작성하는 것이 좋습니다. 그렇지 않은 경우 한 Lambda가 다른 Lambda를 트리거하도록 코드를 분할할 수 있습니다. 여러 Lambda 함수를 시퀀싱하는 데 사용할 수 있는 AWS에서 제공하는 단계 함수도 있습니다.

서버리스 애플리케이션을 로컬에서 어떻게 테스트할 수 있습니까?

서버리스 애플리케이션의 경우 관리형 서버리스 서비스를 제공하는 공급업체가 필요합니다. 우리는 AWS에 의존하여 애플리케이션을 테스트합니다. 애플리케이션을 테스트하기 위해 AWS에서 제공하는 몇 가지 로컬 옵션이 있습니다. AWS 서버리스 기술과 호환되는 일부 오픈 소스 도구를 사용하여 애플리케이션을 로컬에서 테스트할 수도 있습니다.

Lambda 함수와 DynamoDB를 테스트해 보겠습니다. 이렇게 하려면 로컬에서 실행해야 합니다.

먼저 도커 네트워크를 만듭니다. 네트워크는 Lambda 함수와 DynamoDB 간의 통신을 돕습니다.

$ docker network create lambda-local --docker-network lambda-local

DynamoDB 로컬은 AWS에서 제공하는 DynamoDB의 로컬 버전으로, 로컬에서 테스트하는 데 사용할 수 있습니다. 다음 도커 이미지를 실행하여 DynamoDB 로컬을 실행합니다.

$ docker run -p 8000:8000 --network lambda-local --name dynamodb amazon/dynamodb-local

user.rb 파일에 다음 줄을 추가합니다. 파일. 그러면 Lambda가 로컬 DynamoDB에 연결됩니다.

local_client = Aws::DynamoDB::Client.new(
  region: "local",
  endpoint: 'https://dynamodb:8000'
)
UsersTable.configure_client(client: local_client)

input.json 추가 Lambda에 대한 입력이 포함된 파일:

{
  "name": "Milap Neupane",
  "location": "Global"
}

Lambda를 실행하기 전에 로컬 DynamoDB에 테이블을 추가해야 합니다. 이를 위해 aws-migrate에서 제공하는 마이그레이션 기능을 사용할 것입니다. migrate.rb 파일을 만들고 다음 마이그레이션을 추가해 보겠습니다.

require 'aws-record'
require './users.rb'

local_client = Aws::DynamoDB::Client.new(
  region: "local",
  endpoint: 'https://localhost:8000'
)
migration = Aws::Record::TableMigration.new(UsersTable, client: local_client)

migration.create!(
  provisioned_throughput: {
    read_capacity_units: 5,
    write_capacity_units: 5
  }
)
migration.wait_until_available

마지막으로 다음 명령을 사용하여 로컬에서 Lambda를 실행합니다.

$ sam local invoke "CreateUserFunction" -t sam.yaml \
                                        -e input.json \
                                        --docker-network lambda-local

그러면 DynamoDB 테이블에 사용자 데이터가 생성됩니다.

로컬에서 AWS 스택을 실행하기 위한 localstack과 같은 옵션이 있습니다.

서버리스 컴퓨팅을 사용해야 하는 시기

서버리스 컴퓨팅을 사용할지 여부를 결정할 때 장점과 단점을 모두 알아야 합니다. 다음 특성에 따라 서버리스 접근 방식을 사용할 시기를 결정할 수 있습니다.

비용

  • 애플리케이션에 유휴 시간과 일관되지 않은 트래픽이 있는 경우 비용 절감에 도움이 되기 때문에 Lambda가 좋습니다.
  • 애플리케이션에 일관된 트래픽 볼륨이 있는 경우 AWS Lambda를 사용하면 비용이 많이 들 수 있습니다.

성능

  • 애플리케이션이 성능에 민감하지 않다면 AWS Lambda를 사용하는 것이 좋습니다.
  • Lambda에는 콜드 부팅 시간이 있으므로 콜드 부팅 중에 응답 시간이 느려질 수 있습니다.

백그라운드 처리

  • Lambda는 백그라운드 처리에 사용하기에 좋은 선택입니다. Sidekiq와 같은 일부 오픈 소스 도구에는 서버 확장 및 유지 관리 오버헤드가 있습니다. AWS Lambda와 AWS SQS 대기열을 결합하여 번거로운 서버 유지 관리 없이 백그라운드 작업을 처리할 수 있습니다.

동시 처리

  • 알다시피 Ruby의 동시성은 우리가 쉽게 할 수 있는 것이 아닙니다. Lambda를 사용하면 프로그래밍 언어 지원 없이 동시성을 달성할 수 있습니다. Lambda는 동시에 실행할 수 있으며 성능 향상에 도움이 됩니다.

주기적 또는 일회성 스크립트 실행

  • 우리는 크론 작업을 사용하여 Ruby 코드를 실행하지만 크론 작업에 대한 서버 유지 관리는 대규모 애플리케이션의 경우 어려울 수 있습니다. 이벤트 기반 Lambda를 사용하면 애플리케이션을 확장하는 데 도움이 됩니다.

다음은 서버리스 애플리케이션의 Lambda 함수에 대한 몇 가지 사용 사례입니다. 모든 것을 서버리스로 구축할 필요는 없습니다. 위에서 지정한 사용 사례에 대한 하이브리드 모델을 구축할 수 있습니다. 이는 애플리케이션 확장에 도움이 되고 개발자의 생산성을 향상시킵니다. 서버리스 기술은 발전하고 개선되고 있습니다. AWS Fatgate, Google CloudRun 등 AWS Lambda의 한계가 없는 다른 서버리스 기술이 있습니다.