۱. مرور کلی
در آزمایشهای قبلی، شما یک نسخه رویداد-محور از برنامه Pic-a-daily ساختید که از یک تابع ابری فعالشده توسط Google Cloud Storage برای سرویس تحلیل تصویر، یک کانتینر Cloud Run فعالشده توسط GCS از طریق Pub/Sub برای سرویس Thumbnail و Eventarc برای فعالسازی سرویس Image Garbage Collector در Cloud Run استفاده میکرد. همچنین یک سرویس کلاژ فعالشده توسط Cloud Scheduler نیز وجود داشت:

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

آنچه یاد خواهید گرفت
- موتور برنامه
- فروشگاه ابری فایر استور
- توابع ابری
- اجرای ابری
- گردشهای کاری
۲. تنظیمات و الزامات
تنظیم محیط خودتنظیم
- وارد Cloud Console شوید و یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید. (اگر از قبل حساب Gmail یا Google Workspace ندارید، باید یکی ایجاد کنید .)



شناسه پروژه را به خاطر بسپارید، یک نام منحصر به فرد در تمام پروژههای Google Cloud (نام بالا قبلاً گرفته شده و برای شما کار نخواهد کرد، متاسفیم!). بعداً در این آزمایشگاه کد به آن PROJECT_ID گفته خواهد شد.
- در مرحله بعد، برای استفاده از منابع گوگل کلود، باید پرداخت را در Cloud Console فعال کنید .
اجرای این آزمایشگاه کد، اگر اصلاً هزینهای نداشته باشد، نباید هزینه زیادی داشته باشد. حتماً دستورالعملهای بخش «پاکسازی» را که به شما نحوه خاموش کردن منابع را آموزش میدهد، دنبال کنید تا پس از این آموزش، متحمل هزینه نشوید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان ۳۰۰ دلاری هستند.
شروع پوسته ابری
اگرچه میتوان از راه دور و از طریق لپتاپ، گوگل کلود را مدیریت کرد، اما در این آزمایشگاه کد، از گوگل کلود شل ، یک محیط خط فرمان که در فضای ابری اجرا میشود، استفاده خواهید کرد.
از کنسول GCP روی آیکون Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

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

این ماشین مجازی مجهز به تمام ابزارهای توسعه مورد نیاز شماست. این ماشین یک دایرکتوری خانگی دائمی ۵ گیگابایتی ارائه میدهد و روی فضای ابری گوگل اجرا میشود که عملکرد شبکه و احراز هویت را تا حد زیادی بهبود میبخشد. تمام کارهای شما در این آزمایشگاه را میتوان به سادگی با یک مرورگر انجام داد.
۳. مقدمهای بر گردشهای کاری

