Обработка ошибок в бессерверных приложениях

с помощью сервисов AWS Step Functions и AWS Lambda

Работая с данным учебным пособием, вы научитесь обрабатывать ошибки времени исполнения рабочих процессов с помощью сервиса AWS Step Functions. AWS Step Functions – это сервис оркестрации бессерверных приложений, с помощью которого можно координировать работу нескольких функций Lambda и объединять их в гибкие рабочие процессы. Такие рабочие процессы просты в отладке и в них несложно вносить изменения. AWS Lambda – это вычислительный сервис, с помощью которого можно выполнять код, не выделяя серверы и не управляя ими. 

Иногда функции Lambda могут завершаться с ошибкой, например если возникает необработанное исключение, если функция выполняется дольше заданного времени ожидания либо если для нее не хватает памяти. Писать и поддерживать логику обработки ошибок в каждой используемой функции Lambda для различных ситуаций (например, на случай регулирования API или истечения времени ожидания для сокетов) может быть сложно и затратно по времени. Особенно это касается распределенных приложений. Внедрение такого кода в каждую функцию Lambda приводит к появлению зависимостей между функциями, и при внесении изменений может быть трудно поддерживать все эти связи.

Чтобы избежать таких проблем и сократить объем кода для обработки ошибок, который необходимо написать, используйте сервис AWS Step Functions. С его помощью вы можете создавать бессерверные рабочие процессы, которые поддерживают обработку ошибок функций. Независимо от того что представляет собой ошибка – исключение функции, предусмотренное разработчиком (например, если не найден файл), или непредвиденное исключение (например, когда не хватает памяти) – можно настроить сервис Step Functions таким образом, чтобы он реагировал с использованием условной логики на основании видов возникающих ошибок. Отделив таким образом логику рабочего процесса от бизнес-логики, вы можете изменять реакцию вашего рабочего процесса на ошибки, не внося изменений в бизнес-логику функций Lambda.

В рамках данного учебного пособия вы разработаете и запустите бессерверный рабочий процесс с использованием сервиса AWS Step Functions, который будет обрабатывать такие ошибки. Вы создадите функцию AWS Lambda, которая будет имитировать вызовы к API RESTful и возвращать различные коды ответов и исключения. Затем с помощью сервиса AWS Step Functions вы создадите конечный автомат с функциями Retry и Catch. Он будет возвращать отклики, используя различную логику в зависимости от возникшего исключения.

Для работы с этим учебным пособием необходим аккаунт AWS

За использование сервисов AWS Step Functions и AWS Lambda дополнительная плата не взимается. Ресурсы, которые вы создаете при работе с данным учебным пособием, соответствуют условиям уровня бесплатного пользования. 

Подробнее об уровне бесплатного пользования >>


Шаг 1. Создание функции Lambda для имитации API

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


a.  Откройте Консоль управления AWS, оставив открытым данное пошаговое руководство. Когда загрузится соответствующий экран, введите имя пользователя и пароль, чтобы начать работу. Затем введите текст Lambda в строке поиска и щелкните Lambda, чтобы открыть консоль сервиса.

01a
01a

(Щелкните, чтобы увеличить изображение.)


b. Щелкните Create a function (Создать функцию).

01b
01b

(Щелкните, чтобы увеличить изображение.)


c. Не снимайте флажок Author from scratch (Создать «с нуля»). Затем настройте функцию Lambda указанным ниже способом.

В поле Name (Имя) введите MockAPIFunction.
Для параметра Runtime (Среда выполнения) выберите значение Python 3.6.
Для параметра Role (Роль) выберите значение Create custom role (Создать настраиваемую роль).

Откроется новое окно IAM. Оставьте для параметра Role name (Имя роли) значение lambda_basic_execution и щелкните Allow (Разрешить). Вы автоматически вернетесь назад в консоль Lambda.

Щелкните Create function (Создать функцию).

01c
01c

