

# Lambda 관리형 인스턴스 런타임
<a name="lambda-managed-instances-runtimes"></a>

Lambda는 Lambda 관리형 인스턴스를 사용할 때 요청을 다르게 처리합니다. Lambda 관리형 인스턴스는 각 실행 환경에서 요청을 순차적으로 처리하는 대신 각 실행 환경 내에서 여러 요청을 동시에 처리합니다. 실행 모델의 변화로 Lambda 관리형 인스턴스를 사용하는 함수가 Lambda(기본값) 단일 동시성 모델에서는 발생하지 않는 스레드 안전, 상태 관리 및 컨텍스트 격리와 관련된 우려 사항을 고려해야 합니다. 추가로 다중 동시성 구현은 런타임마다 다릅니다.

## 지원되는 언어
<a name="lambda-managed-instances-supported-runtimes"></a>

Lambda 관리형 인스턴스는 다음과 같은 프로그래밍 언어 및 런타임과 함께 사용할 수 있습니다.
+ **Java:** Java 21 이상.
+ **Python:** Python 3.13 이상.
+ **Node.js:** Node.js 22 이상.
+ **.NET:** .NET 8 이상.
+ **Rust:** OS 전용 런타임 `provided.al2023` 이상 사용이 지원됩니다.

## 언어별 고려 사항
<a name="lambda-managed-instances-runtime-considerations"></a>

프로그래밍 언어마다 다르게 다중 동시성을 구현합니다. 적절한 동시성 모범 사례를 적용하려면 선택한 프로그래밍 언어로 다중 동시성이 구현되는 방식을 이해해야 합니다.

**Java**

동시성을 위해 OS 스레드와 함께 단일 프로세스를 사용합니다. 여러 스레드가 핸들러 메서드를 동시에 실행하므로 상태 및 공유 리소스의 스레드 안전 처리가 필요합니다.

**Python**

각각의 동시 요청이 별도의 프로세스에서 실행되는 여러 개의 Python 프로세스를 사용합니다. `/tmp` 디렉터리와 같은 공유 리소스에는 주의가 필요하지만 대부분의 동시성 문제를 예방합니다.

**Node.js**

