1. مقدمة
نظرة عامة
يوضّح لك هذا البرنامج التعليمي كيفية تفعيل مجموعة من العاملين (المستهلكين) في Cloud Run لمعالجة رسائل Pub/Sub، وتوسيع نطاق مثيلات المستهلكين تلقائيًا استنادًا إلى عمق قائمة الانتظار باستخدام التوسيع التلقائي للمقاييس الخارجية في Cloud Run (CREMA).
أهداف الدورة التعليمية
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على ما يلي:
- أنشئ موضوعًا واشتراكًا في Pub/Sub وادفع الرسائل إلى هذا الموضوع.
- نشر مجموعة من العاملين (المستهلكين) في Cloud Run تستهلك الرسائل من Pub/Sub
- انشر مشروع CREMA على GitHub كخدمة Cloud Run لتوسيع مجموعة العاملين تلقائيًا استنادًا إلى عدد الرسائل في اشتراك Pub/Sub.
- اختبِر إعدادات التوسيع التلقائي من خلال إنشاء حمل عن طريق تشغيل نص برمجي Python محليًا.
2. ضبط متغيرات البيئة
بما أنّه يتم استخدام العديد من متغيرات البيئة في جميع أنحاء هذا الدرس التطبيقي حول الترميز، ننصحك بتنفيذ
set -u
التي ستنبّهك إذا حاولت استخدام متغيّر بيئة لم يتم ضبطه بعد. للتراجع عن هذا الإعداد، نفِّذ الأمر set +u
أولاً، غيِّر المتغيّر التالي إلى رقم تعريف مشروعك.
export PROJECT_ID=<YOUR_PROJECT_ID>
ثم اضبطه كمشروع لهذا الدرس العملي.
gcloud config set project $PROJECT_ID
بعد ذلك، اضبط متغيّرات البيئة المستخدَمة في هذا الدرس التطبيقي.
export REGION=us-central1
export TOPIC_ID=crema-pubsub-topic
export SUBSCRIPTION_ID=crema-pubsub-sub
export CREMA_SA_NAME=crema-service-account
export CONSUMER_SA_NAME=consumer-service-account
export CONSUMER_WORKER_POOL_NAME=worker-pool-consumer
export CREMA_SERVICE_NAME=my-crema-service
إنشاء دليل لهذا الدرس التطبيقي حول الترميز
mkdir crema-pubsub-codelab
cd crema-pubsub-codelab
تفعيل واجهات برمجة التطبيقات
gcloud services enable \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
run.googleapis.com \
parametermanager.googleapis.com
أخيرًا، تأكَّد من أنّ gcloud يستخدم أحدث إصدار.
gcloud components update
3- إعداد Pub/Sub
أنشئ الموضوع واشتراك السحب الذي ستعالجه مجموعة العمال. Bash
أنشئ الموضوع.
gcloud pubsub topics create $TOPIC_ID
أنشئ الاشتراك.
gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic=$TOPIC_ID
4. إدارة الهوية وإمكانية الوصول وحسابات الخدمة
يُنصح بإنشاء حساب خدمة لكل مورد من موارد Cloud Run. في هذا الدرس التطبيقي حول الترميز، ستنشئ ما يلي:
- حساب الخدمة للمستهلك: هوية مجموعة العاملين التي تعالج رسائل Pub/Sub.
- CREMA SA: هوية خدمة التحجيم التلقائي CREMA
إنشاء حسابات خدمة
أنشئ حساب الخدمة المستهلك لمجموعة العمّال:
gcloud iam service-accounts create $CONSUMER_SA_NAME \
--display-name="PubSub Consumer Service Account"
أنشئ حساب خدمة CREMA في مجموعة العمّال:
gcloud iam service-accounts create $CREMA_SA_NAME \
--display-name="CREMA Autoscaler Service Account"
منح الأذونات إلى Consumer SA
امنح أذونات لحساب الخدمة المستهلك لمجموعة العمال لسحب الرسائل من الاشتراك.
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.subscriber"
منح الأذونات إلى CREMA SA
يحتاج CREMA إلى أذونات لقراءة المَعلمات وتوسيع مجموعة العاملين وتتبُّع مقاييس Pub/Sub.
- الوصول إلى "مدير المَعلمات" (أداة قراءة الإعدادات):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/parametermanager.parameterViewer"
- توسيع نطاق مجموعة العمال (Cloud Run Developer):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.developer"
- مراقبة Pub/Sub:
منح دور "مُشاهد المراقبة"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/monitoring.viewer"
إضافة سياسة إلى الاشتراك في خدمة CREMA SA للاطّلاع عليها
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.viewer"
يحتاج حساب الخدمة CREMA أيضًا إلى دور "مستخدم حساب الخدمة"، وهو مطلوب لتغيير أعداد المثيلات:
gcloud iam service-accounts add-iam-policy-binding \
$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
5- التحقّق من أذونات المشرف الفائق
قبل المتابعة مع الدرس التطبيقي حول الترميز، تأكَّد من أنّ حساب الخدمة CREMA لديه الأدوار الصحيحة على مستوى المشروع.
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
من المفترض أن يؤدي ذلك إلى ما يلي:
roles/monitoring.viewer
roles/parametermanager.parameterViewer
roles/run.developer
تأكَّد من أنّ اشتراك Pub/Sub يتضمّن سياسة تسمح لحساب الخدمة CREMA بعرضه.
gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--format="table(bindings.role)"
يجب أن يؤدي ذلك إلى
roles/pubsub.viewer
والتحقّق من أنّ حساب الخدمة CREMA لديه دور "مستخدم حساب الخدمة"
gcloud iam service-accounts get-iam-policy \
$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
يجب أن يؤدي ذلك إلى ما يلي
bindings:
members: serviceAccount:crema-service-account@<PROJECT_ID>.iam.gserviceaccount.com
role: roles/iam.serviceAccountUser
ويتم منح حساب الخدمة Worker Pool Consumer دور المشترك في Pub/Sub
gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--format="table(bindings.role)"
يجب أن يؤدي ذلك إلى
ROLE
roles/pubsub.subscriber
6. إنشاء مجموعة العمّال المستهلكين ونشرها
أنشئ دليلاً لرمز المستهلك وأدخِله.
mkdir consumer
cd consumer
- إنشاء ملف
consumer.py
import os
import time
from google.cloud import pubsub_v1
from concurrent.futures import TimeoutError
# Configuration
PROJECT_ID = os.environ.get('PROJECT_ID')
SUBSCRIPTION_ID = os.environ.get('SUBSCRIPTION_ID')
subscription_path = f"projects/{PROJECT_ID}/subscriptions/{SUBSCRIPTION_ID}"
print(f"Worker Pool instance starting. Watching {subscription_path}...")
subscriber = pubsub_v1.SubscriberClient()
def callback(message):
try:
data = message.data.decode("utf-8")
print(f"Processing job: {data}")
time.sleep(5) # Simulate work
print(f"Done {data}")
message.ack()
except Exception as e:
print(f"Error processing message: {e}")
message.nack()
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}...")
# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
try:
# When `timeout` is not set, result() will block indefinitely,
# unless an exception is encountered first.
streaming_pull_future.result()
except TimeoutError:
streaming_pull_future.cancel() # Trigger the shutdown.
streaming_pull_future.result() # Block until the shutdown is complete.
except Exception as e:
print(f"Streaming pull failed: {e}")
- إنشاء
Dockerfile
FROM python:3.12-slim
RUN pip install google-cloud-pubsub
COPY consumer.py .
CMD ["python", "-u", "consumer.py"]
- نشر مجموعة العمّال المستهلكين
يوصي هذا الدرس التطبيقي حول الترميز بنشر مجموعة العمال مع 0 مثيل في البداية، حتى تتمكّن من مشاهدة CREMA وهي توسّع مجموعة العمال عندما ترصد رسائل Pub/Sub في الاشتراك.
gcloud beta run worker-pools deploy $CONSUMER_WORKER_POOL_NAME \
--source . \
--region $REGION \
--service-account="$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--instances=0 \
--set-env-vars PROJECT_ID=$PROJECT_ID,SUBSCRIPTION_ID=$SUBSCRIPTION_ID
7. ضبط CREMA
- انتقِل مجددًا إلى الدليل الجذر لمشروعك.
cd ..
- إنشاء ملف الإعداد أنشئ ملفًا باسم
crema-config.yaml
apiVersion: crema/v1
kind: CremaConfig
spec:
pollingInterval: 30
triggerAuthentications:
- metadata:
name: adc-trigger-auth
spec:
podIdentity:
provider: gcp
scaledObjects:
- spec:
scaleTargetRef:
name: projects/PROJECT_ID_PLACEHOLDER/locations/REGION_PLACEHOLDER/workerpools/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER
triggers:
- type: gcp-pubsub
metadata:
subscriptionName: "SUBSCRIPTION_ID_PLACEHOLDER"
# Target number of undelivered messages per worker instance
value: "10"
mode: "SubscriptionSize"
authenticationRef:
name: adc-trigger-auth
- استبدال المتغيّرات
sed -i "s/PROJECT_ID_PLACEHOLDER/$PROJECT_ID/g" crema-config.yaml
sed -i "s/REGION_PLACEHOLDER/$REGION/g" crema-config.yaml
sed -i "s/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER/$CONSUMER_WORKER_POOL_NAME/g" crema-config.yaml
sed -i "s/SUBSCRIPTION_ID_PLACEHOLDER/$SUBSCRIPTION_ID/g" crema-config.yaml
- تأكَّد من صحة رقم
crema-config.yaml
if grep -q "_PLACEHOLDER" crema-config.yaml; then
echo "❌ ERROR: Validations failed. '_PLACEHOLDER' was found in crema-config.yaml."
echo "Please check your environment variables and run the 'sed' commands again."
else
echo "✅ Config check passed: No placeholders found."
fi
- التحميل إلى "أداة إدارة المَعلمات"
ضبط متغيرات بيئة إضافية لأداة "إدارة المعلَمات"
export PARAMETER_ID=crema-config
export PARAMETER_REGION=global
export PARAMETER_VERSION=1
إنشاء مورد المَعلمة
gcloud parametermanager parameters create $PARAMETER_ID \
--location=$PARAMETER_REGION \
--parameter-format=YAML
إنشاء الإصدار 1 من المَعلمة
gcloud parametermanager parameters versions create $PARAMETER_VERSION \
--parameter=crema-config \
--project=$PROJECT_ID \
--location=$PARAMETER_REGION \
--payload-data-from-file=crema-config.yaml
التأكّد من إضافة المَعلمة بنجاح
gcloud parametermanager parameters versions list \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION
من المفترض أن يظهر لك محتوى مثل
projects/<YOUR_PROJECT_ID>/locations/global/parameters/crema-config/versions/1
8. تفعيل خدمة CREMA
في هذا القسم، ستنشر خدمة المقياس التلقائي CREMA. ستستخدم الصورة المتاحة للجميع.
- ضبط متغيرات البيئة اللازمة لأداة CREMA
CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
- التحقّق من مسار اسم الإصدار
echo $CREMA_CONFIG_PARAM_VERSION
يجب أن يبدو على النحو التالي
projects/<YOUR_PROJECT>/locations/global/parameters/crema-config/versions/1
- ضبط متغير البيئة لصورة CREMA
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0
- ونشر خدمة CREMA
يُرجى العِلم أنّ الصورة الأساسية مطلوبة.
gcloud beta run deploy $CREMA_SERVICE_NAME \
--image=$IMAGE \
--region=${REGION} \
--service-account="${CREMA_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--no-allow-unauthenticated \
--no-cpu-throttling \
--labels=created-by=crema \
--base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-24/runtimes/java25 \
--set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True,ENABLE_CLOUD_LOGGING=True"
9- اختبار التحميل
- إنشاء نص برمجي ينشر الرسائل إلى موضوع Pub/Sub
touch load-pubsub.sh
- أضِف الرمز التالي إلى ملف
load-pubsub.sh
#!/bin/bash
TOPIC_ID=${TOPIC_ID}
PROJECT_ID=${PROJECT_ID}
NUM_MESSAGES=100
echo "Publishing $NUM_MESSAGES messages to topic $TOPIC_ID..."
for i in $(seq 1 $NUM_MESSAGES); do
gcloud pubsub topics publish $TOPIC_ID --message="job-$i" --project=$PROJECT_ID &
if (( $i % 10 == 0 )); then
wait
echo "Published $i messages..."
fi
done
wait
echo "Done. All messages published."
- إجراء اختبار التحميل
chmod +x load-pubsub.sh
./load-pubsub.sh
- انتظِر من 3 إلى 4 دقائق أثناء مراقبة عملية تغيير الحجم. اطّلِع على سجلّات CREMA لترى اقتراحاتها بشأن الآلات الافتراضية استنادًا إلى إعداد authenticationRef الجديد.
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$CREMA_SERVICE_NAME AND textPayload:SCALER" \
--limit=20 \
--format="value(textPayload)" \
--freshness=5m
- مراقبة المعالجة: اطّلِع على سجلّات المستهلك لمعرفة ما إذا كانت قيد التشغيل.
gcloud beta run worker-pools logs tail $CONSUMER_WORKER_POOL_NAME --region=$REGION
من المفترض أن تظهر لك سجلّات مشابهة لما يلي:
Done job-100
10. تحديد المشاكل وحلّها
أولاً، عليك تحديد ما إذا كانت المشكلة في إعدادات خدمة CREMA أو في إعدادات مستهلك PubSub.
اضبط أداة القياس التلقائي لمستهلك PubSub على 1 بدلاً من 0. إذا بدأت على الفور في معالجة رسائل pubsub، يعني ذلك أنّ هناك مشكلة في CREMA. إذا لم تتم معالجة رسائل pubsub، يعني ذلك أنّ هناك مشكلة في مستهلك pubsub.
11. تهانينا!
تهانينا على إكمال هذا الدرس العملي.
ننصحك بمراجعة مستندات Cloud Run.
المواضيع التي تناولناها
- كيفية إنشاء موضوع واشتراك في Pub/Sub وإرسال الرسائل إلى هذا الموضوع
- كيفية نشر مجموعة عاملة (مستهلك) في Cloud Run تستهلك الرسائل من Pub/Sub
- كيفية نشر مشروع CREMA على GitHub كخدمة Cloud Run لتوسيع مجموعة العاملين تلقائيًا استنادًا إلى عدد الرسائل في اشتراك Pub/Sub
- كيفية اختبار إعدادات التوسيع التلقائي من خلال إنشاء حمل عن طريق تشغيل نص برمجي بلغة Python محليًا
12. تَنظيم
لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا الدليل التعليمي، يمكنك إما حذف الموارد التي أنشأتها في هذا الدرس التطبيقي حول الترميز أو حذف المشروع بأكمله.
حذف الموارد المستخدَمة في هذا الدرس التطبيقي حول الترميز
- حذف خدمة CREMA في Cloud Run
gcloud run services delete $CREMA_SERVICE_NAME --region=$REGION --quiet
- حذف مستهلك مجموعة العاملين في Cloud Run
gcloud beta run worker-pools delete $CONSUMER_WORKER_POOL_NAME --region=$REGION --quiet
- حذف اشتراك وموضوع Pub/Sub
gcloud pubsub subscriptions delete $SUBSCRIPTION_ID --quiet
gcloud pubsub topics delete $TOPIC_ID --quiet
- حذف إعداد "مدير المَعلمات"
حذف الإصدار داخل المَعلمة
gcloud parametermanager parameters versions delete $PARAMETER_VERSION \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
الآن، احذف المَعلمة الفارغة.
gcloud parametermanager parameters delete $PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
- حذف حسابات الخدمة
gcloud iam service-accounts delete "$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
gcloud iam service-accounts delete "$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
أو حذف المشروع بأكمله
لحذف المشروع بأكمله، انتقِل إلى إدارة المراجع، واختَر المشروع الذي أنشأته في الخطوة 2، ثم انقر على "حذف". إذا حذفت المشروع، عليك تغيير المشاريع في Cloud SDK. يمكنك الاطّلاع على قائمة بجميع المشاريع المتاحة من خلال تنفيذ gcloud projects list.