Облачные функции Google на C#

1. Введение

Функции Google Cloud Run — это бессерверная вычислительная платформа, управляемая событиями. Функции Cloud Run позволяют вам писать код, не беспокоясь о предоставлении ресурсов или масштабировании для удовлетворения меняющихся требований.

Существует два типа функций Cloud Run:

  • Функции HTTP отвечают на HTTP-запросы.
  • Функции событий запускаются такими событиями, как публикация сообщения в Cloud Pub/Sub или загрузка файла в Cloud Storage .

efb3268e3b74ed4f.png

В этой лаборатории кода вы узнаете, как создать собственные функции Cloud Run на C#. Более конкретно, вы будете развертывать функции C#, реагирующие на HTTP и CloudEvents из различных источников Google Cloud.

Что вы узнаете

  • Фреймворк функций для .NET.
  • Как написать HTTP-функцию.
  • Как написать функцию, запускаемую по событию, реагирующую на события облачного хранилища.
  • Как написать функцию, запускаемую по событию, реагирующую на события Cloud Pub/Sub.
  • Как написать функцию, запускаемую событием, реагирующую на любой тип события.

2. Настройка и требования

Самостоятельная настройка среды

  1. Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google. Вы можете обновить его в любое время.
  • Идентификатор проекта должен быть уникальным для всех проектов Google Cloud и неизменяемым (нельзя изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно он обозначается как PROJECT_ID ). Если вам не нравится сгенерированный идентификатор, вы можете создать другой случайный идентификатор. Кроме того, вы можете попробовать свой собственный и посмотреть, доступен ли он. Его нельзя изменить после этого шага, и он останется в силе на протяжении всего проекта.
  • К вашему сведению, есть третье значение — номер проекта , который используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
  1. Затем вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Чтобы отключить ресурсы и избежать выставления счетов за пределами этого руководства, вы можете удалить созданные вами ресурсы или удалить весь проект. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лаборатории вы будете использовать Google Cloud Shell , среду командной строки, работающую в облаке.

В Google Cloud Console щелкните значок Cloud Shell на верхней правой панели инструментов:

55efc1aaa7a4d3ad.png

Подготовка и подключение к среде займет всего несколько минут. Когда все будет готово, вы должны увидеть что-то вроде этого:

7ffe5cbb04455448.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Всю работу в этой лаборатории кода можно выполнять в браузере. Вам не нужно ничего устанавливать.

3. Прежде чем начать

Внутри Cloud Shell выполните следующую команду, чтобы включить необходимые службы:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  eventarc.googleapis.com \
  run.googleapis.com

Далее укажите свой регион.

REGION=<YOUR_REGION>

Для этой лаборатории кода вы создадите учетную запись службы с необходимыми разрешениями EventArc и ролью инициатора Cloud Run, чтобы получать события из Cloud Storage и вызывать функцию Cloud Run.

Сначала создайте учетную запись службы.

