비동기 프로그래밍 - AWS SDK for Java 1.x

곧 출시될 end-of-support AWS SDK for Java (v1) 버전을 발표했습니다. AWS SDK for Java V2로 마이그레이션하실 것을 권장합니다. 마이그레이션 날짜, 추가 세부 정보 및 방법에 대한 자세한 내용은 링크된 공지 사항을 참조하세요.

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

비동기 프로그래밍

동기 또는 비동기 메서드를 사용하여 서비스에 대한 작업을 호출할 수 있습니다. AWS 비동기 메서드는 클라이언트가 서비스로부터 응답을 받을 때까지 스레드의 실행을 차단합니다. 비동기 메서드는 (값을) 즉시 반환하며, 응답을 기다리지 않고 제어 권한을 호출 스레드에 넘겨줍니다.

비동기 메서드는 응답이 제공되기 전에 (값을) 반환하므로 준비되었을 때 응답을 가져올 방법이 필요합니다. Future 객체와 콜백 메서드라는 두 가지 방법을 AWS SDK for Java 제공합니다.

Java Future

의 비동기 메서드는 미래의 비동기 작업 결과를 포함하는 Future 객체를 AWS SDK for Java 반환합니다.

서비스가 아직 응답 객체를 제공하지 않은 경우 Future isDone() 메서드를 호출합니다. 응답이 준비되면 Future get() 메서드를 호출하여 응답 객체를 가져올 수 있습니다. 이 메커니즘을 사용하면 애플리케이션이 계속 다른 작업을 수행하는 동안 비동기 작업의 결과를 정기적으로 폴링할 수 있습니다.

다음은 객체를 보유할 수 있는 함수를 호출하고 객체를 보유할 수 있는 Lambda 함수를 수신하는 비동기 작업의 예입니다. Future InvokeResult InvokeResult 객체는 isDone()true가 된 후에만 가져옵니다.

import com.amazonaws.services.lambda.AWSLambdaAsyncClient; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import java.nio.ByteBuffer; import java.util.concurrent.Future; import java.util.concurrent.ExecutionException; public class InvokeLambdaFunctionAsync { public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req); System.out.print("Waiting for future"); while (future_res.isDone() == false) { System.out.print("."); try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("\nThread.sleep() was interrupted!"); System.exit(1); } } try { InvokeResult res = future_res.get(); if (res.getStatusCode() == 200) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); } else { System.out.format("Received a non-OK response from {AWS}: %d\n", res.getStatusCode()); } } catch (InterruptedException | ExecutionException e) { System.err.println(e.getMessage()); System.exit(1); } System.exit(0); } }

비동기 콜백

SDK를 사용하면 Java Future 객체를 사용하여 비동기 요청의 상태를 모니터링하는 것 외에도 인터페이스를 사용하는 클래스를 구현할 수 있습니다. AsyncHandler AsyncHandler요청 완료 방식에 따라 호출되는 두 가지 메서드 (및) 를 제공합니다. onSuccess onError

콜백 인터페이스 접근 방법의 주요 장점은 Future 객체를 폴링하여 요청 완료 시점을 알아낼 필요가 없다는 점입니다. 대신에 코드에서 다음 활동을 즉시 시작할 수 있으며, SDK에 의존하여 핸들러를 즉시 호출할 수 있습니다.

import com.amazonaws.services.lambda.AWSLambdaAsync; import com.amazonaws.services.lambda.AWSLambdaAsyncClientBuilder; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import com.amazonaws.handlers.AsyncHandler; import java.nio.ByteBuffer; import java.util.concurrent.Future; public class InvokeLambdaFunctionCallback { private class AsyncLambdaHandler implements AsyncHandler<InvokeRequest, InvokeResult> { public void onSuccess(InvokeRequest req, InvokeResult res) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); System.exit(0); } public void onError(Exception e) { System.out.println(e.getMessage()); System.exit(1); } } public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req, new AsyncLambdaHandler()); System.out.print("Waiting for async callback"); while (!future_res.isDone() && !future_res.isCancelled()) { // perform some other tasks... try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("Thread.sleep() was interrupted!"); System.exit(0); } System.out.print("."); } } }

모범 사례

콜백 실행

AsyncHandler의 구현은 비동기 클라이언트가 소유하는 스레드 풀 내부에서 실행됩니다. 단기 실행 코드는 AsyncHandler 구현 내부에 적합합니다. 핸들러 메서드 내부에서 장기 실행 또는 차단 코드를 실행하면 비동기 클라이언트에 사용되는 스레드 풀에 대한 경합이 발생하여 클라이언트에서 요청을 실행할 수 없습니다. 콜백에서 시작해야 하는 장기 실행 작업이 있는 경우 콜백이 애플리케이션에 의해 관리되는 스레드 풀이나 새 스레드에서 작업을 실행하도록 하십시오.

스레드 풀 구성

의 비동기 클라이언트는 대부분의 응용 프로그램에서 작동하는 기본 스레드 풀을 AWS SDK for Java 제공합니다. 사용자 정의를 ExecutorService구현하고 이를 AWS SDK for Java 비동기 클라이언트에 전달하여 스레드 풀 관리 방식을 더 잘 제어할 수 있습니다.

예를 들어 사용자 지정을 사용하여 풀의 스레드 이름 지정 ThreadFactory방식을 제어하거나 스레드 사용에 대한 추가 정보를 기록하는 ExecutorService 구현을 제공할 수 있습니다.

비동기 액세스

SDK의 TransferManager클래스는 작업을 위한 비동기 지원을 제공합니다. Amazon S3TransferManager비동기 업로드 및 다운로드를 관리하고, 전송에 대한 자세한 진행 상황 보고를 제공하고, 다양한 이벤트에 대한 콜백을 지원합니다.