(Щелкните, чтобы увеличить изображение.)


d. Прокрутите содержимое экрана MockAPIFunction вниз до раздела Function code (Код функции). Работая с данным учебным пособием, вы создадите функцию, в которой используется модель программирования для создания функций Lambda на языке Python. В окне кода замените весь код указанным ниже кодом, а затем нажмите Save (Сохранить).

class TooManyRequestsException(Exception): pass
class ServerUnavailableException(Exception): pass
class UnknownException(Exception): pass

def lambda_handler(event, context):
    statuscode = event["statuscode"]    
    if statuscode == "429":
        raise TooManyRequestsException('429 Too Many Requests')
    elif statuscode == "503":
        raise ServerUnavailableException('503 Server Unavailable')
    elif statuscode == "200":
        return '200 OK'
    else:
        raise UnknownException('Unknown error')
01d
01d

(Щелкните, чтобы увеличить изображение.)


e. После того как ваша функция Lambda будет создана, прокрутите содержимое окна до его верхней части и запишите значение имени Amazon Resource Name (ARN), указанное в правом верхнем углу страницы. Имена Amazon Resource Name (ARN) позволяют уникальным образом идентифицировать ресурсы AWS, а также помогают отслеживать и использовать элементы и политики AWS в сервисах AWS и вызовах API. Чтобы сослаться на определенный ресурс из сервиса Step Functions, необходимо указать имя ARN.

01e
01e

(Щелкните, чтобы увеличить изображение.)


Шаг 2. Создание роли AWS Identity and Access Management (IAM)

Сервис AWS Step Functions может выполнять код и получать доступ к другим ресурсам AWS (например, к данным, хранящимся в корзинах Amazon S3). Чтобы поддерживать надлежащий уровень безопасности, необходимо предоставить сервису Step Functions доступ к этим ресурсам с помощью AWS Identity and Access Management (IAM).


a. В другом окне браузера перейдите в Консоль управления AWS и в строке поиска введите текст IAM. Щелкните IAM, чтобы открыть консоль сервиса.

02a
02a

(Щелкните, чтобы увеличить изображение.)


b. Щелкните Roles (Роли) и выберите пункт Create Role (Создать роль).

02b
02b

(Щелкните, чтобы увеличить изображение.)


c. На странице Select type of trusted entity (Выбор типа доверенного объекта) в сервисе AWS в списке выберите пункт Step Functions и нажмите кнопку Next: Permissions (Далее: разрешения).

02c
02c

(Щелкните, чтобы увеличить изображение.)


d. На странице Attach permissions policy (Прикрепление политики разрешений) нажмите кнопку Next: Review (Далее: проверка).

 

02d
02d

(Щелкните, чтобы увеличить изображение.)


e. На странице Review (Проверка) введите значение step_functions_basic_execution для параметра Role name (Имя роли) и щелкните Create role (Создать роль).

02e
02e

(Щелкните, чтобы увеличить изображение.)


f. Будет создана роль IAM, которая появится в списке под ролью IAM для вашей функции Lambda.

02f
02f

(Щелкните, чтобы увеличить изображение.)


Шаг 3. Создание конечного автомата Step Functions

Теперь, когда вы создали простую функцию Lambda, которая имитирует отклик API, можно создать конечный автомат Step Functions для вызова API и обработки исключений.

На этом шаге вы с помощью консоли Step Functions создадите конечный автомат, который будет использовать состояние задачи с полями Retry и Catch для обработки различных кодов отклика API. Вы будете использовать состояние задачи, чтобы вызывать свою функцию Lambda, имитирующую API, которая будет возвращать код состояния API, который, в свою очередь, вы будете передавать в качестве входных данных для вашего конечного автомата.


a. Откройте консоль AWS Step Functions. На странице Create a state machine (Создание конечного автомата) выберите пункт Author from scratch (Создать «с нуля»). В разделе Details (Сведения) укажите имя MyAPIStateMachine для своего конечного автомата и щелкните I will use an existing role (Я буду использовать существующую роль).

