Поиск по сайту:

Начало работы с .NET с функциями AWS Lambda


AWS Lambda Functions — это модель бессерверных вычислений, которая позволяет запускать код без серверов. Обычно они пишутся на таких языках, как JavaScript и Python, но теперь AWS поддерживает множество различных сред выполнения, включая .NET для C#.

Зачем использовать .NET для Lambda?

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

Если вы предпочитаете язык C#, его использование для Lambda не имеет особых недостатков, особенно если переход на Python или JavaScript вызывает слишком много хлопот. Инструменты, предоставляемые AWS, также хороши, и у вас есть доступ ко всему SDK AWS, что означает, что вы можете легко выполнять поиск таких сервисов, как Lambda и DynamoDB.

Кроме того, AWS поддерживает всю среду выполнения .NET, что означает, что вы можете использовать другие языки помимо C#, которые также компилируются в двоичные файлы .NET. C# в подавляющем большинстве случаев наиболее популярен, но вы также можете писать лямбда-функции на F# или VB.NET.

Как это работает?

Такие языки, как Java и C#, как правило, намного приятнее, но у их использования есть обратная сторона. Оба они скомпилированы в байт-код, который должен быть скомпилирован при запуске, поэтому у них больше времени запуска, особенно при холодном запуске. «Холодный запуск» — это когда AWS не запускал функцию в течение последних нескольких минут, поэтому она не будет кэширована, и ему нужно будет снова выполнить компиляцию точно в срок, чтобы запустить ее. Этот процесс может привести к тому, что вашим функциям потребуется секунда или больше для ответа, что не очень хорошо для веб-приложений.

Однако эта проблема в значительной степени смягчается, если вы используете Lambda очень часто. Вы также можете полностью сократить время холодного запуска с помощью подготовленного параллелизма. Обычное время отклика для .NET очень велико, а производительность находится на одном уровне с полностью скомпилированными языками, такими как Go и Rust.

Если вы в настоящее время используете Java для функций Lambda, C# может стать жизнеспособной заменой, поскольку современная среда выполнения .NET 6 использует меньше памяти и в большинстве случаев запускается быстрее, чем JVM.

Настройка лямбда-функций C#

Во-первых, вам понадобится установленный .NET. AWS поддерживает .NET Core 3.1 и .NET 6, поэтому любая из этих двух сред выполнения будет работать, но, что наиболее важно, вам потребуется установленный интерфейс командной строки dotnet, чтобы вы могли установить шаблоны Lambda. Вы можете получить .NET на портале документации Microsoft.

Вам нужно будет установить шаблоны Lambda и глобальные инструменты Lambda.

dotnet new -i Amazon.Lambda.Templates
dotnet tool install -g Amazon.Lambda.Tools

Это устанавливает множество опций; вы можете перечислить их все с помощью:

dotnet new --list

Этот инструмент довольно удобен, так как он поставляется со многими упакованными шаблонами, предварительно настроенными для различных вариантов использования. Как правило, вам понадобится одна функция для каждого проекта, чтобы размеры сборки были небольшими, но вы можете иметь несколько функций в одной DLL, если используете шаблоны AWS без сервера, которые развертываются с использованием шаблонов CloudFormation. С ними намного сложнее управлять, поэтому используйте их только в том случае, если они вам приносят пользу.

Однако с файлами решений .NET вы можете иметь несколько параллельных проектов, ссылающихся на общие сборки, так что это не большая проблема.

Сейчас мы воспользуемся простым шаблоном «Пустая функция», который создает проект с использованием .NET 6. Вы можете создать его из командной строки или из нового экрана проекта вашего редактора.

dotnet new lambda.EmptyFunction --name SimpleLambdaFunction --profile default --region us-east-1

Это создает очень простую функцию — она принимает строку в качестве входных данных, а также передает ILambdaContext. Это Main() функция точки входа для вашего Lambda, и она будет вызываться средой выполнения всякий раз, когда вызывается функция Lambda. Эта конкретная функция возвращает string, но вы также можете сделать ее async и вернуть Task.

Вверху вы увидите атрибут сборки, настраивающий сериализатор JSON. Внутри Lambda выполнит десериализацию входного содержимого для вас, а затем вызовет вашу функцию. Впоследствии, если он что-то вернет, это будет записано в поток ответов. Библиотеки Lambda обрабатывают этот шаблон за вас, а код, обертывающий вашу функцию, находится в HandlerWrapper.

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

Это означает, что вы можете свободно определять свои собственные модели для входных и выходных данных, передаваемых в функцию и из нее, что является одним из приятных преимуществ обработки JSON с помощью C#.

В этой функции она десериализует класс InputModel, ожидает асинхронно в течение секунды, а затем возвращает класс OutputModel. Этот класс сериализуется обратно в выходной поток, поэтому Lambda может его обработать.

Запуск лямбда-функций

Запустить функцию после того, как вы ее создали, довольно просто, поскольку интерфейс командной строки Lambda .NET предоставляет метод для ее развертывания. Просто запустите deploy-function с помощью

dotnet lambda deploy-function SimpleNETFunction

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

Lambda предоставляет встроенный тестер, которому вы можете передать JSON.

Это выполнит и покажет вам все подробности о выполнении. В данном случае при очень маленькой минимальной функции время холодного запуска составило менее 500 мс, что вполне прилично для .NET и для Lambda в целом. Как только становится тепло, оплачиваемая продолжительность снижается до нескольких миллисекунд.

В данном случае эта функция вообще не использовала много памяти, и уменьшение функции до 128 МБ не вызвало проблем.