شما میتوانید از Workflowها برای ایجاد گردشهای کاری بدون سرور استفاده کنید که مجموعهای از وظایف بدون سرور را به ترتیبی که شما تعریف میکنید، به هم پیوند میدهند. میتوانید قدرت APIهای Google Cloud، محصولات بدون سرور مانند Cloud Functions و Cloud Run و فراخوانیهای APIهای خارجی را برای ایجاد برنامههای بدون سرور انعطافپذیر ترکیب کنید.
همانطور که از یک هماهنگکننده انتظار میرود، Workflows به شما امکان میدهد جریان منطق کسبوکار خود را در یک زبان تعریف گردش کار مبتنی بر YAML/JSON تعریف کنید و یک API اجرای گردشهای کار و رابط کاربری گردشهای کار را برای راهاندازی آن جریانها فراهم میکند.
این نرمافزار با ویژگیهای داخلی و قابل تنظیم زیر، چیزی بیش از یک هماهنگکنندهی صرف است:
- قابلیت انعطافپذیری در تلاش مجدد و مدیریت خطا بین مراحل برای اجرای مطمئن مراحل.
- تجزیه JSON و ارسال متغیر بین مراحل برای جلوگیری از کد چسبی.
- فرمولهای بیان برای تصمیمگیریها، اجرای مراحل شرطی را امکانپذیر میکنند.
- زیرگردشهای کاری برای گردشهای کاری ماژولار و قابل استفاده مجدد.
- پشتیبانی از سرویسهای خارجی، امکان هماهنگسازی سرویسهایی فراتر از Google Cloud را فراهم میکند.
- پشتیبانی از احراز هویت برای Google Cloud و سرویسهای خارجی برای اجرای امن مراحل.
- اتصال به سرویسهای ابری گوگل مانند Pub/Sub، Firestore، Tasks و Secret Manager برای یکپارچهسازی آسانتر.
ناگفته نماند، Workflows یک محصول کاملاً مدیریتشده بدون سرور است. هیچ سروری برای پیکربندی یا مقیاسبندی وجود ندارد و شما فقط برای آنچه استفاده میکنید هزینه پرداخت میکنید.
۴. فعال کردن APIها
در این آزمایشگاه، شما سرویسهای Cloud Functions و Cloud Run را با Workflows متصل خواهید کرد. همچنین از App Engine، Cloud Build، Vision API و سایر سرویسها استفاده خواهید کرد.
در Cloud Shell، مطمئن شوید که تمام سرویسهای لازم فعال هستند:
gcloud services enable \ appengine.googleapis.com \ cloudbuild.googleapis.com \ cloudfunctions.googleapis.com \ compute.googleapis.com \ firestore.googleapis.com \ run.googleapis.com \ vision.googleapis.com \ workflows.googleapis.com \
پس از مدتی، باید ببینید که عملیات با موفقیت به پایان رسیده است:
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
۵. کد را دریافت کنید
اگر کد را در آزمایشگاههای کد قبلی دریافت نکردهاید، آن را دریافت کنید:
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
ساختار پوشهای زیر را خواهید داشت که برای این تمرین مرتبط است:
frontend | workflows | ├── functions ├── |── trigger-workflow ├── |── vision-data-transform ├── services ├── |── collage ├── |── thumbnails ├── workflows.yaml
اینم پوشههای مربوطه:
-
frontendشامل بخش frontend مربوط به App Engine است که از تمرین چهارم دوباره از آن استفاده خواهیم کرد. -
functionsشامل توابع ابری ایجاد شده برای گردش کار است. -
servicesشامل سرویسهای Cloud Run اصلاحشده برای گردش کار هستند. -
workflows.yamlفایل تعریف گردش کار است.
۶. گردشهای کاری YAML را بررسی کنید
فایل workflows.yaml، گردش کار را در یک سری مراحل تعریف میکند. بیایید برای درک بهتر آن را بررسی کنیم.
در ابتدای گردش کار، پارامترهایی وجود دارند که ارسال میشوند. این پارامترها توسط دو تابع ابری که گردشهای کاری را فعال میکنند، ارسال میشوند. بعداً به این توابع خواهیم پرداخت، اما نحوه شروع گردشهای کاری به این صورت است:

In YAML, you can see that these parameters are assigned to variables in the init step such as the file and bucket names triggering the event, and URLs of some Cloud Functions and Cloud Run services that Workflows will call:
main:
params: [args]
steps:
- init:
assign:
- file: ${args.file}
- bucket: ${args.bucket}
- gsUri: ${"gs://" + bucket + "/" + file}
- projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
- urls: ${args.urls}
در مرحله بعد، Workflowها نوع رویداد را بررسی میکنند. دو نوع رویداد پشتیبانی میشوند: object.finalize (زمانی که یک فایل در فضای ذخیرهسازی ابری ذخیره میشود، منتشر میشود) و object.delete (زمانی که یک فایل حذف میشود، منتشر میشود). هر چیز دیگری باعث ایجاد خطای event not supported میشود.

این مرحله در تعریف گردش کار YAML است که در آن نوع رویداد ذخیرهسازی فایل را بررسی میکنیم:
- eventTypeSwitch:
switch:
- condition: ${args.eventType == "google.storage.object.finalize"}
next: imageAnalysisCall
- condition: ${args.eventType == "google.storage.object.delete"}
next: pictureGarbageCollectionGCS
- eventTypeNotSupported:
raise: ${"eventType " + args.eventType + " is not supported"}
next: end
توجه کنید که چگونه Workflows از دستورات switch و مدیریت استثنا پشتیبانی میکند، با دستور switch و شرایط مختلف آن، و دستور raise برای ایجاد خطا زمانی که رویداد تشخیص داده نمیشود.
در مرحله بعد، بیایید نگاهی به imageAnalysisCall بیندازیم. این یک سری فراخوانی از Workflows برای فراخوانی Vision API جهت تجزیه و تحلیل تصویر، تبدیل دادههای پاسخ Vision API برای مرتبسازی برچسبهای موارد شناسایی شده در تصویر، انتخاب رنگهای غالب، بررسی ایمن بودن نمایش تصویر و سپس ذخیره ابرداده در Cloud Firestore است.
توجه داشته باشید که همه چیز در Workflows انجام میشود به جز توابع Vision Transform Cloud (که بعداً آنها را مستقر خواهیم کرد):

