

# 排查 Lambda 托管实例问题
<a name="lambda-managed-instances-troubleshooting"></a>

## 节流和扩缩问题
<a name="lambda-managed-instances-ts-throttling"></a>

### 纵向扩展过程中错误率高
<a name="lambda-managed-instances-ts-high-error-rates"></a>

**问题：**当流量迅速增加时，您会遇到节流错误（HTTP 429）。

**原因：**Lambda 托管实例根据 CPU 资源利用率和多并发饱和状态进行异步扩展。如果您的流量在 5 分钟内增长超过一倍，您可能会在 Lambda 纵向扩展实例和执行环境以满足需求时看到节流出现。

**解决方案：**
+ **调整目标资源利用率：**如果您的工作负载具有可预测的流量模式，则应设定较低的目标资源利用率，以便为流量突发留出更多的缓冲空间。
+ **预热容量：**对于计划中的流量增加，请通过较长时间的逐步增加来实现流量的提升，以使扩展保持同步。
+ **监控扩展指标：**跟踪节流错误指标，以了解节流和容量扩展问题的原因。
+ **查看函数配置：**确保您的函数内存和 vCPU 设置支持多并发执行。如果需要，请增加函数内存或 vCPU 分配。

### 减慢缩减
<a name="lambda-managed-instances-ts-slow-scale-down"></a>

**问题：**流量减少后，实例的缩减过程会持续很长时间。

**原因：**Lambda 托管实例会逐渐缩减，以保持可用性并避免可能影响性能的快速容量变化。

**解决方案：**

这是预料之中的行为。Lambda 会谨慎地缩减实例，以确保稳定性。监控您的 CloudWatch 指标，以跟踪正在运行的实例数量。

## 并发问题
<a name="lambda-managed-instances-ts-concurrency"></a>

### 具有低并发性的执行环境会出现节流情况
<a name="lambda-managed-instances-ts-low-concurrency-throttles"></a>

**问题：**尽管有可用容量，但您的函数仍会出现节流情况。

**原因：**具有极低最大并发量的执行环境可能难以实现有效扩展。Lambda 托管实例专为多并发应用程序而设计。

**解决方案：**
+ **提高最大并发数：**如果您的函数调用所占用的 CPU 极少，可提高最大并发数设置至最高每个 vCPU 64 个。
+ **优化函数代码：**查看您的函数代码，以降低每次调用时的 CPU 使用量，从而实现更高的并发性。
+ **调整函数内存和 vCPU：**确保您的函数具备足够的资源来处理多个并发调用。

### 线程安全问题（Java 运行时）
<a name="lambda-managed-instances-ts-thread-safety-java"></a>

**问题：**您的 Java 函数生成错误的结果或在负载下遭遇竞争条件。

**原因：**多个线程同时执行处理程序方法，且共享状态不具有线程安全性。

**解决方案：**
+ 使用 `AtomicInteger` 或 `AtomicLong` 替代基元类型作为计数器
+ 将 `HashMap` 替换为 `ConcurrentHashMap`
+ 使用 `Collections.synchronizedList()` 来包装 `ArrayList`
+ 将 `ThreadLocal` 用于特定于请求的状态
+ 从 Lambda 上下文对象访问跟踪 ID，而不是环境变量

有关详细指导，请参阅 [Lambda 托管实例的 Java 运行时](lambda-managed-instances-java-runtime.md)文档。

### 状态隔离问题（Node.js 运行时）
<a name="lambda-managed-instances-ts-state-isolation-nodejs"></a>

**问题：**您的 Node.js 函数会从不同的请求中返回数据，或者会出现数据损坏的情况。

**原因：**全局变量在同一工作线程的并发调用中被共享。当异步操作释放控制权时，其他调用可以修改共享状态。

**解决方案：**
+ 安装并将 `@aws/lambda-invoke-store` 用于所有特定于请求的状态
+ 将全局变量替换为 `InvokeStore.set()` 和 `InvokeStore.get()`
+ 在 `/tmp` 中使用带有请求 ID 的唯一文件名
+ 使用 `InvokeStore.getXRayTraceId()` 访问跟踪 ID，而不是环境变量

有关详细指导，请参阅 [Lambda 托管实例的 Node.js 运行时](lambda-managed-instances-nodejs-runtime.md)文档。

### 文件冲突（Python 运行时）
<a name="lambda-managed-instances-ts-file-conflicts-python"></a>

**问题：**您的 Python 函数从 `/tmp` 中的文件中读取了错误的数据。

**原因：**多个进程共享 `/tmp` 目录。对同一文件进行并发写入操作可能会导致数据损坏。

**解决方案：**
+ 使用带有请求 ID 的唯一文件名：`/tmp/request_{context.request_id}.txt`
+ 将文件锁定与 `fcntl.flock()` 结合用于共享文件
+ 在使用后通过 `os.remove()` 清理临时文件

有关详细指导，请参阅 [Lambda 托管实例的 Python 运行时](lambda-managed-instances-python-runtime.md)文档。

## 性能问题
<a name="lambda-managed-instances-ts-performance"></a>

### 高内存利用率
<a name="lambda-managed-instances-ts-high-memory"></a>

**问题：**您的函数出现内存使用率过高或内存不足的问题。

**原因：**Python 中的每个并发请求都在单独的进程中运行，且拥有自己的内存空间。总内存使用量等于每个进程的内存占用量乘以并发进程数量。

**解决方案：**
+ 在 CloudWatch 中监控 `MemoryUtilization` 指标
+ 如果内存使用量接近函数的内存限制，请降低 `MaxConcurrency` 设置
+ 增加函数内存分配以支持更高的并发数
+ 通过按需加载数据而非在初始化时加载来优化内存使用情况

### 不一致的性能
<a name="lambda-managed-instances-ts-inconsistent-performance"></a>

**问题：**函数性能在不同的调用之间差异很大。

**原因：**Lambda 可能会根据可用性选择不同的实例类型，或者某些函数可能运行在资源可用性各不相同的实例上。

**解决方案：**
+ **指定允许的实例类型：**如果您有特定的性能要求，请在容量提供程序中配置允许的实例类型，以限制 Lambda 可选择的实例类型。
+ **监控实例级别的指标：**在容量提供程序级别进行跟踪 `CPUUtilization` 和 `MemoryUtilization` 以确定资源限制。
+ **查看容量指标：**检查 `vCPUAvailable` 和 `MemoryAvailable` 以确保您的实例上有足够的可用资源。

## 容量提供程序问题
<a name="lambda-managed-instances-ts-capacity-provider"></a>

### 函数版本未能变为 ACTIVE 状态
<a name="lambda-managed-instances-ts-function-not-active"></a>

**问题：**您的函数版本发布后仍处于待处理状态。

**原因：**Lambda 正在启动托管实例并开启执行环境。此过程需要时间，特别是对于新容量提供程序上的第一个函数版本。

**解决方案：**

等待 Lambda 完成初始化过程。默认情况下，Lambda 会启动三个实例以实现可用区的容错功能，并在将您的函数版本标记为 ACTIVE 之前启动三个执行环境。这通常需要几分钟时间。

### 无法删除容量提供程序
<a name="lambda-managed-instances-ts-cannot-delete"></a>

**问题：**您在尝试删除容量提供程序时收到错误。

**原因：**您无法删除已附加了函数版本的容量提供程序。

**解决方案：**

1. 使用 `ListFunctionVersionsByCapacityProvider` API 识别所有使用该容量提供程序的函数版本。

1. 删除或更新这些函数版本，以解除容量提供程序的关联。

1. 重新尝试删除容量提供程序。

### 发布函数过程中出现的一般错误消息
<a name="lambda-managed-instances-ts-generic-errors"></a>

**问题：**发布函数时，您会遇到一般错误消息，例如“发布期间出现内部错误”。

**解决方案：**
+ **检查 IAM 权限：**确保您对尝试使用的容量提供程序拥有 `lambda:PassCapacityProvider` 权限。
+ **验证容量提供程序配置：**使用 `GetCapacityProvider` API 确认您的容量提供程序处于 ACTIVE 状态。
+ **查看 VPC 配置：**确保您的容量提供程序中指定的子网和安全组配置正确且可访问。
+ **检查 Amazon CloudTrail 日志：**查看 CloudTrail 日志，了解有关失败操作的详细错误信息。

## 监控和可观测性问题
<a name="lambda-managed-instances-ts-monitoring"></a>

### CloudWatch 指标缺失
<a name="lambda-managed-instances-ts-missing-metrics"></a>

**问题：**您在 CloudWatch 中无法看到您的容量提供程序或函数所对应的预期指标。

**原因：**这些指标每隔 5 分钟发布一次。新的容量提供程序或函数可能无法立即提供指标。

