توابع Google Cloud در سی شارپ

1. مقدمه

توابع Google Cloud Run یک پلت فرم محاسباتی بدون سرور مبتنی بر رویداد است. توابع Cloud Run به شما این امکان را می دهد که کد خود را بدون نگرانی در مورد تهیه منابع یا مقیاس بندی برای رسیدگی به نیازهای در حال تغییر بنویسید.

دو نوع عملکرد Cloud Run وجود دارد:

  • توابع HTTP به درخواست های HTTP پاسخ می دهند.
  • توابع رویداد توسط رویدادها فعال می‌شوند، مانند پیامی که در Cloud Pub/Sub منتشر می‌شود یا فایلی که در Cloud Storage بارگذاری می‌شود.

efb3268e3b74ed4f.png

این لبه کد شما را در ایجاد توابع Cloud Run خود در سی شارپ راهنمایی می کند. به طور خاص، توابع C# را که به HTTP و CloudEvents از منابع مختلف Google Cloud پاسخ می دهند، مستقر خواهید کرد.

چیزی که یاد خواهید گرفت

  • Functions Framework برای دات نت.
  • نحوه نوشتن یک تابع HTTP
  • نحوه نوشتن یک تابع Event Triggered که به رویدادهای Cloud Storage پاسخ می دهد.
  • نحوه نوشتن یک تابع Event Triggered که به رویدادهای Cloud Pub/Sub پاسخ می دهد.
  • نحوه نوشتن یک تابع Event Triggered که به هر نوع رویدادی پاسخ می دهد.

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/APIها باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. برای اینکه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید، می توانید منابعی را که ایجاد کرده اید حذف کنید یا کل پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.

Cloud Shell را راه اندازی کنید

در حالی که Google Cloud را می توان از راه دور از لپ تاپ شما کار کرد، در این کد لبه از Google Cloud Shell استفاده خواهید کرد، یک محیط خط فرمان که در Cloud اجرا می شود.

از 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. Functions Framework برای دات نت

Functions Framework for .NET یک چارچوب متن باز FaaS (عملکرد به عنوان سرویس) برای نوشتن توابع قابل حمل دات نت است - که توسط تیم Google Cloud Functions برای شما آورده شده است.

Functions Framework به شما امکان می دهد توابع سبک وزنی بنویسید که در محیط های مختلف اجرا می شوند، از جمله:

  • توابع Google Cloud Run
  • ماشین توسعه محلی شما
  • Cloud Run و Cloud Run در GKE
  • محیط های مبتنی بر Knative

در این کد لبه، شما از Functions Framework برای دات نت و قالب های آن برای ایجاد و استقرار توابع ابری در سی شارپ استفاده خواهید کرد.

در داخل 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 پاسخ می دهد.

با استفاده از الگوی gcf-http یک تابع HTTP ایجاد کنید:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

این یک پروژه و یک فایل Function.cs ایجاد می کند که به درخواست های HTTP پاسخ می دهد.

چارچوب هدف را در فایل .csproj به net8.0 تغییر دهید:

<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

اگر ترجیح می دهید به عنوان نسل دوم توابع ابری مستقر شوید، از دستور زیر استفاده کنید:

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}

با استفاده از الگوی gcf-event یک تابع CloudEvent ایجاد کنید:

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

این یک پروژه و یک فایل Function.cs ایجاد می کند که به درخواست های CloudEvent پاسخ می دهد. همچنین داده های CloudEvent را به StorageObjectData تجزیه می کند.

چارچوب هدف را در فایل .csproj به net8.0 تغییر دهید:

<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

اگر ترجیح می‌دهید به‌عنوان نسل دوم توابع ابری اجرا شود، می‌توانید از دستور زیر برای استقرار تابع با استفاده از پرچم‌های 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

برای یک تابع نسل دوم، می توانید این دستور را اجرا کنید:

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

7. عملکرد CloudEvent - Pub/Sub

شما یک تابع CloudEvent ایجاد و مستقر خواهید کرد که به رویدادهای Cloud Pub/Sub پاسخ می دهد.

ابتدا یک موضوع Cloud Pub/Sub ایجاد کنید که رویدادها را منتشر می کند:

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

با استفاده از الگوی gcf-event یک تابع CloudEvent ایجاد کنید:

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

این یک پروژه و یک فایل Function.cs ایجاد می کند که به درخواست های CloudEvent پاسخ می دهد. همچنین داده های CloudEvent را به صورت پیش فرض در StorageObjectData تجزیه می کند.

چارچوب هدف را در فایل .csproj به net8.0 تغییر دهید:

<TargetFramework>net8.0</TargetFramework>

برای تجزیه و تحلیل پیام‌های Pub/Sub، StorageObjectData به MessagePublishedData تغییر دهید. 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

اگر ترجیح می‌دهید به‌عنوان نسل دوم توابع ابری مستقر شوید، می‌توانید از دستور زیر برای استقرار تابع با استفاده از پرچم 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

برای یک تابع نسل دوم، می توانید این دستور را اجرا کنید:

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

8. عملکرد CloudEvent - بدون تایپ

اگر در حال آزمایش با CloudEvents هستید و هنوز یک مدل داده payload ندارید که می‌خواهید به آن متعهد شوید، یا می‌خواهید تابع شما بتواند هر رویداد Cloud را مدیریت کند، می‌توانید از یک تابع CloudEvent تایپ نشده استفاده کنید.

با استفاده از الگوی gcf-untyped-event یک تابع CloudEvent ایجاد کنید:

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

این یک پروژه و یک فایل Function.cs ایجاد می کند که به درخواست های CloudEvent بدون هیچ تلاشی برای تجزیه داده های CloudEvent پاسخ می دهد.

چارچوب هدف را در فایل .csproj به net8.0 تغییر دهید:

<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

اگر ترجیح می‌دهید به‌عنوان نسل دوم توابع ابری اجرا شود، می‌توانید از دستور زیر برای استقرار تابع با استفاده از پرچم‌های 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

برای یک تابع نسل دوم، می توانید این دستور را اجرا کنید:

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

9. تبریک می گویم!

برای تکمیل کد لبه تبریک می گویم.

آنچه را پوشش داده ایم

  • Functions Framework برای دات نت.
  • نحوه نوشتن یک تابع ابری HTTP
  • نحوه نوشتن یک تابع CloudEvent که به رویدادهای Cloud Storage پاسخ می دهد.
  • نحوه نوشتن یک تابع CloudEvent که به رویدادهای Cloud Pub/Sub پاسخ می دهد.
  • نحوه نوشتن یک تابع CloudEvent که به هر نوع رویدادی پاسخ می دهد.