PROJECT_ID=$(gcloud config get-value core/project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

SERVICE_ACCOUNT="cloud-run-functions"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run functions Eventarc service account"

Затем предоставьте роль получателя событий Eventarc (roles/eventarc.eventReceiver) в проекте учетной записи службы, связанной с вашим триггером Eventarc, чтобы триггер мог получать события от поставщиков событий.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/eventarc.eventReceiver

Затем предоставьте сервисному аккаунту роль инициатора Cloud Run, чтобы он мог вызывать функцию.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

4. Фреймворк функций для .NET

Functions Framework для .NET — это платформа FaaS (функция как услуга) с открытым исходным кодом для написания переносимых функций .NET, предоставленная вам командой Google Cloud Functions.

Платформа функций позволяет писать облегченные функции, которые выполняются в различных средах, в том числе:

  • Функции Google Cloud Run
  • Ваша локальная машина разработки
  • Cloud Run и Cloud Run на GKE
  • Knative-среды

В этой лаборатории кода вы будете использовать Functions Framework для .NET и ее шаблоны для создания и развертывания облачных функций на C#.

В Cloud Shell выполните следующую команду, чтобы установить шаблоны Cloud Functions для dotnet :

dotnet new install Google.Cloud.Functions.Templates

При этом будут установлены 3 шаблона для dotnet . Каждый шаблон доступен на C#, F# и VB (но в этой лабораторной работе вы будете использовать только C#). Вы можете убедиться, что шаблоны установлены, выполнив:

dotnet new list

Templates                                                 Short Name            
-----------------------------------------------------------------------
Google Cloud Functions CloudEvent Function                gcf-event
Google Cloud Functions CloudEvent Function (Untyped)      gcf-untyped-event
Google Cloud Functions HttpFunction                       gcf-http

5. HTTP-функция

Вы создадите и развернете функцию HTTP, отвечающую на HTTP-запросы.

Создайте функцию HTTP, используя шаблон gcf-http :

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

При этом создается проект и файл Function.cs отвечающий на HTTP-запросы.

Измените целевую платформу на net8.0 в файле .csproj :

<TargetFramework>net8.0</TargetFramework>

Чтобы развернуть функцию Cloud Run непосредственно в Cloud Run, выполните следующую команду:

gcloud beta run deploy hello-http-function \
    --source . \
    --function HelloHttp.Function \
    --base-image dotnet8 \
    --region $REGION \
    --allow-unauthenticated

Если вы предпочитаете развертывать облачные функции 2-го поколения, используйте следующую команду:

gcloud functions deploy hello-http-function \
    --allow-unauthenticated \
    --entry-point HelloHttp.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-http

После развертывания функции вы можете вызвать ее с помощью следующей команды curl:

SERVICE_URL=$(gcloud run services describe hello-http-function --platform managed --region $REGION --format 'value(status.url)')

curl $SERVICE_URL

6. Функция CloudEvent — GCS

Вы создадите и развернете функцию CloudEvent, реагирующую на события Google Cloud Storage (GCS).

Сначала создайте корзину Cloud Storage. Это сегмент, из которого вы будете прослушивать события позже:

BUCKET_NAME="cloud-functions-bucket-${PROJECT_ID}"
gsutil mb -l us-central1 gs://${BUCKET_NAME}

Создайте функцию CloudEvent, используя шаблон gcf-event :

cd ..
mkdir HelloGcs
cd HelloGcs
dotnet new gcf-event

При этом создается проект и файл Function.cs отвечающий на запросы CloudEvent . Он также анализирует данные CloudEvent в StorageObjectData .

Измените целевую платформу на net8.0 в файле .csproj :

<TargetFramework>net8.0</TargetFramework>

Чтобы развернуть функцию Cloud Run непосредственно в Cloud Run, вы сначала развернете функцию, а затем создадите для нее триггер.

gcloud beta run deploy hello-gcs-function \
      --source . \
      --function HelloGcs.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Теперь создайте триггер для функции Cloud Run.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-gcs-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-gcs-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

Если вы предпочитаете развертывать облачные функции 2-го поколения, вы можете использовать следующую команду для развертывания функции с использованием флагов trigger-event и trigger-resource :

gcloud functions deploy hello-gcs-function \
    --allow-unauthenticated \
    --entry-point HelloGcs.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME} \
    --service-account=$SERVICE_ACCOUNT_ADDRESS

Через пару минут функция должна появиться в Cloud Console:

c28654d74bb31420.png

Запустите функцию, загрузив файл в хранилище:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Убедитесь, что функция сработала, прочитав журналы:

Для функции Cloud Run вы можете запустить эту команду:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Для функции 2-го поколения вы можете запустить эту команду:

gcloud functions logs read hello-gcs-function \
    --gen2 \
    --region us-central1

7. Функция CloudEvent — публикация/подписка

Вы создадите и развернете функцию CloudEvent, реагирующую на события Cloud Pub/Sub.

Сначала создайте тему Cloud Pub/Sub, которая будет отправлять события:

TOPIC_NAME=cloud-functions-topic
gcloud pubsub topics create ${TOPIC_NAME}

Создайте функцию CloudEvent, используя шаблон gcf-event :

cd ..
mkdir HelloPubSub
cd HelloPubSub
dotnet new gcf-event

При этом создается проект и файл Function.cs отвечающий на запросы CloudEvent . Он также по умолчанию анализирует данные CloudEvent в StorageObjectData .

Измените целевую платформу на net8.0 в файле .csproj :

<TargetFramework>net8.0</TargetFramework>