03c
03c

(Щелкните, чтобы увеличить изображение.)


b. Далее вы разработаете конечный автомат, который будет выполнять различные действия в зависимости от отклика от вашего фиктивного API. В случаях, когда не удается связаться с API, рабочий процесс будет повторять попытки. Повторение попыток – хороший способ справиться с проблемами, связанными с временными ошибками. Рабочий процесс также перехватывает различные исключения, созданные фиктивным API.

Замените содержимое раздела State machine definition (Определение конечного автомата) указанным ниже кодом.

{
  "Comment": "An example of using retry and catch to handle API responses",
  "StartAt": "Call API",
  "States": {
    "Call API": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
      "Next" : "OK",
      "Comment": "Catch a 429 (Too many requests) API exception, and resubmit the failed request in a rate-limiting fashion.",
      "Retry" : [ {
        "ErrorEquals": [ "TooManyRequestsException" ],
        "IntervalSeconds": 1,
        "MaxAttempts": 2
      } ],
      "Catch": [ 
        {
          "ErrorEquals": ["TooManyRequestsException"],
          "Next": "Wait and Try Later"
        }, {
          "ErrorEquals": ["ServerUnavailableException"],
          "Next": "Server Unavailable"
        }, {
          "ErrorEquals": ["States.ALL"],
          "Next": "Catch All"
        }
      ]
    },
    "Wait and Try Later": {
      "Type": "Wait",
      "Seconds" : 1,
      "Next" : "Change to 200"
    },
    "Server Unavailable": {
      "Type": "Fail",
      "Error":"ServerUnavailable",
      "Cause": "The server is currently unable to handle the request."
    },
    "Catch All": {
      "Type": "Fail",
      "Cause": "Unknown error!",
      "Error": "An error of unknown type occurred"
    },
    "Change to 200": {
      "Type": "Pass",
      "Result": {"statuscode" :"200"} ,
      "Next": "Call API"
    },
    "OK": {
      "Type": "Pass",
      "Result": "The request has succeeded.",
      "End": true
    }
  }
}
03d
03d

(Щелкните, чтобы увеличить изображение.)


c. Найдите строку Resource (Ресурс) в состоянии задачи Call API (Вызов API) (строка 7). Чтобы обновить имя ARN до имени ARN только что созданной функции Lambda, которая имитирует API, щелкните текст имени ARN и выберите необходимое имя ARN в списке.

03e
03e

(Щелкните, чтобы увеличить изображение.)


d. Нажмите кнопку обновления рядом с областью визуального рабочего процесса, чтобы сервис Step Functions создал схему конечного автомата, соответствующую только что созданному вами рабочему процессу. После проверки визуального рабочего процесса щелкните Create state machine (Создать конечный автомат).

03f
03f

(Щелкните, чтобы увеличить изображение.)


Шаг 4. Тестирование рабочего процесса обработки ошибок

Чтобы протестировать процесс обработки ошибок, запустите конечный автомат, чтобы он совершил вызов к фиктивному API, передав ему код ошибки в качестве входных параметров.


a. Щелкните Start execution (Начать выполнение).

04a
04a

(Щелкните, чтобы увеличить изображение.)


b. Откроется новое диалоговое окно выполнения, в котором можно ввести входные данные для конечного автомата. Вы воспроизведете часть API и предоставите код ошибки, который (по нашему замыслу) должен возвратить фиктивный API. Замените имеющийся текст приведенным ниже кодом, а затем нажмите Start execution (Начать выполнение).

{
    "statuscode": "200"
}
04b
04b

(Щелкните, чтобы увеличить изображение.)


c. На экране Execution details (Сведения о ходе выполнения) щелкните Input (Входные данные), чтобы отобразить входные данные, предоставленные вашему конечному автомату. Затем щелкните Output (Выходные данные), чтобы отобразить результат выполнения конечного автомата. Вы увидите, что рабочий процесс интерпретировал код состояния 200 как успешное выполнение вызова API.

04c
04c

(Щелкните, чтобы увеличить изображение.)


d. В разделе Visual workflow (Визуальный рабочий процесс) будет отображаться путь выполнения каждого сеанса выполнения, который будет показан зеленым цветом в рабочем процессе. Щелкните состояние задачи Call API и разверните поля Input (Входные данные) и Output (Выходные данные) на экране Step details (Сведения о шаге).

Вы увидите, что состояние задачи успешно вызвало вашу функцию Lambda, имитирующую API, и передало ей предоставленные вами входные данные, а затем получило выходные данные этой функции Lambda – «200 OK».

04d
04d

(Щелкните, чтобы увеличить изображение.)


e. Далее щелкните состояние задачи OK в визуальном рабочем процессе. В разделе Step details (Сведения о шаге) вы увидите, что выходные данные предыдущего шага (состояние задачи Call API) переданы в качестве входных данных в этот шаг. Состояние OK – это состояние Pass, которое просто передало поступившие на вход данные в качестве выходных данных, не выполняя никакой работы. Состояния Pass удобно использовать при проектировании и отладке конечных автоматов.

04e
04e

(Щелкните, чтобы увеличить изображение.)


Шаг 5. Проверка выполнения конечного автомата


a. Прокрутите содержимое окна в верхнюю часть экрана Execution details (Сведения о выполнении) и щелкните MyAPIStateMachine.

05a
05a

(Щелкните, чтобы увеличить изображение.)


b. Еще раз щелкните Start execution (Начать выполнение), и в этот раз передайте указанные ниже входные данные, а затем щелкните Start execution (Начать выполнение).

{
    "statuscode": "503"
}
05b
05b

(Щелкните, чтобы увеличить изображение.)


c. В разделе Execution event history (Журнал событий выполнения) разверните каждый шаг выполнения, чтобы убедиться, что ваш рабочий процесс работал, как ожидалось. Мы ожидали, что во время этого выполнения произойдет сбой, поэтому не тревожьтесь. Вы заметите указанное ниже.

  1. Сервис Step Functions перехватил ваши входные данные
  2. Эти входные данные были переданы в состояние задачи Call API
  3. Состояние задачи Call API вызвало вашу функцию MockAPIFunction с использованием этих входных данных
  4. Функция MockAPIFunction выполнена
  5. Работа функции MockAPIFunction была завершена с ошибкой и с созданием исключения ServerUnavailableException
  6. Оператор перехвата в вашем состоянии задачи Call API перехватил это исключение
  7. Оператор перехвата вызвал ошибку в рабочем процессе
  8. Выполнение вашего конечного автомата завершилось
05c
05c

(Щелкните, чтобы увеличить изображение.)


d. Далее вы выполните эмуляцию исключения 429. Прокрутите содержимое окна в верхнюю часть экрана Execution details (Сведения о выполнении) и щелкните MyAPIStateMachine. Щелкните Start execution (Начать выполнение), передайте указанные ниже входные данные, а затем щелкните Start execution (Начать выполнение).

{
    "statuscode": "429"
}
05d
05d

(Щелкните, чтобы увеличить изображение.)


e. Теперь вы проверите, как ваш рабочий процесс выполняет повторные попытки. В разделе Execution event history (Журнал событий выполнения) еще раз разверните каждый шаг выполнения, чтобы убедиться, что сервис Step Functions пытался вызвать функцию MockAPILambda еще два раза, причем обе попытки были неудачными. В этой точке ваш рабочий процесс перешел в состояние Wait (Ожидание) и Try Later (Повторить попытку позже) (что показано на изображении справа) в расчете на то, что API не отвечает из-за временных проблем.