비동기 실행으로 [작업자 스레드](https://nodejs.org/api/worker_threads.html)를 사용합니다. 동시 요청이 작업자 스레드에 분산되고, 각 작업자 스레드는 동시 요청을 비동기식으로 처리할 수 있으므로 상태 및 공유 리소스를 안전하게 처리해야 합니다.

**.NET**

여러 동시 요청의 비동기 처리와 함께 .NET 태스크를 사용합니다. 상태 및 공유 리소스의 안전한 처리가 필요합니다.

**Rust**

[Tokio](https://tokio.rs/)로 구동되는 비동기식 태스크와 함께 단일 프로세스를 사용합니다. 핸들러는 `Clone` \$1 `Send`여야 합니다.

## 다음 단계
<a name="lambda-managed-instances-runtime-next-steps"></a>

각 런타임에 자세한 내용은 다음을 참조하세요.
+ [Lambda 관리형 인스턴스용 Java 런타임](lambda-managed-instances-java-runtime.md)
+ [Lambda 관리형 인스턴스용 Node.js 런타임](lambda-managed-instances-nodejs-runtime.md)
+ [Lambda 관리형 인스턴스용 Python 런타임](lambda-managed-instances-python-runtime.md)
+ [Lambda 관리형 인스턴스용 .NET 런타임](lambda-managed-instances-dotnet-runtime.md)
+ [Lambda 관리형 인스턴스에 대한 Rust 지원](lambda-managed-instances-rust.md)

# Lambda 관리형 인스턴스용 Java 런타임
<a name="lambda-managed-instances-java-runtime"></a>

Java 런타임의 경우 Lambda 관리형 인스턴스는 동시성을 위해 OS 스레드를 사용합니다. Lambda는 초기화 중에 실행 환경별로 한 번씩 핸들러 객체를 로드한 다음 여러 개의 스레드를 생성합니다. 이러한 스레드는 병렬로 실행되고 상태 및 공유 리소스의 스레드 안전 처리가 필요합니다. 각 스레드는 동일한 핸들러 객체와 모든 정적 필드를 공유합니다.

## 동시성 구성
<a name="lambda-managed-instances-java-concurrency-config"></a>

Lambda가 각 실행 환경에 보내는 최대 동시 요청 수는 함수 구성의 `PerExecutionEnvironmentMaxConcurrency` 설정으로 제어됩니다. 이 설정은 선택 사항이며, 기본값은 런타임에 따라 달라집니다. Java 런타임의 경우 기본값은 vCPU당 32개 동시 요청이며, 직접 값을 구성할 수도 있습니다. 또한 이 값은 Java 런타임에서 사용하는 스레드 수를 결정합니다. Lambda는 각 실행 환경의 용량에 따라 구성된 최대 수까지 동시 요청 수를 자동으로 조정하여 이러한 요청을 수용합니다.

## 다중 동시성 함수 빌드
<a name="lambda-managed-instances-java-building"></a>

Lambda 관리형 인스턴스를 사용할 때는 다른 다중 스레드 환경에서와 동일한 스레드 안전 관행을 적용해야 합니다. 핸들러 객체는 모든 런타임 작업자 스레드에서 공유되기에 변경 가능한 상태는 스레드 안전 상태여야 합니다. 여기에는 컬렉션, 데이터베이스 연결 및 요청 처리 도중 수정된 모든 정적 객체가 포함됩니다.

AWS SDK 클라이언트는 스레드 안전 상태이기에 별도의 처리가 필요하지 않습니다.

**예제: 데이터베이스 연결 풀**

다음 코드는 스레드 간에 공유되는 정적 데이터베이스 연결 객체를 사용합니다. 사용되는 연결 라이브러리에 따라 스레드가 안전하지 않을 수 있습니다.

```
public class DBQueryHandler implements RequestHandler<Object, String> {
    // Single connection shared across all threads - NOT SAFE
    private static Connection connection;

    public DBQueryHandler() {
        this.connection = DriverManager.getConnection(jdbcUrl, username, password);
    }

    @Override
    public String handleRequest(Object input, Context context) {
        PreparedStatement stmt = connection.prepareStatement(query);
        ResultSet rs = stmt.executeQuery();
        // Multiple threads using same connection causes issues
        return result.toString();
    }
}
```

스레드에 있어 안전한 방식은 연결 풀을 사용하는 것입니다. 다음 예제에서 함수 핸들러는 풀에서 연결을 검색합니다. 연결은 단일 요청의 컨텍스트에서만 사용됩니다.

```
public class DBQueryHandler implements RequestHandler<Object, String> {

    private static HikariDataSource dataSource;

    public DBQueryHandler() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/your_database");
        dataSource = new HikariDataSource(config); // Create pool once per Lambda container
    }

    @Override
    public String handleRequest(Object input, Context context) {
        String query = "SELECT column_name FROM your_table LIMIT 10";
        StringBuilder result = new StringBuilder("Data:\n");

        // try-with-resources automatically calls close() on the connection,
        // which returns it to the HikariCP pool (does NOT close the physical DB connection)
        try (Connection connection = dataSource.getConnection();
             PreparedStatement stmt = connection.prepareStatement(query);
             ResultSet rs = stmt.executeQuery()) {

            while (rs.next()) {
                result.append(rs.getString("column_name")).append("\n");
            }

        } catch (Exception e) {
            context.getLogger().log("Error: " + e.getMessage());
            return "Error";
        }

        return result.toString();
    }
}
```

**예제: 컬렉션**

표준 Java 컬렉션은 스레드에 있어 안전하지 않습니다.

```
public class Handler implements RequestHandler<Object, String> {
    private static List<String> items = new ArrayList<>();
    private static Map<String, Object> cache = new HashMap<>();

    @Override
    public String handleRequest(Object input, Context context) {
        items.add("list item");  // Not thread-safe
        cache.put("key", input); // Not thread-safe
        return "Success";
    }
}
```

대신 다음 스레드 안전 컬렉션을 사용합니다.

```
public class Handler implements RequestHandler<Object, String> {
    private static final List<String> items = 
        Collections.synchronizedList(new ArrayList<>());
    private static final ConcurrentHashMap<String, Object> cache = 
        new ConcurrentHashMap<>();

    @Override
    public String handleRequest(Object input, Context context) {
        items.add("list item");  // Thread-safe
        cache.put("key", input); // Thread-safe
        return "Success";
    }
}
```

## 공유 /tmp 디렉터리
<a name="lambda-managed-instances-java-shared-tmp"></a>

`/tmp` 디렉터리는 실행 환경의 모든 동시 요청에서 공유됩니다. 동일한 파일에 대한 동시 쓰기로 인해 다른 프로세스가 파일을 덮어쓰는 등 데이터가 손상될 수 있습니다. 이를 해결하려면 공유 파일에 대한 파일 잠금을 구현하거나 스레드 또는 요청별로 고유한 파일 이름을 사용하여 충돌을 방지합니다. 사용 가능한 공간이 소진되지 않도록 불필요한 파일을 정리해야 합니다.

## 로깅
<a name="lambda-managed-instances-java-logging"></a>

다중 동시 시스템에서는 로그 인터리브(로그에서 서로 다른 요청의 로그 항목이 인터리브됨)가 정상적인 동작입니다.

Lambda 관리형 인스턴스를 사용하는 함수는 항상 [고급 로깅 제어](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)가 도입된 구조화된 JSON 로그 형식을 사용합니다. 이 형식에는 `requestId`가 포함되어 로그 항목을 단일 요청과 연관시킬 수 있습니다. `context.getLogger()`의 `LambdaLogger` 객체를 사용하면 `requestId`가 각 로그 항목에 자동으로 포함됩니다. 자세한 내용은 [Java에서 Lambda 고급 로깅 제어 사용](java-logging.md#java-logging-advanced) 항목을 참조하세요.

## 요청 컨텍스트
<a name="lambda-managed-instances-java-request-context"></a>

`context` 객체는 요청 스레드에 바인딩됩니다. `context.getAwsRequestId()`를 사용하면 현재 요청의 요청 ID에 대해 스레드 안전 액세스가 가능합니다.

`context.getXrayTraceId()`를 사용하여 X-Ray 트레이스 ID에 액세스합니다. 이렇게 하면 현재 요청의 트레이스 ID에 대한 스레드 안전 액세스 권한이 제공됩니다. Lambda는 Lambda 관리형 인스턴스에서 `_X_AMZN_TRACE_ID` 환경 변수를 지원하지 않습니다. AWS SDK를 사용할 때 X-Ray 트레이스 ID가 자동으로 전파됩니다.

`com.amazonaws.services.lambda.runtime.Context.getRemainingTimeInMillis()`를 사용하여 제한 시간 초과를 감지합니다. 자세한 정보는 [오류 처리 및 복구](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling)을 참조하세요.

프로그램에서 가상 스레드를 사용하거나 초기화 도중 스레드를 생성하는 경우 필요한 요청 컨텍스트를 스레드에 전달해야 합니다.

## 초기화 및 종료
<a name="lambda-managed-instances-java-init-shutdown"></a>

함수 초기화는 실행 환경당 한 번 발생합니다. 초기화 도중 생성된 객체는 스레드 간에 공유됩니다.

확장이 포함된 Lambda 함수의 경우 실행 환경은 종료 중에 SIGTERM 신호를 내보냅니다. 이 신호는 확장에서 버퍼 비우기와 같은 정리 태스크를 트리거하는 데 사용됩니다. SIGTERM 이벤트를 구독하여 데이터베이스 연결 종료와 같은 함수 정리 태스크를 트리거할 수 있습니다. 실행 환경 수명 주기에 대한 자세한 내용은 [Lambda 실행 환경 수명 주기 이해](lambda-runtime-environment.md) 섹션을 참조하세요.

## 종속성 버전
<a name="lambda-managed-instances-java-dependencies"></a>

Lambda 관리형 인스턴스에는 다음과 같은 최소 패키지 버전이 필요합니다.
+ AWS SDK for Java 2.0: 버전 2.34.0 이상
+ AWS X-Ray SDK for Java: 버전 2.20.0 이상
+ AWS Distro for OpenTelemetry - Instrumentation for Java: 버전 2.20.0 이상
+ Powertools for AWS Lambda(Java): 버전 2.8.0 이상

## Powertools for AWS Lambda(Java)
<a name="lambda-managed-instances-java-powertools"></a>

Powertools for AWS Lambda(Java)는 Lambda 관리형 인스턴스와 호환되고 로깅, 추적, 지표 등을 위한 유틸리티를 제공합니다. 자세한 내용은 [Powertools for AWS Lambda(Java)](https://github.com/aws-powertools/powertools-lambda-java)를 참조하세요.

## 다음 단계
<a name="lambda-managed-instances-java-next-steps"></a>
+ [Lambda 관리형 인스턴스용 Node.js 런타임](lambda-managed-instances-nodejs-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 Python 런타임](lambda-managed-instances-python-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 .NET 런타임](lambda-managed-instances-dotnet-runtime.md) 검토
+ [Lambda 관리형 인스턴스 규모 조정](lambda-managed-instances-scaling.md) 알아보기

# Lambda 관리형 인스턴스용 Node.js 런타임
<a name="lambda-managed-instances-nodejs-runtime"></a>

Node.js 런타임의 경우 Lambda 관리형 인스턴스는 `async`/`await` 기반 실행과 함께 작업자 스레드를 사용하여 동시 요청을 처리합니다. 함수 초기화는 작업자 스레드당 한 번 발생합니다. 동시 간접 호출은 2가지 차원에서 처리됩니다. 작업자 스레드는 vCPU 간에 병렬 처리를 제공하고, 비동기 실행은 각 스레드 내에서 동시성을 제공합니다. 동일한 작업자 스레드에서 처리하는 각 동시 요청은 동일한 핸들러 객체와 전역 상태를 공유하기에 여러 동시 요청에서의 안전한 처리가 필요합니다.

## 최대 동시성
<a name="lambda-managed-instances-nodejs-max-concurrency"></a>

Lambda가 각 실행 환경에 보내는 최대 동시 요청 수는 함수 구성의 `PerExecutionEnvironmentMaxConcurrency` 설정으로 제어됩니다. 이 설정은 선택 사항이며, 기본값은 런타임에 따라 달라집니다. Node.js 런타임의 경우 기본값은 vCPU당 64개 동시 요청으로, 또는 자체 값을 구성할 수 있습니다. Lambda는 각 실행 환경의 용량에 따라 구성된 최대 수까지 동시 요청 수를 자동으로 조정하여 이러한 요청을 수용합니다.

Node.js의 경우 각 실행 환경에서 처리할 수 있는 동시 요청 수는 작업자 스레드 수와 동시 요청을 비동기식으로 처리하는 각 작업자 스레드의 용량에 따라 결정됩니다. 기본 작업자 스레드 수는 사용 가능한 vCPU 수에 따라 결정됩니다. 또는 `AWS_LAMBDA_NODEJS_WORKER_COUNT` 환경 변수를 설정하여 작업자 스레드 수를 구성할 수 있습니다. 비동기 함수 핸들러를 사용하면 작업자 스레드당 여러 요청을 처리할 수 있어 사용이 권장됩니다. 함수 핸들러가 동기식인 경우 각 작업자 스레드는 한 번에 하나의 요청만 처리할 수 있습니다.

## 다중 동시성 함수 빌드
<a name="lambda-managed-instances-nodejs-building"></a>

비동기 함수 핸들러를 사용하면 각 런타임 작업자가 여러 개의 요청을 동시에 처리합니다. 전역 객체가 여러 동시 요청에서 공유됩니다. 변경 가능한 객체의 경우 전역 상태를 사용하지 않거나 `AsyncLocalStorage`를 사용합니다.

AWS SDK 클라이언트는 비동기식으로 안전하기에 별도의 처리가 필요하지 않습니다.

**예제: 전역 상태**

다음 코드는 함수 핸들러 내에서 변형되는 전역 객체를 사용합니다. 비동기식에서 사용하기에 안전하지 않습니다.

```
let state = {
    currentUser: null,
    requestData: null
};

export const handler = async (event, context) => {
    state.currentUser = event.userId;
    state.requestData = event.data;

    await processData(state.requestData);

    // state.currentUser might now belong to a different request
    return { user: state.currentUser };
};
```

함수 핸들러 내에서 `state` 객체를 초기화하면 전역 상태가 공유되지 않습니다.

```
export const handler = async (event, context) => {
    let state = {
        currentUser: event.userId,
        requestData: event.data
    };
    
    await processData(state.requestData);

    return { user: state.currentUser };
};
```

**예제: 데이터베이스 연결**

다음 코드는 여러 간접 호출 간에 공유되는 클라이언트 객체를 사용합니다. 사용되는 연결 라이브러리에 따라 동시성이 안전하지 않을 수 있습니다.

```
const { Client } = require('pg');

// Single connection created at init time
const client = new Client({
  host: process.env.DB_HOST,
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD
});

// Connect once during cold start
client.connect();

exports.handler = async (event) => {
  // Multiple parallel invocations share this single connection = BAD
  // With multi-concurrent Lambda, queries will collide
  const result = await client.query('SELECT * FROM users WHERE id = $1', [event.userId]);
  
  return {
    statusCode: 200,
    body: JSON.stringify(result.rows[0])
  };
};
```

동시성에 있어 안전한 방식은 연결 풀을 사용하는 것입니다. 풀은 각 동시 데이터베이스 쿼리에 별도의 연결을 사용합니다.

```
const { Pool } = require('pg');

// Connection pool created at init time
const pool = new Pool({
  host: process.env.DB_HOST,
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  max: 20,  // Max connections in pool
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000
});

exports.handler = async (event) => {
  // Pool gives each parallel invocation its own connection
  const result = await pool.query('SELECT * FROM users WHERE id = $1', [event.userId]);
  
  return {
    statusCode: 200,
    body: JSON.stringify(result.rows[0])
  };
};
```

## Node.js 22 콜백 기반 핸들러
<a name="lambda-managed-instances-nodejs-callback-handlers"></a>

Node.js 22를 사용하는 경우 Lambda 관리형 인스턴스에서 콜백 기반 함수 핸들러를 사용할 수 없습니다. 콜백 기반 핸들러는 Lambda(기본값) 함수에서만 지원됩니다. Node.js 24 이상 런타임의 경우 Lambda(기본값) 및 Lambda 관리형 인스턴스 모두에서 콜백 기반 함수 핸들러가 더 이상 사용되지 않습니다.

대신 Lambda 관리형 인스턴스를 사용할 때는 `async` 함수 핸들러를 사용하세요. 자세한 내용은 [Node.js에서 Lambda 함수 핸들러 정의](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html)를 참조하세요.

## 공유 /tmp 디렉터리
<a name="lambda-managed-instances-nodejs-shared-tmp"></a>

`/tmp` 디렉터리는 실행 환경의 모든 동시 요청에서 공유됩니다. 동일한 파일에 대한 동시 쓰기로 인해 다른 프로세스가 파일을 덮어쓰는 등 데이터가 손상될 수 있습니다. 이를 해결하려면 공유 파일에 대한 파일 잠금을 구현하거나 요청당 고유한 파일 이름을 사용하여 충돌을 방지합니다. 사용 가능한 공간이 소진되지 않도록 불필요한 파일을 정리해야 합니다.

## 로깅
<a name="lambda-managed-instances-nodejs-logging"></a>

다중 동시 시스템에서는 로그 인터리브(로그에서 서로 다른 요청의 로그 항목이 인터리브됨)가 정상적인 동작입니다. Lambda 관리형 인스턴스를 사용하는 함수는 항상 [고급 로깅 제어](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)가 도입된 구조화된 JSON 로그 형식을 사용합니다. 이 형식에는 `requestId`가 포함되어 로그 항목을 단일 요청과 연관시킬 수 있습니다. `console` 로거를 사용하면 `requestId`가 각 로그 항목에 자동으로 포함됩니다. 자세한 내용은 [Node.js에서 Lambda 고급 로깅 제어 사용](nodejs-logging.md#node-js-logging-advanced) 항목을 참조하세요.

[Winston](https://github.com/winstonjs/winston)과 같이 많이 사용되는 타사 로깅 라이브러리에는 일반적으로 로그 출력에 콘솔 사용 지원이 포함되어 있습니다.

## 요청 컨텍스트
<a name="lambda-managed-instances-nodejs-request-context"></a>

`context.awsRequestId`를 사용하면 현재 요청의 요청 ID에 대해 비동기식 안전 액세스가 가능합니다.

`context.xRayTraceId`를 사용하여 X-Ray 트레이스 ID에 액세스합니다. 이렇게 하면 현재 요청의 트레이스 ID에 대한 동시성 안전 액세스 권한이 제공됩니다. Lambda는 Lambda 관리형 인스턴스에서 `_X_AMZN_TRACE_ID` 환경 변수를 지원하지 않습니다. AWS SDK를 사용할 때 X-Ray 트레이스 ID가 자동으로 전파됩니다.

`context.getRemainingTimeInMillis()`를 사용하여 제한 시간 초과를 감지합니다. 자세한 정보는 [오류 처리 및 복구](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling)을 참조하세요.

## 초기화 및 종료
<a name="lambda-managed-instances-nodejs-init-shutdown"></a>

함수 초기화는 작업자 스레드당 한 번 발생합니다. 함수가 초기화 도중 로그를 내보내는 경우 반복 로그 항목이 표시될 수 있습니다.

확장이 포함된 Lambda 함수의 경우 실행 환경은 종료 중에 SIGTERM 신호를 내보냅니다. 이 신호는 확장에서 버퍼 비우기와 같은 정리 태스크를 트리거하는 데 사용됩니다. 확장이 포함된 Lambda(기본값) 함수는 `process.on()`을 사용하여 SIGTERM 신호를 구독할 수도 있습니다. `process.on()`은 작업자 스레드에서 사용할 수 없으므로 Lambda 관리형 인스턴스를 사용하는 함수에서는 지원되지 않습니다. 실행 환경 수명 주기에 대한 자세한 내용은 [Lambda 실행 환경 수명 주기 이해](lambda-runtime-environment.md) 섹션을 참조하세요.

## 종속성 버전
<a name="lambda-managed-instances-nodejs-dependencies"></a>

Lambda 관리형 인스턴스에는 다음과 같은 최소 패키지 버전이 필요합니다.
+ AWS SDK for JavaScript v3: 버전 3.933.0 이상
+ AWS X-Ray SDK for Node.js: 버전 3.12.0 이상
+ AWS Distro for OpenTelemetry - Instrumentation for JavaScript: 버전 0.8.0 이상
+ Powertools for AWS Lambda(TypeScript): 버전 2.29.0 이상

## Powertools for AWS Lambda(TypeScript)
<a name="lambda-managed-instances-nodejs-powertools"></a>

Powertools for AWS Lambda(TypeScript)는 Lambda 관리형 인스턴스와 호환되고 로깅, 추적, 지표 등을 위한 유틸리티를 제공합니다. 자세한 내용은 [Powertools for AWS Lambda(TypeScript)](https://github.com/aws-powertools/powertools-lambda-typescript)를 참조하세요.

## 다음 단계
<a name="lambda-managed-instances-nodejs-next-steps"></a>
+ [Lambda 관리형 인스턴스용 Java 런타임](lambda-managed-instances-java-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 Python 런타임](lambda-managed-instances-python-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 .NET 런타임](lambda-managed-instances-dotnet-runtime.md) 검토
+ [Lambda 관리형 인스턴스 규모 조정](lambda-managed-instances-scaling.md) 알아보기

# Lambda 관리형 인스턴스용 Python 런타임
<a name="lambda-managed-instances-python-runtime"></a>

Lambda 런타임은 여러 개의 Python 프로세스를 사용하여 동시 요청을 처리합니다. 각 동시 요청은 자체 메모리 공간 및 초기화를 갖춘 별도의 프로세스로 실행됩니다. 각 프로세스는 한 번에 하나의 요청을 동기식으로 처리합니다. 프로세스는 메모리를 직접 공유하지 않으므로 전역 변수, 모듈 수준 캐시 및 싱글톤 객체는 동시 요청 간에 격리됩니다.

## 동시성 구성
<a name="lambda-managed-instances-python-concurrency-config"></a>

Lambda가 각 실행 환경에 보내는 최대 동시 요청 수는 함수 구성의 `PerExecutionEnvironmentMaxConcurrency` 설정으로 제어됩니다. 이 설정은 선택 사항이며, 기본값은 런타임에 따라 달라집니다. Python 런타임의 경우 기본값은 vCPU당 16개 동시 요청으로, 또는 자체 값을 구성할 수 있습니다. 또한 이 값은 Python 런타임에서 사용하는 프로세스 수를 결정합니다. Lambda는 각 실행 환경의 용량에 따라 구성된 최대 수까지 동시 요청 수를 자동으로 조정하여 이러한 요청을 수용합니다.

**중요**  
프로세스 기반 동시성을 사용하면 각 런타임 작업자 프로세스에서 자체적으로 초기화를 수행합니다. 총 메모리 사용량은 프로세스당 메모리와 동시 프로세스 수를 곱한 값과 같습니다. 대용량 라이브러리 또는 데이터 세트를 로드하고 동시성이 높은 경우 메모리 공간이 커집니다. 워크로드에 따라 사용 가능한 메모리를 초과하지 않도록 CPU-메모리 비율을 조정하거나 더 낮은 동시성 설정을 사용해야 할 수 있습니다. CloudWatch의 `MemoryUtilization` 지표를 사용하여 메모리 사용량을 추적할 수 있습니다.

## 다중 동시성 함수 빌드
<a name="lambda-managed-instances-python-building"></a>

프로세스 기반 다중 동시성 모델로 인해 Python 런타임을 사용하는 Lambda 관리형 인스턴스 함수는 여러 간접 호출에서 동시에 메모리 내 리소스에 액세스하지 않습니다. 메모리 내 동시성 안전을 위한 코딩 방식을 적용할 필요가 없습니다.

## 공유 /tmp 디렉터리
<a name="lambda-managed-instances-python-shared-tmp"></a>

`/tmp` 디렉터리는 실행 환경의 모든 동시 요청에서 공유됩니다. 동일한 파일에 대한 동시 쓰기로 인해 다른 프로세스가 파일을 덮어쓰는 등 데이터가 손상될 수 있습니다. 이를 해결하려면 공유 파일에 대한 파일 잠금을 구현하거나 프로세스 또는 요청별로 고유한 파일 이름을 사용하여 충돌을 방지합니다. 사용 가능한 공간이 소진되지 않도록 불필요한 파일을 정리해야 합니다.

## 로깅
<a name="lambda-managed-instances-python-logging"></a>

다중 동시 시스템에서는 로그 인터리브(로그에서 서로 다른 요청의 로그 항목이 인터리브됨)가 정상적인 동작입니다.

Lambda 관리형 인스턴스를 사용하는 함수는 항상 [고급 로깅 제어](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)가 도입된 구조화된 JSON 로그 형식을 사용합니다. 이 형식에는 `requestId`가 포함되어 로그 항목을 단일 요청과 연관시킬 수 있습니다. Lambda의 Python 표준 라이브러리에서 `logging` 모듈을 사용하면 `requestId`가 각 로그 항목에 자동으로 포함됩니다. 자세한 내용은 [Python에서 Lambda 고급 로깅 제어 사용](https://docs.aws.amazon.com/lambda/latest/dg/python-logging.html#python-logging-advanced)을 참조하세요.

## 요청 컨텍스트
<a name="lambda-managed-instances-python-request-context"></a>

`context.aws_request_id`를 사용하면 현재 요청의 요청 ID에 액세스할 수 있습니다.

Python 런타임을 사용하는 경우 `_X_AMZN_TRACE_ID` 환경 변수를 사용하여 Lambda 관리형 인스턴스에서 X-Ray 트레이스 ID에 액세스할 수 있습니다. AWS SDK를 사용할 때 X-Ray 트레이스 ID가 자동으로 전파됩니다.

`context.get_remaining_time_in_millis()`를 사용하여 제한 시간 초과를 감지합니다. 자세한 정보는 [오류 처리 및 복구](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling)을 참조하세요.

## 초기화 및 종료
<a name="lambda-managed-instances-python-init-shutdown"></a>

함수 초기화는 프로세스당 한 번 발생합니다. 함수가 초기화 도중 로그를 내보내는 경우 반복 로그 항목이 표시될 수 있습니다.

확장이 포함된 Lambda 함수의 경우 실행 환경은 종료 중에 SIGTERM 신호를 내보냅니다. 이 신호는 확장에서 버퍼 비우기와 같은 정리 태스크를 트리거하는 데 사용됩니다. SIGTERM 이벤트를 구독하여 데이터베이스 연결 종료와 같은 함수 정리 태스크를 트리거할 수 있습니다. 실행 환경 수명 주기에 대한 자세한 내용은 [Lambda 실행 환경 수명 주기 이해](lambda-runtime-environment.md) 섹션을 참조하세요.

## 종속성 버전
<a name="lambda-managed-instances-python-dependencies"></a>

Lambda 관리형 인스턴스에는 다음과 같은 최소 패키지 버전이 필요합니다.
+ Powertools for AWS Lambda(Python): 버전 3.23.0 이상

## Powertools for AWS Lambda(Python)
<a name="lambda-managed-instances-python-powertools"></a>

Powertools for AWS Lambda(Python)는 Lambda 관리형 인스턴스와 호환되고 로깅, 추적, 지표 등을 위한 유틸리티를 제공합니다. 자세한 내용은 [Powertools for AWS Lambda(Python)](https://github.com/aws-powertools/powertools-lambda-python)를 참조하세요.

## 다음 단계
<a name="lambda-managed-instances-python-next-steps"></a>
+ [Lambda 관리형 인스턴스용 Java 런타임](lambda-managed-instances-java-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 Node.js 런타임](lambda-managed-instances-nodejs-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 .NET 런타임](lambda-managed-instances-dotnet-runtime.md) 검토
+ [Lambda 관리형 인스턴스 규모 조정](lambda-managed-instances-scaling.md) 알아보기

# Lambda 관리형 인스턴스용 .NET 런타임
<a name="lambda-managed-instances-dotnet-runtime"></a>

.NET 런타임의 경우 Lambda 관리형 인스턴스는 실행 환경당 단일 .NET 프로세스를 사용합니다. 여러 동시 요청은 .NET 태스크를 사용하여 처리됩니다.

## 동시성 구성
<a name="lambda-managed-instances-dotnet-concurrency-config"></a>

Lambda가 각 실행 환경에 보내는 최대 동시 요청 수는 함수 구성의 `PerExecutionEnvironmentMaxConcurrency` 설정으로 제어됩니다. 이 설정은 선택 사항이며, 기본값은 런타임에 따라 달라집니다. .NET 런타임의 경우 기본값은 vCPU당 32개 동시 요청으로, 또는 자체 값을 구성할 수 있습니다. Lambda는 각 실행 환경의 용량에 따라 구성된 최대 수까지 동시 요청 수를 자동으로 조정하여 이러한 요청을 수용합니다.

## 다중 동시성 함수 빌드
<a name="lambda-managed-instances-dotnet-building"></a>

Lambda 관리형 인스턴스를 사용할 때는 다른 다중 동시성 환경에서와 동일한 동시성 안전 관행을 적용해야 합니다. 핸들러 객체는 모든 태스크에서 공유되므로 변경 가능한 상태는 스레드 안전 상태여야 합니다. 여기에는 컬렉션, 데이터베이스 연결 및 요청 처리 도중 수정된 모든 정적 객체가 포함됩니다.

AWS SDK 클라이언트는 스레드 안전 상태이기에 별도의 처리가 필요하지 않습니다.

**예제: 데이터베이스 연결 풀**

다음 코드는 동시 요청 간에 공유되는 정적 데이터베이스 연결 객체를 사용합니다. `SqlConnection` 객체는 스레드 안전 상태가 아닙니다.

```
public class DBQueryHandler
{
    // Single connection shared across threads - NOT SAFE
    private SqlConnection connection;

    public DBQueryHandler()
    {
        connection = new SqlConnection("your-connection-string-here");
        connection.Open();
    }

    public string Handle(object input, ILambdaContext context)
    {
        using var cmd = connection.CreateCommand();
        cmd.CommandText = "SELECT ..."; // your query

        using var reader = cmd.ExecuteReader();

        ...
    }
}
```

이를 해결하려면 연결 풀에서 가져온 각 요청에 대해 별도의 연결을 사용합니다. `Microsoft.Data.SqlClient`와 같은 ADO.NET 공급자는 연결 객체가 열릴 때 연결 풀링을 자동으로 지원합니다.

```
public class DBQueryHandler
{
    public DBQueryHandler()
    {
    }

    public string Handle(object input, ILambdaContext context)
    {
        using var connection = new SqlConnection("your-connection-string-here");
        connection.Open();
        using var cmd = connection.CreateCommand();
        cmd.CommandText = "SELECT ..."; // your query

        using var reader = cmd.ExecuteReader();

        ...
    }
}
```

**예제: 컬렉션**

표준 .NET 컬렉션은 스레드에 있어 안전하지 않습니다.

```
public class Handler
{
    private static List<string> items = new List<string>();
    private static Dictionary<string, object> cache = new Dictionary<string, object>();

    public string FunctionHandler(object input, ILambdaContext context)
    {
        items.Add(context.AwsRequestId);
        cache["key"] = input;

        return "Success";
    }
}
```

동시성 안전을 위해 `System.Collections.Concurrent` 네임스페이스의 컬렉션을 사용합니다.

```
public class Handler
{
    private static ConcurrentBag<string> items = new ConcurrentBag<string>();
    private static ConcurrentDictionary<string, object> cache = new ConcurrentDictionary<string, object>();

    public string FunctionHandler(object input, ILambdaContext context)
    {
        items.Add(context.AwsRequestId);
        cache["key"] = input;

        return "Success";
    }
}
```

## 공유 /tmp 디렉터리
<a name="lambda-managed-instances-dotnet-shared-tmp"></a>

`/tmp` 디렉터리는 실행 환경의 모든 동시 요청에서 공유됩니다. 동일한 파일에 대한 동시 쓰기로 인해 다른 요청이 파일을 덮어쓰는 등 데이터가 손상될 수 있습니다. 이를 해결하려면 공유 파일에 대한 파일 잠금을 구현하거나 요청당 고유한 파일 이름을 사용하여 충돌을 방지합니다. 사용 가능한 공간이 소진되지 않도록 불필요한 파일을 정리해야 합니다.

## 로깅
<a name="lambda-managed-instances-dotnet-logging"></a>

다중 동시 시스템에서는 로그 인터리브(로그에서 서로 다른 요청의 로그 항목이 인터리브됨)가 정상적인 동작입니다. Lambda 관리형 인스턴스를 사용하는 함수는 항상 [고급 로깅 제어](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)가 도입된 구조화된 JSON 로그 형식을 사용합니다. 이 형식에는 `requestId`가 포함되어 로그 항목을 단일 요청과 연관시킬 수 있습니다. `context.Logger` 객체를 사용하여 로그를 생성하면 `requestId`가 각 로그 항목에 자동으로 포함됩니다. 자세한 내용은 [.NET에서 Lambda 고급 로깅 제어 사용](csharp-logging.md#csharp-logging-advanced) 항목을 참조하세요.

## 요청 컨텍스트
<a name="lambda-managed-instances-dotnet-request-context"></a>

`context.AwsRequestId` 속성을 사용하면 현재 요청의 요청 ID에 액세스할 수 있습니다.

`context.TraceId` 속성을 사용하면 X-Ray 트레이스 ID에 액세스할 수 있습니다. 이렇게 하면 현재 요청의 트레이스 ID에 대한 동시성 안전 액세스 권한이 제공됩니다. Lambda는 Lambda 관리형 인스턴스에서 `_X_AMZN_TRACE_ID` 환경 변수를 지원하지 않습니다. AWS SDK를 사용할 때 X-Ray 트레이스 ID가 자동으로 전파됩니다.

`ILambdaContext.RemainingTime`을 사용하여 제한 시간 초과를 감지합니다. 자세한 정보는 [오류 처리 및 복구](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling)을 참조하세요.

## 초기화 및 종료
<a name="lambda-managed-instances-dotnet-init-shutdown"></a>

함수 초기화는 실행 환경당 한 번 발생합니다. 초기화 도중 생성된 객체는 요청 간에 공유됩니다.

확장이 포함된 Lambda 함수의 경우 실행 환경은 종료 중에 SIGTERM 신호를 내보냅니다. 이 신호는 확장에서 버퍼 비우기와 같은 정리 태스크를 트리거하는 데 사용됩니다. SIGTERM 이벤트를 구독하여 데이터베이스 연결 종료와 같은 함수 정리 태스크를 트리거할 수 있습니다. 실행 환경 수명 주기에 대한 자세한 내용은 [Lambda 실행 환경 수명 주기 이해](lambda-runtime-environment.md) 섹션을 참조하세요.

## 종속성 버전
<a name="lambda-managed-instances-dotnet-dependencies"></a>

Lambda 관리형 인스턴스에는 다음과 같은 최소 패키지 버전이 필요합니다.
+ Amazon.Lambda.Core: 버전 2.7.1 이상
+ Amazon.Lambda.RuntimeSupport: 버전 1.14.1 이상
+ OpenTelemetry.Instrumentation.AWSLambda: 버전 1.14.0 이상
+ AWSXRayRecorder.Core: 버전 2.16.0 이상
+ AWSSDK.Core: 버전 4.0.0.32 이상

## Powertools for AWS Lambda(.NET)
<a name="lambda-managed-instances-dotnet-powertools"></a>

[Powertools for AWS Lambda(.NET)](https://docs.aws.amazon.com/powertools/dotnet/) 및 [AWS Distro for OpenTelemetry - Instrumentation for DotNet](https://github.com/aws-observability/aws-otel-dotnet-instrumentation)은 현재 Lambda 관리형 인스턴스를 지원하지 않습니다.

## 다음 단계
<a name="lambda-managed-instances-dotnet-next-steps"></a>
+ [Lambda 관리형 인스턴스용 Java 런타임](lambda-managed-instances-java-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 Node.js 런타임](lambda-managed-instances-nodejs-runtime.md) 검토
+ [Lambda 관리형 인스턴스용 Python 런타임](lambda-managed-instances-python-runtime.md) 검토
+ [Lambda 관리형 인스턴스 규모 조정](lambda-managed-instances-scaling.md) 알아보기

# Lambda 관리형 인스턴스에 대한 Rust 지원
<a name="lambda-managed-instances-rust"></a>

## 동시성 구성
<a name="lambda-managed-instances-rust-concurrency-config"></a>

Lambda가 각 실행 환경에 보내는 최대 동시 요청 수는 함수 구성의 `PerExecutionEnvironmentMaxConcurrency` 설정으로 제어됩니다. 이 설정은 선택 사항이며, Rust의 기본값은 vCPU당 동시 요청 8개이고, 자체 값을 구성할 수 있습니다. 이 값은 런타임에서 생성된 Tokio 태스크 수를 결정하며 실행 환경의 수명 동안 변하지 않습니다. 각 작업자는 작업자당 멀티플렉싱 없이 한 번에 정확히 하나의 진행 중인 요청을 처리합니다. Lambda는 각 실행 환경의 용량에 따라 구성된 최대 수까지 동시 요청 수를 자동으로 조정하여 이러한 요청을 수용합니다.

## 다중 동시성 함수 빌드
<a name="lambda-managed-instances-rust-building"></a>

Lambda 관리형 인스턴스를 사용할 때는 다른 다중 스레드 환경에서와 동일한 스레드 안전 관행을 적용해야 합니다. 핸들러 객체는 모든 작업자 스레드에서 공유되므로 변경 가능한 상태는 스레드 안전 상태여야 합니다. 여기에는 컬렉션, 데이터베이스 연결 및 요청 처리 도중 수정된 모든 정적 객체가 포함됩니다.

동시 요청 처리를 활성화하려면 `Cargo.toml` 파일에 `concurrency-tokio` 특성 플래그를 추가합니다.

```
[dependencies]  
lambda_runtime = { version = "1", features = ["concurrency-tokio"] }
```

`lambda_runtime::run_concurrent(…)` 진입점은 Tokio 런타임 내에서 직접적으로 호출되어야 하며, 일반적으로 기본 함수의 `#[tokio::main]` 속성에서 제공됩니다. 핸들러 종료에서는 [https://doc.rust-lang.org/std/clone/trait.Clone.html](https://doc.rust-lang.org/std/clone/trait.Clone.html) \$1 [https://doc.rust-lang.org/std/marker/trait.Send.html](https://doc.rust-lang.org/std/marker/trait.Send.html)를 구현해야 합니다. 그러면 프레임워크가 여러 비동기식 태스크에서 핸들러를 안전하게 공유할 수 있습니다. 이러한 경계가 충족되지 않으면 코드가 컴파일되지 않습니다.

간접 호출(데이터베이스 풀, 구성 구조) 간에 공유된 상태가 필요하면 [https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html)로 래핑하고 각 간접 호출에 `Arc`를 복제합니다.

모든 AWS SDK for Rust 클라이언트는 동시성에 안전하며 특별한 처리가 필요하지 않습니다.

### 예: AWS SDK 클라이언트
<a name="lambda-managed-instances-rust-example-sdk"></a>

다음 예제에서는 S3 클라이언트를 사용하여 간접 호출마다 객체를 업로드합니다. 클라이언트는 `Arc` 없이 종료에 직접 복제됩니다.

```
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;  
let s3_client = aws_sdk_s3::Client::new(&config);  
  
run_concurrent(service_fn(move |event: LambdaEvent<Request>| {  
    let s3_client = s3_client.clone(); // cheap clone, no Arc needed  
    async move {  
        s3_client.put_object()  
            .bucket(&event.payload.bucket)  
            .key(&event.payload.key)  
            .body(event.payload.body.into_bytes().into())  
            .send()  
            .await?;  
        Ok(Response { message: "uploaded".into() })  
    }  
}))  
.await
```

### 예제: 데이터베이스 연결 풀
<a name="lambda-managed-instances-rust-example-db"></a>

핸들러에서 클라이언트 및 구성과 같은 공유된 상태에 액세스해야 한다면 [https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html)로 래핑하고 각 간접 호출에 `Arc`를 복제합니다.

```
#[derive(Debug)]  
struct AppState {  
    dynamodb_client: DynamoDbClient,  
    table_name: String,  
    cache_ttl: Duration,  
}  
  
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;  
let state = Arc::new(AppState {  
    dynamodb_client: DynamoDbClient::new(&config),  
    table_name: std::env::var("TABLE_NAME").expect("TABLE_NAME must be set"),  
    cache_ttl: Duration::from_secs(300),  
});  
  
run_concurrent(service_fn(move |event: LambdaEvent<Request>| {  
    let state = state.clone();  
    async move { handle(event, state).await }  
}))  
.await
```

## 공유 /tmp 디렉터리
<a name="lambda-managed-instances-rust-tmp"></a>

`/tmp` 디렉터리는 동일한 실행 환경의 모든 동시 간접 호출에서 공유됩니다. 간접 호출당 고유한 파일 이름을 사용하거나(예: 요청 ID 포함) 명시적 파일 잠금을 구현하여 데이터 손상을 방지합니다.

## 로깅
<a name="lambda-managed-instances-rust-logging"></a>

다중 동시 시스템에서는 로그 인터리브(로그에서 서로 다른 요청의 로그 항목이 인터리브됨)가 정상적인 동작입니다. Lambda 관리형 인스턴스를 사용하는 함수에서는 Lambda의 [고급 로깅 제어](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)를 통해 구조화된 JSON 로그 형식을 지원합니다. 이 형식에는 `requestId`가 포함되어 로그 항목을 단일 요청과 연관시킬 수 있습니다. 자세한 내용은 [Tracing 크레이트를 사용한 고급 로깅 구현](rust-logging.md#rust-logging-tracing) 항목을 참조하세요.

## 요청 컨텍스트
<a name="lambda-managed-instances-rust-context"></a>

`Context` 객체는 각 핸들러 간접 호출에 직접 전달됩니다. `event.context.request_id`를 사용하여 현재 요청의 요청 ID에 액세스합니다.

`event.context.xray_trace_id`를 사용하여 X-Ray 트레이스 ID에 액세스합니다. Lambda는 Lambda 관리형 인스턴스에서 `_X_AMZN_TRACE_ID` 환경 변수를 지원하지 않습니다. AWS SDK for Rust를 사용할 때 X-Ray 트레이스 ID가 자동으로 전파됩니다.

`event.context.deadline`를 사용하여 제한 시간을 탐지합니다. 밀리초 단위의 간접 호출 기한이 있습니다.

## 초기화 및 종료
<a name="lambda-managed-instances-rust-lifecycle"></a>

함수 초기화는 실행 환경당 한 번 발생합니다. 초기화 도중 생성된 객체는 요청 간에 공유됩니다.

확장이 포함된 Lambda 함수의 경우 실행 환경은 종료 중에 SIGTERM 신호를 내보냅니다. 이 신호는 확장에서 버퍼 비우기와 같은 정리 태스크를 트리거하는 데 사용됩니다. `lambda_runtime`에서는 정상 종료 신호 처리 구성을 단순화하는 도우미를 제공합니다([https://docs.rs/lambda_runtime/latest/lambda_runtime/fn.spawn_graceful_shutdown_handler.html](https://docs.rs/lambda_runtime/latest/lambda_runtime/fn.spawn_graceful_shutdown_handler.html)). 실행 환경 수명 주기에 대한 자세한 내용은 [Lambda 실행 환경 수명 주기 이해](lambda-runtime-environment.md) 섹션을 참조하세요.

## 종속성 버전
<a name="lambda-managed-instances-rust-dependencies"></a>

Lambda 관리형 인스턴스에는 다음과 같은 최소 패키지 버전이 필요합니다.
+ `lambda_runtime`: `concurrency-tokio` 특성이 활성화된 버전 1.1.1 이상
+ 지원되는 최소 Rust 버전(MSRV)은 1.84.0입니다.