Измените StorageObjectData на MessagePublishedData , чтобы проанализировать сообщения Pub/Sub. Измените Google.Events.Protobuf.Cloud.Storage.V1 на Google.Events.Protobuf.Cloud.PubSub.V1 .

В конечном итоге ваша функция должна выглядеть так:

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Cloud.PubSub.V1;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace HelloPubSub;

public class Function : ICloudEventFunction<MessagePublishedData>
{
    public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
    {
        var nameFromMessage = data.Message?.TextData;
        var name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage;
        Console.WriteLine($"Hello {name}");
        return Task.CompletedTask;
    }
}

Чтобы развернуть функцию Cloud Run непосредственно в Cloud Run, вы сначала развернете функцию, а затем создадите для нее триггер.

gcloud beta run deploy hello-pubsub-function \
      --source . \
      --function HelloPubSub.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated \
      --service-account=$SERVICE_ACCOUNT_ADDRESS

Теперь создайте триггер для функции Cloud Run.

gcloud eventarc triggers create my-pubsub-trigger \
    --location=$REGION \
    --service-account=$SERVICE_ACCOUNT_ADDRESS \
    --destination-run-service=hello-pubsub-function \
    --destination-run-region=$REGION \
    --destination-run-path="/" \
    --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
    --transport-topic=projects/$PROJECT_ID/topics/$TOPIC_NAME

Если вы предпочитаете развертывать облачные функции 2-го поколения, вы можете использовать следующую команду для развертывания функции с использованием флага trigger-topic :

gcloud functions deploy hello-pubsub-function \
    --allow-unauthenticated \
    --entry-point HelloPubSub.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-topic ${TOPIC_NAME}

Через пару минут функция должна появиться в Cloud Console:

3443808da7caf3bc.png

Запустите функцию, опубликовав сообщение в теме:

gcloud pubsub topics publish ${TOPIC_NAME} --message="World"

Проверьте, что функция была запущена, прочитав журналы.

Для функции Cloud Run вы можете запустить эту команду:

gcloud logging read "resource.labels.service_name=hello-pubsub-function AND textPayload: World" --format=json

Для функции 2-го поколения вы можете запустить эту команду:

gcloud functions logs read hello-pubsub-function \
    --gen2 \
    --region us-central1

8. Функция CloudEvent — нетипизированная

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

Создайте функцию CloudEvent, используя шаблон gcf-untyped-event :

cd ..
mkdir HelloUntyped
cd HelloUntyped
dotnet new gcf-untyped-event

При этом создается проект и файл Function.cs отвечающий на запросы CloudEvent без каких-либо попыток анализа данных CloudEvent .

Измените целевую платформу на net8.0 в файле .csproj :

<TargetFramework>net8.0</TargetFramework>

Чтобы развернуть функцию Cloud Run непосредственно в Cloud Run, вы сначала развернете функцию, а затем создадите для нее триггер.

gcloud beta run deploy hello-untyped-function \
      --source . \
      --function HelloUntyped.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Теперь создайте триггер для функции Cloud Run.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-untyped-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-untyped-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

Если вы предпочитаете развертывать облачные функции 2-го поколения, вы можете использовать следующую команду для развертывания функции с использованием флагов trigger-event и trigger-resource :

gcloud functions deploy hello-untyped-function \
    --allow-unauthenticated \
    --entry-point HelloUntyped.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME}

Функция сработает, когда файл будет загружен в корзину хранилища.

Через пару минут функция должна появиться в Cloud Console:

afe56530826787c6.png

Запустите функцию, загрузив файл в хранилище:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Проверьте, что функция была активирована, прочитав журналы.

Для функции Cloud Run вы можете запустить эту команду:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Для функции 2-го поколения вы можете запустить эту команду:

gcloud functions logs read hello-untyped-function \
    --gen2 \
    --region us-central1

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

Поздравляем с завершением работы над кодом.

Что мы рассмотрели

  • Фреймворк функций для .NET.
  • Как написать облачную функцию HTTP.
  • Как написать функцию CloudEvent, реагирующую на события Cloud Storage.
  • Как написать функцию CloudEvent, реагирующую на события Cloud Pub/Sub.
  • Как написать функцию CloudEvent, реагирующую на любой тип события.