**解决方案：**

发布函数版本后，至少等待 5 到 10 分钟，然后才能期望在 CloudWatch 中看到相关指标。请确认您查看的命名空间（`AWS/Lambda`）和维度（`CapacityProviderName`、`FunctionName` 或 `InstanceType`）是否正确。

### 找不到 CloudWatch 日志
<a name="lambda-managed-instances-ts-no-logs"></a>

**问题：**您的函数成功执行，但在 CloudWatch Logs 中找不到相关日志。

**原因：**Lambda 托管实例在您的 VPC 中运行，需要网络连接才能将日志发送至 CloudWatch Logs。如果没有正确的 VPC 连接配置，您的函数将无法连接到 CloudWatch Logs 服务端点。

**解决方案：**

配置 VPC 连接来让您的函数将日志发送到 CloudWatch Logs。您有三种选择：

**选项 1：CloudWatch Logs 的 VPC 端点（建议用于生产环境）**

1. 通过 [console.aws.amazon.com/vpc/](https://console.amazonaws.cn/vpc/) 打开 Amazon VPC 控制台。

1. 在导航窗格中，选择**端点**。

1. 选择 **创建端点**。

1. 对于**服务类别**，选择 **Amazon 服务**。

1. 在**服务名称**中，选择 `com.amazonaws.region.logs`（将 `region` 替换为您的 Amazon 区域）。

1. 对于 **VPC**，请选择您的容量提供程序使用的 VPC。

1. 对于**子网**，选择要在其中创建端点网络接口的子网。要获得高可用性，在多个可用区中选择子网。

1. 对于**安全组**，请选择允许来自您函数安全组的入站 HTTPS 流量（端口 443）的安全组。

1. 为端点启用**私有 DNS**。

1. 选择**创建端点**。

**选项 2：带有互联网网关的公有子网**

如果您的容量提供程序使用公有子网，请确保：

1. 互联网网关已连接到您的 VPC

1. 路由表将 `0.0.0.0/0` 流量路由到互联网网关

1. 安全组允许端口 443 上的出站 HTTPS 流量

**选项 3：具有 NAT 网关的私有子网**

如果您的容量提供程序使用私有子网，请确保：

1. 公有子网中存在 NAT 网关

1. 私有子网路由表将 `0.0.0.0/0` 流量路由到 NAT 网关

1. 公有子网路由表将 `0.0.0.0/0` 流量路由到互联网网关

1. 安全组允许端口 443 上的出站 HTTPS 流量

有关 VPC 连接选项的详细指南，请参阅 [Lambda 托管实例的 VPC 连接](lambda-managed-instances-networking.md)。

### 难以将来自并发请求的日志进行关联
<a name="lambda-managed-instances-ts-log-correlation"></a>

**问题：**来自不同请求的日志是交错排列的，这使得难以跟踪具体的单个请求。

**原因：**在多并发系统中，日志的交错排列是预期且标准的行为。

**解决方案：**
+ **使用采用 JSON 格式的结构化日志记录：**在所有日志语句中包含请求 ID
+ **Java：**将 Log4j 与 `ThreadContext` 配合使用以自动包含请求 ID
+ **Node.js：**使用采用 JSON 格式的 `console.log()` 并包含 `InvokeStore.getRequestId()`
+ **Python：**使用采用 JSON 格式的标准日志记录模块并包含 `context.request_id`

有关详细指导，请参阅特定于运行时的文档页面。

## 获得更多帮助
<a name="lambda-managed-instances-ts-getting-help"></a>

如果您在尝试这些解决方案后仍然遇到问题：

1. **查看 CloudWatch 指标：**检查容量提供程序和执行环境指标，以确定资源限制或扩展问题。

1. **检查 Amazon CloudTrail 日志：**查看 CloudTrail 日志，了解有关 API 调用和错误的详细错误信息。

1. **联系 Amazon Support：**如果您无法解决问题，请联系 Amazon Support，提供有关您的容量提供程序配置、函数配置以及您遇到的具体错误消息的详细信息。

## 后续步骤
<a name="lambda-managed-instances-ts-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 了解 [Lambda 托管实例的扩展](lambda-managed-instances-scaling.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南
+ 使用 [CloudWatch 指标](lambda-managed-instances-monitoring.md)监控 Lambda 托管实例
+ 查看 [Lambda 托管实例的最佳实践](lambda-managed-instances-best-practices.md)