当请求较多时,在 lambda 函数内调用 API 会失败

问题描述 投票:0回答:1

在文档上传过程中,有一个API端点用于更新数据库。该端点通过 Aws API 网关公开,并且已指向 AWS SQS 来处理请求。该队列触发 lambda 函数并调用 API 方法来更新 lambda 内的数据库。当存在大量请求时(15-20 个文档上传请求),lambda 函数会失败并抛出“响应状态代码不指示成功:400”(400 错误)。当请求数量较少时,它可以正常工作。会是什么原因呢?

Lambda 代码。

 public async Task FunctionHandler(SQSEvent evnt, ILambdaContext context)
    {
        try
        {
            HttpClient client = new();

            foreach (var message in evnt.Records)
            {
                await ProcessMessageAsync(message, context, client);
            }
        }
        catch (Exception ex)
        {
            throw new UploaderException(ex.Message);
        }
    }

//Private method
private async Task ProcessMessageAsync(SQSEvent.SQSMessage message, ILambdaContext context, HttpClient client) {
 
        string item = string.Empty;
        string methodName = string.Empty;
        string httpMethod = string.Empty;

        foreach (var attribute in message.MessageAttributes)
        {
            if (attribute.Key.ToLower() == "item")
            {
                item = attribute.Value.StringValue;
            }
            if (attribute.Key.ToLower() == "methodname")
            {
                methodName = attribute.Value.StringValue;
            }
            if (attribute.Key.ToLower() == "httpmethod")
            {
                httpMethod = attribute.Value.StringValue;
            }

            if (attribute.Key.ToLower() != "methodname" || attribute.Key.ToLower() != "httpmethod")
            {
                client.DefaultRequestHeaders.Add(attribute.Key, attribute.Value.StringValue);
            }
        }

        if (string.IsNullOrWhiteSpace(item))
        {
            throw new UploaderException("Could not find item");
        }

        string baseUrl = Environment.GetEnvironmentVariable(item.ToUpper());
        var content = new StringContent(message.Body, System.Text.Encoding.UTF8, "application/json");

        context.Logger.LogLine($"URL: {baseUrl}{methodName}");

        HttpResponseMessage response;
        if (httpMethod.ToUpper() == "POST")
        {
            response = await client.PostAsync($"{baseUrl}{methodName}", content);
        }
        else
        {
            response = await client.PutAsync($"{baseUrl}{methodName}", content);
        }
        
        response.EnsureSuccessStatusCode();
        context.Logger.LogLine("Document upload success");

        await Task.CompletedTask;
 }

.net amazon-web-services aws-lambda amazon-sqs
1个回答
0
投票

有许多不同的进程同时修改同一个客户端 (client.DefaultRequestHeaders.Add(..)) - 这可能是一个问题。

我建议为每个消息/HTTP 请求创建一个单独的标头对象,并且根本不依赖默认标头(除非它们在所有请求中共享)。

© www.soinside.com 2019 - 2024. All rights reserved.