Разработка .NET Web приложения на Yandex Cloud Functions

—

от автора

Введение

Яндекс Облако предоставляет возможность разворачивания .NET приложений разными способами, типичным из которых является docker контейнеры, развернутые на созданных вычислительных ресурсах, что подразумевают оплату за выделенные процессоры и память. Более экономный вариант предоставляют serverless сервисы Cloud Functions и Serverless Containers, где оплата идет по фактически потребленным ресурсам, масштабирование осуществляется самим облаком. Контейнеры это хороший вариант разработки, но более простым и легковесным является Cloud Functions.

Инструменты

Visual Studio предоставляет возможность создавать любые Web приложения, но разворачиваться они должны на хостах, которые открывают порты для взаимодействия с пользователями. Вариант для Cloud Functions это создать модуль, который имеет предопределенную точку входа. Метод-обработчик должен быть публичным, иметь имя FunctionHandler и один входной параметр. Но хотелось бы создавать полноценные Web Api, где под капотом midlware и вся мощь внедрения зависимостей созданное MS. Такого инструмента у Яндекс нет, но это есть у Amazon. AWS SDK для .NET дает возможность создавать и переносить существующие Web приложения на облако, и интегрируется с Visual Studio, чем мы просто и воспользуемся. Данная технология дает возможность запускать и отлаживать локально средствами Visual Studio.

Шаблоны проектов AWS

Компоненты

AWS SDK реализует IHostBuilder, но при запуске заменяет сервис IServer пустой заглушкой, потому хост при запуске не открывает порты и т.д. но цепочка обработки midleware работает. Точка входа и сигнатура вызова не совпадает с Яндекс, но это не проблема, open source дает возможность доделать проект, и вот сразу появляется наш AWS SDK с поддержкой Яндекс.

Разработка

Скачаем и локально установим nuget packet Amazon.Lambda.Yandex.0.0.1.nupkg, который мы создали, запустив команду nuget add с параметрами локального репозитория, который можно посмотреть в настройках VS.

Создадим на Visual Studio проект Web Api :

using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection;  namespace WebApplication {     public class Startup     {         public Startup(IConfiguration configuration)         {             Configuration = configuration;         }          public IConfiguration Configuration { get; }           public void ConfigureServices(IServiceCollection services)         {             services.AddControllers();         }          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)         {             app.UseRouting();             app.UseEndpoints(endpoints =>             {                 endpoints.MapControllers();                 endpoints.MapGet("/", () => "Welcome to running ASP.NET Core Minimal API");                 endpoints.MapGet("/test", () => "Welcome to Yandex");             });         }     } } 
using Amazon.Lambda.AspNetCoreServer; using Microsoft.AspNetCore.Hosting;  namespace WebApplication {     public class YandexFunction : YandexGatewayProxyFunction     {         protected override void Init(IWebHostBuilder builder)         {             builder.UseStartup<Startup>();         }     } }
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using WebApplication.Model;  namespace WebApplication.Controllers {     [ApiController]     [Route("api/test")]     public class ApiController : ControllerBase     {         private static readonly string[] Summaries = new[]         {             "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"         };          private readonly ILogger<WeatherForecastController> _logger;          public ApiController(ILogger<WeatherForecastController> logger)         {             _logger = logger;         }          [HttpGet]         public IEnumerable<WeatherForecast> Get()         {             var rng = new Random();             return Enumerable.Range(1, 5).Select(index => new WeatherForecast             {                 Date = DateTime.Now.AddDays(index),                 TemperatureC = rng.Next(-20, 55),                 Summary = Summaries[rng.Next(Summaries.Length)]             })             .ToArray();         }     } } 

Развертывание

Яндекс наверно оптимизировал и урезал среду исполнения net6, потому придется делать сборку Self-contained, иначе загрузчик ругается на отсутствие библиотек ядра, потом удалим системные библиотеки.

Делаем локальное разворачивание Publish, ставим параметры:

  • linuх-x64

  • net6.0

  • Self-contained

  • Trim unused code

Удаляем System.*.dll и файлы *.so кроме System.Diagnostics.*.dll System.IO.*.dll System.Text.*.dll
Упакуем в .zip, грузим в облако.

Точка входа: WebApplication.YandexFunction

Создаем для функции отдельный Yandex API Gateway:

openapi: 3.0.0 info:   title: Sample Web API   version: 1.0.0 servers: - url: https://....apigw.yandexcloud.net paths:   /test:     get:       summary: Get Test       operationId: gettest10       tags:         - example       x-yc-apigateway-integration:         type: cloud_functions         function_id: ...         payload_format_version: "1.0"         tag: "$latest"       responses:         '200':           description: Ok   /api/{param+}:     x-yc-apigateway-any-method:       summary: Get Controllers       parameters:         - name: param           in: path           required: true           schema:             type: string       operationId: getcontrollers       tags:         - example       x-yc-apigateway-integration:         type: cloud_functions         function_id: ...         payload_format_version: "1.0"         tag: "$latest"       responses:         '200':           description: Ok

Наше приложение готово и доступно в интернете по адресу шлюза.

Ссылки на исходники:


ссылка на оригинал статьи https://habr.com/ru/articles/729406/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *