AWS Lambda Force закрывает соединение? - PullRequest
1 голос
/ 17 марта 2020

У меня работает API на AWS Lambda через API-шлюз, и я получаю очень небольшое количество пользователей, которые неожиданно получают запросы, отбрасываемые назад как connection forcibly closed by remote host, что вызывает проблемы в программе. За месяц или около того ничего не изменилось на стороне сервера, но они только начали появляться. Как уже упоминалось, он не отображается для всех, только для небольшого числа пользователей, но, основываясь на трассировке стека, он выглядит на стороне сервера, если я не интерпретирую его неправильно. Вот пример стека ошибок от пользователя (с отметкой времени как из файла журнала):

2020-03-17 10:12:25,521 (2020-03-17 14:12:25,521 UTC) [23] ERROR RDES.License.Core.Services.Implementation.LicenseValidatorApi - General exception from startup authentication, loop 0
RdRestConsumer.Exceptions.ApiGeneralException: Revolution Design API responded with status code:  :  ---> Flurl.Http.FlurlHttpException: Call failed. An error occurred while sending the request. POST https://*apiUrl*/auth/refresh ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   --- End of inner exception stack trace ---
   at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
   at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
   at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Flurl.Http.FlurlRequest.<SendAsync>d__19.MoveNext()
   --- End of inner exception stack trace ---
   at Flurl.Http.FlurlRequest.<HandleExceptionAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Flurl.Http.FlurlRequest.<SendAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Flurl.Http.FlurlRequest.<SendAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Flurl.Http.HttpResponseMessageExtensions.<ReceiveJson>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at RdRestConsumer.Services.Implementation.AuthService.<RefreshAccessTokenAsync>d__22.MoveNext()
   --- End of inner exception stack trace ---
   at RdRestConsumer.Services.Implementation.AuthService.<RefreshAccessTokenAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at RdRestConsumer.Services.Implementation.AuthService.<AttemptStartupAuthenticationAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at RDES.License.Core.Services.Implementation.LicenseValidatorApi.<AttemptStartupAuthenticationAsync>d__50.MoveNext()

Тесты, которые мы сделали и что исключили:

  1. Timeout (Тайм-аут). Если посмотреть на время в файлах журнала, время между началом запроса и получением этой ошибки составляет примерно 1-2 секунды (примерно), а время ожидания для Lambda и API-шлюза установлено на 30 секунд, поэтому времени для этого недостаточно. timeout.
  2. Память - я прочитал в SO сообщении (извините, у меня нет ссылки, когда я закрывал ее), что закрытые соединения могут быть вызваны проблемами с ресурсами. Я не вижу, где запросы достигли предела памяти, но я все равно увеличил объем памяти с 512 до 768 для тестирования, но, насколько я могу судить, это никак не отразилось.

Кто-нибудь знает, что будет вызывает эту проблему?

1 Ответ

2 голосов
/ 18 марта 2020

Несколько мыслей по этому поводу, так как я думаю, что ответ может быть многогранным.

Я прочитал, что обеспечение того, что соединения являются TLSv1.2, может уменьшить возникновение проблемы сброса соединения этого типа.

Вы можете принудительно использовать TLS 1.2 на стороне сервера, настроив ваш API-шлюз, который будет использоваться вместе с именем пользовательского домена API-шлюза или иметь трафик c, перенаправленный через дистрибутив Cloudfront. И пользовательские доменные имена, и Cloudfront позволяют включать только TLSv1.2.

Если вы управляете клиентским кодом, вы также можете убедиться, что они настроены на использование TLSv1.2.

Вверху из-за этого при работе с сетевым трафиком c всегда происходят сбои в сети, и для клиентского кода лучше всего использовать логи повторных попыток c с добавочным откатом на месте, чтобы все происходило автоматически.

Мы использовали другой стек технологий поддержки, но столкнулись с похожими проблемами, когда наша клиентская база выросла, и мы начали получать больше трафика c. Мы контролировали наш клиентский код, поэтому добавили туда логи повторных попыток c, которые сделали наших клиентов намного более надежными. Вот сообщение в блоге AWS о том, что это хорошо читать на топи c: https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/

...