AWS Lambda를 사용한 서버리스 컴퓨팅, 1 부

서버리스 컴퓨팅은 오늘날 클라우드 컴퓨팅에서 가장 인기있는 것일 수 있지만 정확히 무엇입니까? 이 두 부분으로 구성된이 자습서는 서버리스 컴퓨팅의 개요부터 기존 클라우드 컴퓨팅을 방해하는 것으로 간주되는 이유, Java 기반 프로그래밍에서 사용하는 방법에 이르기까지 서버리스 컴퓨팅의 개요로 시작합니다.

개요를 따라 가면 오늘날 서버리스 컴퓨팅을위한 많은 프리미어 Java 기반 솔루션으로 간주되는 AWS Lambda에 대한 실무 소개를 받게됩니다. 1 부에서는 AWS Lambda를 사용하여 Java로 첫 번째 Lambda 함수를 빌드, 배포 및 테스트합니다. 2 부에서는 Lambda 함수를 DynamoDB와 통합 한 다음 AWS SDK를 사용하여 Java 애플리케이션에서 Lambda 함수를 호출합니다.

서버리스 컴퓨팅이란 무엇입니까?

작년에 저는 회사 인턴에게 다양한 아키텍처 패턴에 대해 이야기하고 서버리스 아키텍처에 대해 언급했습니다. 그는 모든 애플리케이션에 서버가 필요하며 허공에서 실행할 수 없다는 사실을 금방 알아 차 렸습니다. 인턴은 내 것을 놓치고 있더라도 요점이 있었다. 서버리스 컴퓨팅은 애플리케이션 실행을위한 마법 같은 플랫폼이 아닙니다.

사실 서버리스 컴퓨팅 은 개발자 인 여러분 이 서버 를 다룰 필요가 없음을 의미 합니다. AWS Lambda와 같은 서버리스 컴퓨팅 플랫폼을 사용하면 기본 서버를 구성하거나 관리 할 필요없이 코드를 빌드하고 배포 할 수 있습니다. 배포 단위는 코드입니다. 코드를 호스팅하는 컨테이너 나 코드를 실행하는 서버가 아니라 단순히 코드 자체입니다. 생산성 측면에서 코드가 저장되는 위치와 실행 환경을 관리하는 방법에 대한 세부 정보를 오프로드하면 분명한 이점이 있습니다. 서버리스 컴퓨팅은 실행 메트릭에 따라 가격이 책정되므로 재정적 이점도 있습니다.

AWS Lambda의 비용은 얼마입니까?

이 글을 쓰는 시점에서 AWS Lambda의 가격 등급은 실행 횟수와 실행 기간을 기반으로합니다.

  • 매월 처음 백만 번의 실행은 무료이며 그 이후에는 백만 번의 실행 당 $ 0.20를 지불합니다 (요청 당 $ 0.0000002).
  • 기간은 코드 실행이 시작된 시간부터 결과를 반환 할 때까지 계산되며 가장 가까운 100ms로 반올림됩니다. 청구되는 양은 함수에 할당 된 RAM 양을 기준으로하며 비용은 GB- 초당 0.00001667 USD입니다.

가격 세부 정보 및 무료 계층 할당은 개요에서 의미하는 것보다 약간 더 복잡합니다. 가격 등급을 방문하여 몇 가지 가격 시나리오를 살펴보세요.

서버리스 컴퓨팅의 작동 방식에 대한 아이디어를 얻으려면 그림 1에 나와있는 서버리스 컴퓨팅 실행 모델부터 시작하겠습니다.

스티븐 헤인즈

간단히 말해서 서버리스 실행 모델은 다음과 같습니다.

  1. 클라이언트는 서버리스 컴퓨팅 플랫폼에 특정 기능을 실행하도록 요청합니다.
  2. 서버리스 컴퓨팅 플랫폼은 먼저 기능이 서버에서 실행 중인지 확인합니다. 함수가 아직 실행 중이 아니면 플랫폼은 데이터 저장소에서 함수를로드합니다.
  3. 그런 다음 플랫폼은 기능을 실행할 수있는 실행 환경으로 미리 구성된 서버 중 하나에 기능을 배포합니다.
  4. 함수를 실행하고 결과를 캡처합니다.
  5. 결과를 다시 클라이언트에 반환합니다.

빌드하는 코드의 세분성이 함수 이기 때문에 서버리스 컴퓨팅을 FaaS (Function as a Service)라고도 합니다 . 플랫폼은 자체 서버에서 함수를 실행하고 함수 요청과 함수 응답 간의 프로세스를 조율합니다.

나노 서비스, 확장 성 및 가격

서버리스 컴퓨팅에 대해 정말 중요한 세 가지는 나노 서비스 아키텍처입니다. 사실상 무한 확장 가능하다는 사실; 무한에 가까운 확장 성과 관련된 가격 모델. 우리는 각 요소를 파헤칠 것입니다.