Далее в состоянии Wait (Ожидание) методом подбора код отклика был изменен на 200, и ваш рабочий процесс успешно завершил выполнение. Этот метод, вероятно, не похож на метод, которым вы обрабатывали бы исключение 429 в реальном приложении, но в данном учебном пособии мы стараемся ничего не усложнять.

05e
05e

(Щелкните, чтобы увеличить изображение.)


f. Выполните еще один инстанс своего рабочего процесса, и в этот раз предоставьте случайное значение отклика API, которое не учтено в вашем конечном автомате:

{
    "statuscode": "999"
}

Еще раз проверьте сеанс выполнения в разделе Execution event history (Журнал событий выполнения). По завершении еще раз щелкните MyAPIStateMachine. В области Executions (Сеансы выполнения) отображается журнал всех сеансов выполнения вашего рабочего процесса. Вы можете отдельно выбрать любой этап.

05f
05f

(Щелкните, чтобы увеличить изображение.)


Шаг 6. Удаление ресурсов

В этом шаге вы удалите свои ресурсы, связанные с сервисами AWS Step Functions и AWS Lambda.

Важно! Удаление неиспользуемых ресурсов позволяет сократить расходы и является рекомендованной мерой. Если не удалить ресурсы, может взиматься дополнительная плата.


a. В верхней части окна консоли AWS Step Functions щелкните пункт State machines (Конечные автоматы).

06a
06a

(Щелкните, чтобы увеличить изображение.)


b. В окне State machines (Конечные автоматы) щелкните пункт MyAPIStateMachine и выберите команду Delete (Удалить). Подтвердите действие, выбрав команду Delete state machine (Удалить конечный автомат) в диалоговом окне. Ваш конечный автомат будет удален через одну-две минуты после того как сервис Step Functions подтвердит, что все сеансы выполнения процессов завершены.

06b
06b

(Щелкните, чтобы увеличить изображение.)


c. Затем удалите свои функции Lambda. В меню Консоли управления AWS Management щелкните Services (Сервисы) и выберите пункт Lambda.

06c
06c

(Щелкните, чтобы увеличить изображение.)


d. На экране Functions (Функции) щелкните свою функцию MockAPIFunction, выберите пункт Actions (Действия), а затем команду Delete (Удалить). Подтвердите удаление, еще раз щелкнув Delete (Удалить).

06d
06d

(Щелкните, чтобы увеличить изображение.)


e. И, наконец, удалите свои роли IAM. В меню Консоли управления AWS Management щелкните Services (Сервисы) и выберите пункт IAM.

06e
06e

(Щелкните, чтобы увеличить изображение.)


f. Выберите обе роли IAM, которые вы создали для работы с данным учебным пособием, а затем щелкните Delete role (Удалить роль). Подтвердите удаление, щелкнув пункт Yes, Delete (Да, удалить) в диалоговом окне.


Теперь можно выйти из системы Консоли управления AWS.

06f
06f

(Щелкните, чтобы увеличить изображение.)


Поздравляем!

Вы научились использовать сервисы AWS Step Functions и AWS Lambda для создания рабочего процесса обработки ошибок для API сети. С помощью сервиса AWS Lambda можно запускать код для практически любых типов приложений и серверных сервисов, и при этом не требуется выполнять никакие операции администрирования. Просто загрузите программный код, и Lambda обеспечит все ресурсы, необходимые для его исполнения, масштабирования и обеспечения высокой доступности.

Совместное использование сервисов AWS Step Functions и AWS Lambda упрощает оркестрацию функций AWS Lambda для бессерверных приложений. С помощью сервиса Step Functions можно управлять сложными рабочими процессами с использованием функций Lambda без необходимости управлять приложениями и выполнять оркестрацию состояния. Кроме того, вы можете применять сервис Step Functions для оркестрации микросервисов с использованием вычислительных ресурсов, например Amazon EC2 и Amazon ECS.


Была ли полезной информация, представленная в этом учебном пособии?