مراحل در YAML به این صورت است:
- imageAnalysisCall:
call: http.post
args:
url: https://vision.googleapis.com/v1/images:annotate
headers:
Content-Type: application/json
auth:
type: OAuth2
body:
requests:
- image:
source:
gcsImageUri: ${gsUri}
features:
- type: LABEL_DETECTION
- type: SAFE_SEARCH_DETECTION
- type: IMAGE_PROPERTIES
result: imageAnalysisResponse
- transformImageAnalysisData:
call: http.post
args:
url: ${urls.VISION_DATA_TRANSFORM_URL}
auth:
type: OIDC
body: ${imageAnalysisResponse.body}
result: imageMetadata
- checkSafety:
switch:
- condition: ${imageMetadata.body.safe == true}
next: storeMetadata
next: end
- storeMetadata:
call: http.request
args:
url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file + "?updateMask.fieldPaths=color&updateMask.fieldPaths=labels&updateMask.fieldPaths=created"}
auth:
type: OAuth2
method: PATCH
body:
name: ${"projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
fields:
color:
stringValue: ${imageMetadata.body.color}
created:
timestampValue: ${imageMetadata.body.created}
labels:
arrayValue:
values: ${imageMetadata.body.labels}
result: storeMetadataResponse
پس از تجزیه و تحلیل تصویر، دو مرحله بعدی ایجاد تصویر بندانگشتی از تصویر و یک کلاژ از جدیدترین تصاویر است. این کار با استقرار دو سرویس Cloud Run و فراخوانی آنها از مراحل thumbnailCall و collageCall انجام میشود:

مراحل در YAML:
- thumbnailCall:
call: http.post
args:
url: ${urls.THUMBNAILS_URL}
auth:
type: OIDC
body:
gcsImageUri: ${gsUri}
result: thumbnailResponse
- collageCall:
call: http.get
args:
url: ${urls.COLLAGE_URL}
auth:
type: OIDC
result: collageResponse
این شاخه از اجرا با برگرداندن کدهای وضعیت از هر سرویس در مرحله finalizeCompleted به پایان میرسد:
- finalizeCompleted:
return:
imageAnalysis: ${imageAnalysisResponse.code}
storeMetadata: ${storeMetadataResponse.code}
thumbnail: ${thumbnailResponse.code}
collage: ${collageResponse.code}
شاخهی دیگر اجرا زمانی است که یک فایل از سطل ذخیرهسازی اصلی که حاوی نسخههای با وضوح بالای تصاویر است، حذف میشود. در این شاخه، میخواهیم تصویر کوچک تصویر را در سطل حاوی تصاویر کوچک حذف کنیم و فرادادههای آن را از Firestore حذف کنیم. هر دوی اینها با فراخوانیهای HTTP از Workflows انجام میشوند:

مراحل در YAML:
- pictureGarbageCollectionGCS:
try:
call: http.request
args:
url: ${"https://storage.googleapis.com/storage/v1/b/thumbnails-" + projectId + "/o/" + file}
auth:
type: OAuth2
method: DELETE
result: gcsDeletionResult
except:
as: e
steps:
- dummyResultInOutVar:
assign:
- gcsDeletionResult:
code: 200
body: "Workaround for empty body response"
- pictureGarbageCollectionFirestore:
call: http.request
args:
url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
auth:
type: OAuth2
method: DELETE
result: firestoreDeletionResult
شاخهی حذف با برگرداندن نتایج/کدهای هر مرحله به پایان میرسد:
- deleteCompleted:
return:
gcsDeletion: ${gcsDeletionResult}
firestoreDeletion: ${firestoreDeletionResult.code}
در مراحل بعدی، تمام وابستگیهای خارجی گردشهای کاری را ایجاد خواهیم کرد: سطلها، توابع ابری، سرویسهای Cloud Run و پایگاه داده Firestore.
۷. سطلها را ایجاد کنید
شما به دو سطل برای تصاویر نیاز دارید: یکی برای ذخیره تصاویر اصلی با وضوح بالا و یکی برای ذخیره تصاویر کوچک.
با استفاده از ابزار gsutil یک سطل عمومی منطقهای (در این مورد در اروپا) با دسترسی یکسان برای کاربران جهت آپلود تصاویر ایجاد کنید:
export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_PICTURES}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_PICTURES}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_PICTURES}
یک سطل منطقهای عمومی دیگر برای تصاویر کوچک ایجاد کنید:
export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_THUMBNAILS}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_THUMBNAILS}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_THUMBNAILS}
با مراجعه به بخش ذخیرهسازی ابری در کنسول ابری، میتوانید دوباره بررسی کنید که سطلها ایجاد شده و عمومی هستند:

۸. تبدیل دادههای بینایی (عملکرد ابری)
Workflows.yaml با مراحل init ، eventTypeSwitch و eventTypeNotSupported شروع میشود. این مراحل تضمین میکنند که رویدادهای دریافتی از bucketها به مراحل صحیح هدایت شوند.
برای رویداد object.finalize ، مرحله imageAnalysisCall فراخوانی به Vision API برای استخراج فرادادههای تصویر ایجاد شده انجام میدهد. همه این مراحل در Workflows انجام میشوند:

در مرحله بعد، قبل از اینکه بتوانیم دادههای برگردانده شده از Vision API را در Firestore ذخیره کنیم، باید آنها را تبدیل کنیم. به طور خاص، باید:
- برچسبهای برگردانده شده برای تصویر را فهرست کنید.
- رنگ غالب تصویر را بازیابی کنید.
- مشخص کنید که آیا تصویر ایمن است یا خیر.
این کار به صورت کد در یک تابع ابری انجام میشود و Workflows به سادگی این تابع را فراخوانی میکند:

کد را کاوش کنید
تابع ابری vision-data-transform نام دارد. میتوانید کد کامل آن را در index.js بررسی کنید. همانطور که میبینید، تنها هدف این تابع انجام تبدیل JSON به JSON است تا بتوان فرادادههای تصویر را به راحتی در Firestore ذخیره کرد.
توابع را به فضای ابری منتقل کنید
به پوشه بروید:
cd workflows/functions/vision-data-transform/nodejs
منطقه مورد نظر خود را تنظیم کنید:
export REGION=europe-west1
gcloud config set functions/region ${REGION}
تابع را با موارد زیر مستقر کنید:
export SERVICE_NAME=vision-data-transform
gcloud functions deploy ${SERVICE_NAME} \
--source=. \
--runtime nodejs10 \
--entry-point=vision_data_transform \
--trigger-http \
--allow-unauthenticated
پس از استقرار تابع، مرحله transformImageAnalysisData در Workflows قادر خواهد بود این تابع را برای انجام تبدیل دادههای Vision API فراخوانی کند.
۹. آمادهسازی پایگاه داده
مرحله بعدی در گردشهای کاری، بررسی ایمنی تصویر از دادههای تصویر و سپس ذخیره اطلاعات مربوط به تصویر برگردانده شده توسط Vision API در پایگاه داده Cloud Firestore است، یک پایگاه داده سند NoSQL سریع، کاملاً مدیریتشده، بدون سرور و ابری:

هر دوی این موارد در Workflows انجام میشوند، اما برای ذخیرهسازی فرادادهها باید پایگاه داده Firestore را ایجاد کنید.
ابتدا، یک برنامه App engine در منطقهای که میخواهید پایگاه داده Firestore در آن قرار گیرد (یک الزام برای Firestore) ایجاد کنید:
export REGION_FIRESTORE=europe-west2
gcloud app create --region=${REGION_FIRESTORE}
در مرحله بعد، پایگاه داده Firestore را در همان منطقه ایجاد کنید:
gcloud firestore databases create --region=${REGION_FIRESTORE}
این اسناد به صورت برنامهنویسی شده در مجموعه ما ایجاد میشوند و شامل ۴ فیلد خواهند بود:
- نام (رشته): نام فایل تصویر آپلود شده که کلید سند نیز هست.
- برچسبها (آرایهای از رشتهها): برچسبهای اقلام شناساییشده توسط Vision API
- رنگ (رشته): کد رنگ هگزادسیمال رنگ غالب (مثلاً #ab12ef)
- ایجاد شده (تاریخ): مهر زمانی ذخیره شدن فرادادههای این تصویر
- تصویر بندانگشتی (boolean): یک فیلد اختیاری که در صورت ایجاد تصویر بندانگشتی برای این تصویر، وجود خواهد داشت و مقدار آن true خواهد بود.
از آنجایی که ما در Firestore به دنبال تصاویری خواهیم گشت که تصویر بندانگشتی (thumbnail) آنها موجود باشد و آنها را بر اساس تاریخ ایجاد مرتب کنیم، باید یک فهرست جستجو ایجاد کنیم. میتوانید این فهرست را با دستور زیر ایجاد کنید:
gcloud firestore indexes composite create --collection-group=pictures \ --field-config field-path=thumbnail,order=descending \ --field-config field-path=created,order=descending
توجه داشته باشید که ایجاد ایندکس میتواند تا 10 دقیقه یا بیشتر طول بکشد.
پس از ایجاد ایندکس، میتوانید آن را در Cloud Console مشاهده کنید:

مرحلهی storeMetadata در گردش کار، اکنون میتواند متادیتای تصویر را در Firestore ذخیره کند.
۱۰. سرویس تصویر بندانگشتی (Cloud Run)
مرحله بعدی در این زنجیره، ایجاد یک تصویر بندانگشتی از یک تصویر است. این کار به صورت کد در یک سرویس Cloud Run انجام میشود و Workflows این سرویس را در مرحله thumbnailCall فراخوانی میکند:

کد را کاوش کنید
سرویس Cloud Run، thumbnails نام دارد. میتوانید کد کامل آن را در index.js بررسی کنید.
ساخت و انتشار تصویر کانتینر
Cloud Run کانتینرها را اجرا میکند، اما ابتدا باید تصویر کانتینر (تعریف شده در Dockerfile ) را بسازید. Google Cloud Build میتواند برای ساخت تصاویر کانتینر و سپس میزبانی در Google Container Registry استفاده شود.
به پوشه بروید:
cd workflows/services/thumbnails/nodejs
ساخت:
export SERVICE_SRC=thumbnails
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
. \
--tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
بعد از یک یا دو دقیقه، ساخت باید با موفقیت انجام شود و کانتینر در رجیستری کانتینر گوگل مستقر شود.
استقرار در Cloud Run
برخی از متغیرها و پیکربندیهای مورد نیاز را تنظیم کنید:
export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed
با دستور زیر مستقر کنید:
gcloud run deploy ${SERVICE_NAME} \
--image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
--no-allow-unauthenticated \
--memory=1Gi \
--update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}
پس از استقرار سرویس، مرحله thumbnailCall در Workflows قادر به فراخوانی این سرویس خواهد بود.
۱۱. سرویس کلاژ (Cloud Run)
مرحله بعدی در این زنجیره، ایجاد یک کلاژ از جدیدترین تصاویر است. این کار به صورت کد در سرویس Cloud Run انجام میشود و Workflows این سرویس را در مرحله collageCall فراخوانی میکند:

کد را کاوش کنید
سرویس Cloud Run، collage نام دارد. میتوانید کد کامل آن را در index.js بررسی کنید.
ساخت و انتشار تصویر کانتینر
Cloud Run کانتینرها را اجرا میکند، اما ابتدا باید تصویر کانتینر (تعریف شده در Dockerfile ) را بسازید. Google Cloud Build میتواند برای ساخت تصاویر کانتینر و سپس میزبانی در Google Container Registry استفاده شود.
به پوشه بروید:
cd services/collage/nodejs
ساخت:
export SERVICE_SRC=collage
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
. \
--tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
بعد از یک یا دو دقیقه، ساخت باید با موفقیت انجام شود و کانتینر در رجیستری کانتینر گوگل مستقر شود.
استقرار در Cloud Run
برخی از متغیرها و پیکربندیهای مورد نیاز را تنظیم کنید:
export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed
استقرار:
gcloud run deploy ${SERVICE_NAME} \
--image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
--no-allow-unauthenticated \
--memory=1Gi \
--update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}
پس از استقرار سرویس، میتوانید بررسی کنید که هر دو سرویس در بخش Cloud Run از Cloud Console اجرا میشوند و در مرحله collageCall Workflows میتوانید این سرویس را فراخوانی کنید:

۱۲. استقرار گردشهای کاری
ما تمام وابستگیهای خارجی Workflows را مستقر کردیم. تمام مراحل باقیمانده ( finalizeCompleted ، pictureGarbageCollectionGCS ، pictureGarbageCollectionFirestore ، deleteCompleted ) میتوانند توسط خود Workflows تکمیل شوند.
وقت آن است که Workflowها را مستقر کنیم!
به پوشهای که حاوی فایل workflows.yaml است بروید و آن را با دستور زیر مستقر کنید:
export WORKFLOW_REGION=europe-west4
export WORKFLOW_NAME=picadaily-workflows
gcloud workflows deploy ${WORKFLOW_NAME} \
--source=workflows.yaml \
--location=${WORKFLOW_REGION}
ظرف چند ثانیه، گردش کار باید اجرا شود و میتوانید آن را در بخش گردشهای کاری Cloud Console مشاهده کنید:

در صورت تمایل میتوانید روی گردش کار کلیک کرده و آن را ویرایش کنید. در حین ویرایش، یک نمایش بصری زیبا از گردش کار دریافت خواهید کرد:

همچنین میتوانید Workflow را از Cloud Console به صورت دستی با پارامترهای مناسب اجرا کنید. در عوض، ما آن را به صورت خودکار در پاسخ به رویدادهای Cloud Storage در مرحله بعدی اجرا خواهیم کرد.
۱۳. محرکهای گردش کار (توابع ابری)
گردش کار مستقر و آماده است. اکنون، باید گردشهای کاری را هنگامی که یک فایل در یک مخزن ذخیرهسازی ابری ایجاد یا حذف میشود، فعال کنیم. این رویدادها به ترتیب storage.object.finalize و storage.object.delete هستند.
گردشهای کاری دارای APIها و کتابخانههای کلاینت برای ایجاد، مدیریت و اجرای گردشهای کاری هستند که میتوانید از آنها استفاده کنید. در این حالت، شما از API اجرای گردشهای کاری و به طور خاصتر از کتابخانه کلاینت Node.js آن برای راهاندازی گردش کار استفاده خواهید کرد.
شما گردشهای کاری را از تابع ابری فعال میکنید که به رویدادهای ذخیرهسازی ابری گوش میدهند. از آنجایی که یک تابع ابری فقط میتواند به یک نوع رویداد گوش دهد، شما دو تابع ابری را برای گوش دادن به رویدادهای ایجاد و حذف مستقر خواهید کرد:

کد را کاوش کنید
تابع ابری trigger-workflow نام دارد. میتوانید کد کامل آن را در index.js بررسی کنید.
توابع را به فضای ابری منتقل کنید
به پوشه بروید:
cd workflows/functions/trigger-workflow/nodejs
برخی از متغیرها و پیکربندیهای مورد نیاز را تنظیم کنید:
export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
export WORKFLOW_NAME=picadaily-workflows
export WORKFLOW_REGION=europe-west4
export COLLAGE_URL=$(gcloud run services describe collage-service --format 'value(status.url)')
export THUMBNAILS_URL=$(gcloud run services describe thumbnails-service --format 'value(status.url)')
export VISION_DATA_TRANSFORM_URL=$(gcloud functions describe vision-data-transform --format 'value(httpsTrigger.url)')
gcloud config set functions/region ${REGION}
تابعی را که به رویدادهای نهایی پاسخ میدهد، مستقر کنید:
export SERVICE_NAME=trigger-workflow-on-finalize
gcloud functions deploy ${SERVICE_NAME} \
--source=. \
--runtime nodejs10 \
--entry-point=trigger_workflow \
--trigger-resource=${BUCKET_PICTURES} \
--trigger-event=google.storage.object.finalize \
--allow-unauthenticated \
--set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}
تابع دوم را که به رویدادهای حذف پاسخ میدهد، پیادهسازی کنید:
export SERVICE_NAME=trigger-workflow-on-delete
gcloud functions deploy ${SERVICE_NAME} \
--source=. \
--runtime nodejs10 \
--entry-point=trigger_workflow \
--trigger-resource=${BUCKET_PICTURES} \
--trigger-event=google.storage.object.delete \
--allow-unauthenticated \
--set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}
وقتی استقرار کامل شد، میتوانید هر دو عملکرد را در Cloud Console مشاهده کنید:

۱۴. فرانتاند (موتور برنامه)
در این مرحله، شما یک رابط کاربری وب در Google App Engine از Pic-a-daily ایجاد میکنید: تمرین ۴ - یک رابط کاربری وب ایجاد کنید که به کاربران امکان آپلود تصاویر از برنامه وب و همچنین مرور تصاویر آپلود شده و تصاویر کوچک آنها را میدهد.

میتوانید اطلاعات بیشتری در مورد App Engine کسب کنید و توضیحات کد را در Pic-a-daily: آزمایشگاه ۴ - ایجاد یک رابط کاربری وب بخوانید.
کد را کاوش کنید
برنامهی App Engine، frontend نام دارد. میتوانید کد کامل آن را در index.js بررسی کنید.
استقرار در موتور برنامه
به پوشه بروید:
cd frontend
منطقه مورد نظر خود را تنظیم کنید و همچنین GOOGLE_CLOUD_PROJECT را در app.yaml با شناسه پروژه واقعی خود جایگزین کنید:
export REGION=europe-west1
gcloud config set compute/region ${REGION}
sed -i -e "s/GOOGLE_CLOUD_PROJECT/${GOOGLE_CLOUD_PROJECT}/" app.yaml
استقرار:
gcloud app deploy app.yaml -q
بعد از یک یا دو دقیقه، به شما گفته میشود که برنامه در حال ارائه ترافیک است:
Beginning deployment of service [default]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 8 files to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ File upload done. Updating service [default]...done. Setting traffic split for service [default]...done. Deployed service [default] to [https://GOOGLE_CLOUD_PROJECT.appspot.com] You can stream logs from the command line by running: $ gcloud app logs tail -s default To view your application in the web browser run: $ gcloud app browse
همچنین میتوانید از بخش App Engine در Cloud Console دیدن کنید تا ببینید آیا برنامه مستقر شده است و ویژگیهای App Engine مانند نسخهبندی و تقسیم ترافیک را بررسی کنید:

۱۵. گردشهای کاری را آزمایش کنید
برای آزمایش، به آدرس پیشفرض موتور برنامه ( https://<YOUR_PROJECT_ID>.appspot.com/ ) بروید و باید رابط کاربری frontend را در حال اجرا ببینید!

یک عکس آپلود کنید. این کار باید گردشهای کاری را فعال کند و شما میتوانید اجرای گردش کار را در حالت Active در Cloud Console مشاهده کنید:

پس از اتمام گردشهای کاری، میتوانید روی شناسه اجرا کلیک کنید و خروجی سرویسهای مختلف را مشاهده کنید:

۳ عکس دیگر آپلود کنید. همچنین باید تصویر کوچک و کلاژ تصاویر را در Cloud Storage buckets ببینید و ظاهر App Engine بهروزرسانی شود:

۱۶. تمیز کردن (اختیاری)
اگر قصد ندارید برنامه را نگه دارید، میتوانید با حذف کل پروژه، منابع را پاکسازی کنید تا در هزینهها صرفهجویی کنید و در کل یک شهروند ابری خوب باشید:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
۱۷. تبریک میگویم!
شما یک نسخه هماهنگ از برنامه را با استفاده از Workflows برای هماهنگسازی و فراخوانی سرویسها ایجاد کردید.
آنچه ما پوشش دادهایم
- موتور برنامه
- فروشگاه ابری فایر استور
- توابع ابری
- اجرای ابری
- گردشهای کاری