나노 서비스

마이크로 서비스에 대해 들어 보셨고 12 단계 애플리케이션에 대해 알고 계실 것입니다.하지만 서버리스 기능은 구성 요소를 구성 요소로 분류하는 패러다임을 완전히 새로운 수준으로 끌어 올렸습니다. "나노 서비스"라는 용어는 업계에서 인정하는 용어가 아니지만 아이디어는 간단합니다. 각 나노 서비스는 단일 작업 또는 책임을 구현해야합니다. 예를 들어, 위젯을 생성하려는 경우 생성 행위는 자체 나노 서비스가됩니다. 위젯을 검색하려는 경우 검색 행위도 나노 서비스가됩니다. 위젯을 주문하려는 경우 해당 주문은 또 다른 나노 서비스가됩니다.

나노 서비스 아키텍처를 사용하면 매우 세분화 된 수준에서 애플리케이션을 정의 할 수 있습니다. 테스트 기반 개발 (개별 테스트 수준에서 코드를 작성하여 원치 않는 부작용을 방지하는 데 도움이 됨)과 유사하게 나노 서비스 아키텍처는 매우 세분화되고 특정 기능 측면에서 애플리케이션을 정의하도록 권장합니다. 이 접근 방식은 빌드중인 항목에 대한 명확성을 높이고 새 코드에서 원치 않는 부작용을 줄입니다.

마이크로 서비스 대 나노 서비스

마이크로 서비스는 애플리케이션을 각각 특정 작업을 수행하는 서비스 모음으로 나눌 것을 권장합니다. 문제는 아무도 마이크로 서비스 의 범위 를 실제로 정량화하지 않았다는 것 입니다. 결과적으로 우리는 마이크로 서비스를 관련 서비스 모음으로 정의하고 모두 동일한 데이터 모델과 상호 작용합니다. 개념적으로 주어진 데이터 모델과 상호 작용하는 저수준 기능이있는 경우 해당 기능은 관련 서비스 중 하나로 이동해야합니다. 높은 수준의 상호 작용은 데이터베이스를 직접 쿼리하는 대신 서비스를 호출해야합니다.

마이크로 서비스 또는 나노 서비스 수준에서 Lambda 함수를 구축할지 여부에 대해 서버리스 컴퓨팅에서 지속적인 논쟁이 있습니다. 좋은 소식은 세분화로 함수를 쉽게 빌드 할 수 있지만 마이크로 서비스 전략에는 요청 핸들러에 약간의 추가 라우팅 로직이 필요하다는 것입니다.

디자인 관점에서 서버리스 애플리케이션은 매우 잘 정의되고 깔끔해야합니다. 배포 관점에서 훨씬 더 많은 배포를 관리해야하지만 다른 기능에 영향을주지 않고 기능의 새 버전을 개별적으로 배포 할 수도 있습니다. 서버리스 컴퓨팅은 특히 대규모 팀의 개발에 적합하며, 개발 프로세스를 더 쉽게 만들고 코드 오류 발생 가능성을 줄일 수 있습니다.

확장 성

새로운 아키텍처 패러다임을 도입하는 것 외에도 서버리스 컴퓨팅 플랫폼은 사실상 무한한 확장 성을 제공합니다. 나는 진정으로 그런 것은 없기 때문에 "실질적으로"말한다무한한 확장 성. 그러나 모든 실용적인 목적을 위해 Amazon과 같은 서버리스 컴퓨팅 공급자는 사용자가 처리 할 수있는 것보다 더 많은 부하를 처리 할 수 ​​있습니다. 증가하는 수요를 충족하기 위해 자체 서버 (또는 클라우드 기반 가상 머신) 확장을 관리하려면 사용량을 모니터링하고, 더 많은 서버를 시작할시기를 식별하고, 적시에 클러스터에 더 많은 서버를 추가해야합니다. 마찬가지로 수요가 감소하면 수동으로 축소해야합니다. 서버리스 컴퓨팅을 사용하면 서버리스 컴퓨팅 플랫폼에 실행하려는 최대 동시 기능 요청 수를 알리고 플랫폼이 확장을 수행합니다.

가격

Finally, the serverless computing pricing model allows you to scale your cloud bill based on usage. When you have light usage, your bill will be low (or nil if you stay in the free range). Of course, your bill will increase with usage, but hopefully you will also have new revenue to support your higher cloud bill. For contrast, if you were to manage your own servers, you would have to pay a base cost to run the minimum number of servers required. As usage increased, you would scale up in increments of entire servers, rather than increments of individual function calls. The serverless computing pricing model is directly proportional to your usage.

AWS Lambda for serverless computing

