Рубрики
Без рубрики

Экспоненциальный откат для AWS Lambda

Недавно я настроил лямбда-функцию, которая считывает данные из очереди SQS и выполняет вызов API для one o… Помеченный как aws, java, бессерверный.

Недавно я настроил лямбда-функцию, которая считывает данные из очереди SQS и выполняет вызов API для одного из наших микросервисов. Естественно, это требует механизма обработки ошибок, учитывая, что микросервис может быть отключен или не отвечать на запросы.

AWS Lambda предоставляет свой собственный механизм повторных попыток, при котором сообщение извлекается из очереди потребителем Lambda и становится невидимым для других потребителей в течение определенного времени, называемого таймаутом видимости . Если потребитель успешно завершает выполнение, он автоматически удаляет сообщение из очереди. В случае неудачного выполнения (например, исключения во время выполнения) значение approximatereceivecount сообщения увеличивается, и оно становится доступным для других потребителей после истечения тайм-аута видимости . Количество раз, когда сообщение может быть повторно прочитано из очереди , прежде чем оно будет окончательно отправлено в Очередь с мертвыми письмами (DLQ), настраивается в политике Redrive очереди SQS и отслеживается с помощью приблизительного количества полученных сообщений .

Этот механизм повторной попытки был не совсем тем, что я имел в виду для нашего варианта использования. Я думал о стратегии отступления, которая продолжает повторять вызов API с экспоненциально увеличивающимся временем ожидания; наконец, отправка сообщения в DLQ после заданного количества попыток. Это дало бы нам достаточно времени, чтобы устранить любые проблемы с нашим микросервисом и предотвратить его бомбардировку неудачными вызовами API.

Вот что у меня получилось в итоге:

Во-первых, очень простая функция Java для вычисления экспоненциального времени ожидания, учитывая количество попыток recvCount :

        int randomInt = rand.nextInt(60);
        Long result = new Double(Math.pow(2, recvCount)).longValue() + 30 +randomInt;  //adding jitter to new random visibility timeout

Обратите внимание на добавление random Int . Это и есть “дрожание”. Немного случайности. Я прочитал об этом в некоторой документации Google Cloud и включил это в качестве хорошей практики.

Далее установите время ожидания видимости сообщения на значение, которое мы только что рассчитали выше. Максимальное значение, разрешенное AWS, составляет 43200 секунд или 12 часов.

  sqs.changeMessageVisibility(queueUrl, msg.getReceiptHandle(), newVisibilityTimeout.intValue());

Наконец, мы проверяем ответ на наш вызов API. Если это ответ серии 400 или 500, мы создаем исключение RuntimeException и изменяем время ожидания видимости сообщения. Это самый простой способ, который я мог придумать, чтобы сигнализировать о неудачном выполнении лямбда-функции. Кроме того, мы можем создавать только непроверенные исключения в нашем методе обработчика.

...
// api call
...  
 if (response.getStatusLine().getStatusCode() >= 400){
                            new ExponentialBackoff().setVisibilityTimeout(msg);
                            throw new RuntimeException("Request to server failed");
                        }

Экспоненциальный откат – это мой служебный класс, в котором живет код, который вычисляет и устанавливает тайм-аут видимости. Он также имеет некоторые другие полезные функции, которые не являются существенными для этой демонстрации.

Вот оно, что у вас есть; Голая реализация экспоненциального отката для AWS Lambda.

Оригинал: “https://dev.to/sohaibtariq/exponential-backoff-for-aws-lambda-3aj2”