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

۱. مقدمه

توابع 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
  • نحوه نوشتن یک تابع Event Triggered که به رویدادهای Cloud Storage پاسخ می‌دهد.
  • نحوه نوشتن یک تابع Event Triggered که به رویدادهای Cloud Pub/Sub پاسخ می‌دهد.
  • چگونه یک تابع فعال شونده توسط رویداد بنویسیم که به هر نوع رویدادی پاسخ دهد.

۲. تنظیمات و الزامات

تنظیم محیط خودتنظیم

  1. وارد کنسول گوگل کلود شوید و یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید. اگر از قبل حساب جیمیل یا گوگل ورک اسپیس ندارید، باید یکی ایجاد کنید .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • نام پروژه ، نام نمایشی برای شرکت‌کنندگان این پروژه است. این یک رشته کاراکتری است که توسط APIهای گوگل استفاده نمی‌شود. می‌توانید آن را در هر زمانی به‌روزرسانی کنید.
  • شناسه پروژه باید در تمام پروژه‌های گوگل کلود منحصر به فرد باشد و تغییرناپذیر است (پس از تنظیم، قابل تغییر نیست). کنسول کلود به طور خودکار یک رشته منحصر به فرد تولید می‌کند؛ معمولاً برای شما مهم نیست که چیست. در اکثر آزمایشگاه‌های کد، باید شناسه پروژه را ارجاع دهید (که معمولاً با عنوان PROJECT_ID شناخته می‌شود). اگر شناسه تولید شده را دوست ندارید، می‌توانید یک شناسه تصادفی دیگر ایجاد کنید. به عنوان یک جایگزین، می‌توانید شناسه خودتان را امتحان کنید و ببینید که آیا در دسترس است یا خیر. پس از این مرحله قابل تغییر نیست و در طول پروژه باقی خواهد ماند.
  • برای اطلاع شما، یک مقدار سوم هم وجود دارد، شماره پروژه که برخی از APIها از آن استفاده می‌کنند. برای کسب اطلاعات بیشتر در مورد هر سه این مقادیر، به مستندات مراجعه کنید.
  1. در مرحله بعد، برای استفاده از منابع/API های ابری، باید پرداخت صورتحساب را در کنسول ابری فعال کنید . اجرای این آزمایشگاه کد، اگر اصلاً هزینه‌ای نداشته باشد، هزینه زیادی نخواهد داشت. برای خاموش کردن منابع به طوری که پس از این آموزش متحمل پرداخت صورتحساب نشوید، می‌توانید منابعی را که ایجاد کرده‌اید یا کل پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان ۳۰۰ دلاری هستند.

شروع پوسته ابری

اگرچه می‌توان از راه دور و از طریق لپ‌تاپ، گوگل کلود را مدیریت کرد، اما در این آزمایشگاه کد، از گوگل کلود شل ، یک محیط خط فرمان که در فضای ابری اجرا می‌شود، استفاده خواهید کرد.

از کنسول گوگل کلود ، روی آیکون Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

55efc1aaa7a4d3ad.png

آماده‌سازی و اتصال به محیط فقط چند لحظه طول می‌کشد. وقتی تمام شد، باید چیزی شبیه به این را ببینید:

7ffe5cbb04455448.png

این ماشین مجازی با تمام ابزارهای توسعه‌ای که نیاز دارید، مجهز شده است. این ماشین مجازی یک دایرکتوری خانگی پایدار ۵ گیگابایتی ارائه می‌دهد و روی فضای ابری گوگل اجرا می‌شود که عملکرد شبکه و احراز هویت را تا حد زیادی بهبود می‌بخشد. تمام کارهای شما در این آزمایشگاه کد را می‌توان در یک مرورگر انجام داد. نیازی به نصب چیزی ندارید.

۳. قبل از شروع

در داخل 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 Event Receiver (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

۴. چارچوب توابع برای دات‌نت

چارچوب توابع برای .NET یک چارچوب FaaS (تابع به عنوان سرویس) متن‌باز برای نوشتن توابع قابل حمل .NET است که توسط تیم توابع Google Cloud ارائه شده است.

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

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

در این آزمایشگاه کد، شما از چارچوب توابع برای .NET و قالب‌های آن برای ایجاد و استقرار توابع ابری در C# استفاده خواهید کرد.

در داخل Cloud Shell، دستور زیر را برای نصب قالب‌های Cloud Functions برای dotnet اجرا کنید:

dotnet new install Google.Cloud.Functions.Templates

این دستور ۳ قالب برای 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

۵. تابع 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

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

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

۶. تابع CloudEvent - GCS

شما یک تابع CloudEvent ایجاد و مستقر خواهید کرد که به رویدادهای Google Cloud Storage (GCS) پاسخ می‌دهد.

ابتدا، یک مخزن ذخیره‌سازی ابری ایجاد کنید. این مخزنی است که بعداً رویدادها را از آن گوش خواهید داد:

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

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

۷. تابع 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

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

۳۴۴۳۸۰۸da7caf3bc.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

۸. تابع CloudEvent - بدون نوع

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

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

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

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

۹. تبریک می‌گویم!

تبریک می‌گویم که آزمایشگاه کد را تمام کردی.

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

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