1. مقدمة
وظائف Google Cloud Run هي منصة حوسبة بدون خادم مستنِدة إلى الأحداث. تتيح لك دوال Cloud Run كتابة الرمز بدون القلق بشأن توفير الموارد أو توسيع نطاقها للتعامل مع المتطلبات المتغيرة.
يتوفّر نوعان من وظائف Cloud Run:
- تستجيب دوال HTTP لطلبات HTTP.
- يتم تشغيل دوال الأحداث بواسطة أحداث، مثل نشر رسالة إلى Cloud Pub/Sub أو تحميل ملف إلى Cloud Storage.

سيرشدك هذا الدرس التطبيقي حول الترميز إلى كيفية إنشاء دوال Cloud Run الخاصة بك بلغة C#. على وجه التحديد، ستنشئ دوال C# تستجيب لطلبات HTTP وCloudEvents من مصادر مختلفة في Google Cloud.
أهداف الدورة التعليمية
- إطار عمل الدوال لـ .NET
- كيفية كتابة دالة HTTP
- كيفية كتابة دالة يتم تشغيلها عند وقوع حدث استجابةً لأحداث Cloud Storage
- كيفية كتابة دالة يتم تشغيلها عند وقوع حدث استجابةً لأحداث Cloud Pub/Sub
- كيفية كتابة دالة يتم تشغيلها عند وقوع حدث وتستجيب لأي نوع من الأحداث
2. الإعداد والمتطلبات
إعداد البيئة بالسرعة التي تناسبك
- سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.



- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديله في أي وقت.
- يجب أن يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud، كما أنّه غير قابل للتغيير (لا يمكن تغييره بعد ضبطه). تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس البرمجة، عليك الرجوع إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه
PROJECT_ID). إذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم مستخدم من اختيارك لمعرفة ما إذا كان متاحًا. لا يمكن تغيير هذا الخيار بعد هذه الخطوة وسيظل ساريًا طوال مدة المشروع. - للعلم، هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز الكثير من المال، إن لم تكلفك شيئًا على الإطلاق. لإيقاف الموارد كي لا يتم تحصيل رسوم منك بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بأكمله. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.
بدء Cloud Shell
على الرغم من إمكانية تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدرس العملي Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.
من Google Cloud Console، انقر على رمز Cloud Shell في شريط الأدوات العلوي على يسار الصفحة:

لن يستغرق توفير البيئة والاتصال بها سوى بضع لحظات. عند الانتهاء، من المفترض أن يظهر لك ما يلي:

يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. توفّر هذه الخدمة دليلًا منزليًا ثابتًا بسعة 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 for .NET
Functions Framework for .NET هو إطار عمل مفتوح المصدر للوظائف كخدمة (FaaS) يتيح كتابة وظائف .NET قابلة للنقل، وهو من تطوير فريق Google Cloud Functions.
يتيح لك Functions Framework كتابة دوال بسيطة تعمل في العديد من البيئات المختلفة، بما في ذلك:
- دوال Google Cloud Run
- جهاز التطوير المحلي
- Cloud Run وCloud Run على GKE
- البيئات المستندة إلى Knative
في هذا الدرس التطبيقي حول الترميز، ستستخدم Functions Framework for .NET وقوالبه لإنشاء Cloud Functions وتفعيلها في 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
إذا كنت تفضّل النشر كـ "الجيل الثاني من 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
6. CloudEvent Function - 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
إذا كنت تفضّل النشر كـ "الجيل الثاني من Cloud Functions"، يمكنك استخدام الأمر التالي لنشر الدالة باستخدام العلامتَين 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:

يمكنك تشغيل الدالة من خلال تحميل ملف إلى حزمة التخزين:
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}
أنشئ دالة 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
إذا كنت تفضّل النشر كـ "الجيل الثاني من Cloud Functions"، يمكنك استخدام الأمر التالي لنشر الدالة باستخدام العلامة 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:

فعِّل الدالة من خلال نشر رسالة في الموضوع:
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 ولم يكن لديك بعد نموذج بيانات حمولة تريد الالتزام به، أو إذا كنت تريد أن تكون وظيفتك قادرة على التعامل مع أي Cloud Event، يمكنك استخدام وظيفة 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
إذا كنت تفضّل النشر كـ "الجيل الثاني من Cloud Functions"، يمكنك استخدام الأمر التالي لنشر الدالة باستخدام العلامتَين 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:

يمكنك تشغيل الدالة من خلال تحميل ملف إلى حزمة التخزين:
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- تهانينا!
تهانينا على إكمال هذا الدرس العملي.
المواضيع التي تناولناها
- إطار عمل الدوال لـ .NET
- كيفية كتابة دالة Cloud Function تستند إلى HTTP
- كيفية كتابة دالة CloudEvent تستجيب لأحداث Cloud Storage
- كيفية كتابة دالة CloudEvent تستجيب لأحداث Cloud Pub/Sub
- كيفية كتابة دالة CloudEvent تستجيب لأي نوع من الأحداث