AWS Lambda는 EC2 및 S3와 같은 Amazon Web Services 플랫폼 위에 구현 된 서버리스 컴퓨팅 플랫폼입니다. AWS Lambda는 S3에 코드를 암호화하고 저장합니다. 함수 실행이 요청되면 런타임 사양을 사용하여 "컨테이너"를 생성하고 컴퓨팅 팜의 EC2 인스턴스 중 하나에 배포 한 다음 해당 함수를 실행합니다. 프로세스는 그림 2에 나와 있습니다.

스티븐 헤인즈

When you create a Lambda function, you configure it in AWS Lambda, specifying things like the runtime environment (we'll use Java 8 for this article), how much memory to allocate to it, identity and access management roles, and the method to execute. AWS Lambda uses your configuration to setup a container and deploy the container to an EC2 instance. It then executes the method that you've specified, in the order of package, class, and method.

At the time of this writing, you can build Lambda functions in Node, Java, Python, and most recently, C#. For the purposes of this article we will use Java.

What is a Lambda function?

When you write code designed to run in AWS Lambda, you are writing functions. The term functions comes from functional programming, which originated in lambda calculus. The basic idea is to compose an application as a collection of functions, which are methods that accept arguments, compute a result, and have no unwanted side-effects. Functional programming takes a mathematical approach to writing code that can be proven to be correct. While it's good to keep functional programming in mind when you are writing code for AWS Lambda, all you really need to understand is that the function is a single-method entry-point that accepts an input object and returns an output object.

Serverless execution modes

While Lambda functions can run synchronously, as described above, they can also run asynchronously and in response to events. For example, you could configure a Lambda to run whenever a file was uploaded to an S3 bucket. This configuration is sometimes used for image or video processing: when a new image is uploaded to an S3 bucket, a Lambda function is invoked with a reference to the image to process it.

I worked with a very large company that leveraged this solution for photographers covering a marathon. The photographers were on the course taking photographs. Once their memory cards were full, they loaded the images onto a laptop and uploaded the files to S3. As images were uploaded, Lambda functions were executed to resize, watermark, and add a reference for each image to its runner in the database.

All of this would take a lot of work to accomplish manually, but in this case the work not only processed faster because of AWS Lambda's horizontal scalability, but also seamlessly scaled up and back down, thus optimizing the company's cloud bill.

In addition to responding to files uploaded to S3, lambdas can be triggered by other sources, such as records being inserted into a DynamoDB database and analytic information streaming from Amazon Kinesis. We'll look at an example featuring DynamoDB in Part 2.

AWS Lambda functions in Java

Now that you know a little bit about serverless computing and AWS Lambda, I'lll walk you through building an AWS Lambda function in Java. 

이 자습서 "AWS Lambda를 사용한 서버리스 컴퓨팅"의 예제 애플리케이션에 대한 코드 소스 코드를 가져옵니다. JavaWorld를 위해 Steven Haines가 작성했습니다.

Lambda 함수 구현

다음 두 가지 방법 중 하나로 Lambda 함수를 작성할 수 있습니다.

  • 이 함수는 클라이언트에 대한 입력 스트림을 수신하고 클라이언트에 다시 출력 스트림에 쓸 수 있습니다.
  • 이 함수는 미리 정의 된 인터페이스를 사용할 수 있습니다.이 경우 AWS Lambda는 입력 스트림을 객체로 자동으로 역 직렬화하고,이를 함수에 전달하고, 함수의 응답을 클라이언트에 반환하기 전에 직렬화합니다.

AWS Lambda 함수를 구현하는 가장 쉬운 방법은 사전 정의 된 인터페이스를 사용하는 것입니다. Java의 경우 먼저 프로젝트에 다음 AWS Lambda 코어 라이브러리를 포함해야합니다 (이 예제에서는 Maven을 사용함).

 com.amazonaws aws-lambda-java-core 1.1.0  

Next, have your class implement the following interface:

Listing 1. RequestHandler.java

 public interface RequestHandler { /** * Handles a Lambda function request * @param input The Lambda function input * @param context The Lambda execution environment context object. * @return The Lambda function output */ public O handleRequest(I input, Context context); } 

The RequestHandler interface defines a single method: handleRequest(), which is passed an input object and a Context object, and returns an output object. For example, if you were to define a Request class and a Response class, you could implement your lambda as follows:

 public class MyHandler implements RequestHandler { public Response handleRequest(Request request, Context context) { ... } } 

Alternatively, if you wanted to bypass the predefined interface, you could manually handle the InputStream and OutputStream yourself, by implementing a method with the following signature:

 public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { ... } 

The Context object provides information about your function and the environment in which it is running, such as the function name, its memory limit, its logger, and the amount of time remaining, in milliseconds, that the function has to complete before AWS Lambda kills it.