При вызове AWSLambdaClient возникла исключительная ситуация: com.amazonaws.SdkClientException: невозможно выполнить запрос HTTP: целевой сервер не смог ответить - PullRequest
0 голосов
/ 10 января 2019

У меня есть существующая лямбда-функция aws, и я пытаюсь вызвать ее с помощью AWSLambdaClient (библиотека: aws-java-sdk-lambda) . Я получаю ответ, если время выполнения для лямбды меньше 5 минут. Но если время работы лямбды больше 5 минут, я получаю исключение:

com.amazonaws.SdkClientException: Unable to execute HTTP request: The target server failed to respond

Какая конфигурация мне не хватает при настройке лямбда-клиента?

Полная трассировка стека:

Exception in thread "main" com.amazonaws.SdkClientException: Unable to execute HTTP request: The target server failed to respond
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1163)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1109)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:758)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:732)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:714)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:674)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:656)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:520)
at com.amazonaws.services.lambda.AWSLambdaClient.doInvoke(AWSLambdaClient.java:3154)
at com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:3121)
at com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:3110)
at com.amazonaws.services.lambda.AWSLambdaClient.executeInvoke(AWSLambdaClient.java:1735)
at com.amazonaws.services.lambda.AWSLambdaClient.invoke(AWSLambdaClient.java:1707)
at LambdaTest.main(LambdaTest.java:48)
Caused by: org.apache.http.NoHttpResponseException: The target server failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
at com.amazonaws.http.protocol.SdkHttpRequestExecutor.doReceiveResponse(SdkHttpRequestExecutor.java:82)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at com.amazonaws.http.apache.client.impl.SdkHttpClient.execute(SdkHttpClient.java:72)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1285)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1101)
... 12 more

Я уже увеличил максимальное время ожидания лямбды до 15 минут на лямбда-консоли aws . Также я внес изменения в код и установил ClientExecutionTimeout, ConnectionTimeout, RequestTimeout и SocketTimeout на 15 минут (900 секунд) в конфигурации AWSLambdaClient.

ClientConfiguration configuration = new ClientConfiguration()
            .withMaxErrorRetry(0)
            // These is measured in milliseconds.
            .withClientExecutionTimeout(900 * 1000)
            .withConnectionTimeout(900 * 1000)
            .withRequestTimeout(900 * 1000)
            .withSocketTimeout(900 * 1000);
AWSLambda lambdaClient = AWSLambdaClientBuilder
            .standard()
            .withRegion(region)
            .withClientConfiguration(configuration)
            .withCredentials(new AWSStaticCredentialsProvider(creds)).build();
InvokeRequest request = new InvokeRequest()
            .withFunctionName(functionName)
            .withInvocationType(InvocationType.RequestResponse)
            .withLogType(LogType.Tail);
InvokeResult result = lambdaClient.invoke(request);
String responseLog = new String(Base64.getDecoder().decode(result.getLogResult()), StandardCharsets.UTF_8);
System.out.println(responseLog);

Я использую Apache HttpClient: 4.5.5

Я видел вопрос https://stackoverflow.com/a/44703601/9669982 Я также пробовал некоторые конфигурации:

configuration.setValidateAfterInactivityMillis(900 * 1000);

Также, чтобы попробовать больше, я также использовал:

configuration.setConnectionMaxIdleMillis(900*1000);
configuration.setUseTcpKeepAlive(true);

Но не повезло.

В AWS Cloudwatch я вижу, что моя лямбда-функция работает нормально и полное задание выполнено, и в cloudwatch не было никаких следов каких-либо ошибок, но я получаю указанное выше исключение.

Я не могу получить то, что мне не хватает.

1 Ответ

0 голосов
/ 10 января 2019

Как вы уже знаете, проблема

Я получаю ответ, если время выполнения для лямбды меньше 5 минут. Но если время лямбды больше 5 минут, я получаю исключение:

Ваши соединения, которые поддерживаются диспетчером соединений, становятся устаревшими. То есть целевой сервер завершает соединение на своем конце, и HttpClient не может реагировать на это событие.

Вам необходимо добавить setHttpRequestRetryHandler для вашего HTTP-клиента, как и отвечено в следующей ссылке.

...