عکس روزانه: آزمایشگاه 5 - پاکسازی پس از حذف تصویر

۱. مرور کلی

در این آزمایشگاه کد، شما یک سرویس جدید Cloud Run به نام image garbage collector ایجاد می‌کنید که توسط Eventarc، یک سرویس جدید برای دریافت رویدادها در Cloud Run، فعال می‌شود. وقتی تصویری از سطل تصاویر حذف می‌شود، این سرویس یک رویداد از Eventarc دریافت می‌کند. سپس، تصویر را از سطل تصاویر کوچک حذف می‌کند و همچنین آن را از مجموعه تصاویر Firestore حذف می‌کند.

d93345bfc235f81e.png

آنچه یاد خواهید گرفت

  • اجرای ابری
  • فضای ذخیره‌سازی ابری
  • فروشگاه ابری فایر استور
  • ایونتارک

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

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

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

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

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

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

bce75f34b2c53987.png

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

f6ef2b5f13479f3a.png

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

۳. مقدمه‌ای بر ایونتارک

Eventarc اتصال سرویس‌های Cloud Run را با رویدادها از منابع مختلف آسان می‌کند. این سرویس، دریافت، تحویل، امنیت، مجوزدهی و مدیریت خطا را برای شما انجام می‌دهد.

776ed63706ca9683.png

شما می‌توانید رویدادها را از منابع Google Cloud و برنامه‌های سفارشی که در Cloud Pub/Sub منتشر می‌شوند، دریافت کرده و آنها را به سینک‌های Google Cloud Run تحویل دهید.

رویدادهای طیف وسیعی از منابع Google Cloud از طریق Cloud Audit Logs ارائه می‌شوند. تأخیر و در دسترس بودن تحویل رویداد از این منابع به Cloud Audit Logs وابسته است. هر زمان که رویدادی از یک منبع Google Cloud ایجاد می‌شود، یک ورودی Cloud Audit Log مربوطه ایجاد می‌شود.

برنامه‌های سفارشی که در Cloud Pub/Sub منتشر می‌شوند، می‌توانند پیام‌هایی را در هر قالبی که برای Pub/Sub مشخص می‌کنند، منتشر کنند.

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

تمام رویدادها برای قابلیت همکاری متقابل در سرویس‌ها، در قالب CloudEvents v1.0 ارائه می‌شوند.

۴. قبل از شروع

فعال کردن APIها

برای راه‌اندازی سرویس Cloud Run به سرویس Eventarc نیاز دارید. مطمئن شوید که فعال است:

gcloud services enable eventarc.googleapis.com

باید ببینید که عملیات با موفقیت به پایان رسیده است:

Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.

پیکربندی حساب‌های سرویس

حساب کاربری پیش‌فرض سرویس محاسباتی در تریگرها استفاده خواهد شد. نقش eventarc.eventReceiver را به حساب کاربری پیش‌فرض سرویس محاسباتی اعطا کنید:

PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format='value(projectNumber)')

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
    --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
    --role roles/eventarc.eventReceiver

نقش pubsub.publisher را به حساب سرویس Cloud Storage اعطا کنید. این برای فعال‌سازی Eventarc Cloud Storage مورد نیاز است:

SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)

gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
    --member serviceAccount:$SERVICE_ACCOUNT \
    --role roles/pubsub.publisher

اگر حساب سرویس Pub/Sub را در تاریخ ۸ آوریل ۲۰۲۱ یا قبل از آن فعال کرده‌اید، نقش iam.serviceAccountTokenCreator را به حساب سرویس Pub/Sub اعطا کنید:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
  --role roles/iam.serviceAccountTokenCreator

۵. کد را کپی کنید

اگر قبلاً در آزمایشگاه کد قبلی این کار را نکرده‌اید، کد را کلون کنید:

git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop

سپس می‌توانید به دایرکتوری حاوی سرویس بروید:

cd serverless-photosharing-workshop/services/garbage-collector/nodejs

شما طرح فایل زیر را برای سرویس خواهید داشت:

services
 |
 ├── garbage-collector
      |
      ├── nodejs
           |
           ├── index.js
           ├── package.json

داخل پوشه، شما 3 فایل دارید:

  • index.js شامل کد Node.js است.
  • package.json وابستگی‌های کتابخانه را تعریف می‌کند.

۶. کد را بررسی کنید

وابستگی‌ها

فایل package.json وابستگی‌های کتابخانه‌ای مورد نیاز را تعریف می‌کند:

{
  "name": "garbage_collector_service",
  "version": "0.0.1",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "cloudevents": "^4.0.1",
    "express": "^4.17.1",
    "@google/events": "^3.1.0",
    "@google-cloud/firestore": "^4.9.9",
    "@google-cloud/storage": "^5.8.3"
  }
}

ما برای حذف تصاویر درون Cloud Storage به کتابخانه Cloud Storage وابسته هستیم. ما یک وابستگی به Cloud Firestore اعلام می‌کنیم تا ابرداده‌های تصویری که قبلاً ذخیره کرده‌ایم را نیز حذف کنیم. علاوه بر این، ما برای خواندن CloudEvents ارسال شده توسط Eventarc به کتابخانه‌های CloudEvents SDK و Google Events وابسته هستیم. Express یک چارچوب وب جاوا اسکریپت/Node است. Bluebird برای مدیریت promiseها استفاده می‌شود.

ایندکس.js

بیایید نگاه دقیق‌تری به کد index.js خود داشته باشیم:

const express = require('express');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const { HTTP } = require("cloudevents");
const {toStorageObjectData} = require('@google/events/cloud/storage/v1/StorageObjectData');

ما برای اجرای برنامه خود به وابستگی‌های مختلفی نیاز داریم: Express چارچوب وب Node است که از آن استفاده خواهیم کرد، Bluebird کتابخانه‌ای برای مدیریت promiseهای جاوا اسکریپت است، Storage و Firestore به ترتیب برای کار با Google Cloud Storage (مجموعه تصاویر ما) و Cloud Firestore datastore هستند. علاوه بر این، ما به CloudEvent نیاز داریم تا CloudEvent ارسال شده توسط Eventarc StoreObjectData را از کتابخانه Google Events بخواند تا بدنه رویداد Cloud Storage مربوط به CloudEvent را بخواند.

const app = express();
app.use(express.json());

app.post('/', async (req, res) => {
    try {
        const cloudEvent = HTTP.toEvent({ headers: req.headers, body: req.body });
        console.log(cloudEvent);


        /* ... */

    } catch (err) {
        console.log(`Error: ${err}`);
        res.status(500).send(err);
    }
});

در بالا، ساختار Node handler خود را داریم: برنامه ما به درخواست‌های HTTP POST پاسخ می‌دهد. CloudEvent را از درخواست HTTP می‌خواند و در صورت بروز مشکل، کمی مدیریت خطا انجام می‌دهیم. حال بیایید نگاهی به درون این ساختار بیندازیم.

مرحله بعدی بازیابی و تجزیه بدنه CloudEvent و بازیابی نام شیء است:

const storageObjectData = toStorageObjectData(cloudEvent.data);
console.log(storageObjectData);

const objectName = storageObjectData.name;

وقتی نام تصویر را بدانیم، می‌توانیم آن را از بخش تصاویر بندانگشتی حذف کنیم:

try {
    await storage.bucket(bucketThumbnails).file(objectName).delete();
    console.log(`Deleted '${objectName}' from bucket '${bucketThumbnails}'.`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from bucket '${bucketThumbnails}': ${err}.`);
}

به عنوان آخرین مرحله، متادیتای تصویر را از مجموعه Firestore نیز حذف کنید:

try {
    const pictureStore = new Firestore().collection('pictures');
    const docRef = pictureStore.doc(objectName);
    await docRef.delete();

    console.log(`Deleted '${objectName}' from Firestore collection 'pictures'`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from Firestore: ${err}.`);
}

res.status(200).send(`Processed '${objectName}'.`);

حالا وقتشه که اسکریپت Node خودمون رو طوری تنظیم کنیم که به درخواست‌های ورودی گوش بده. همچنین بررسی کنید که متغیرهای محیطی مورد نیاز تنظیم شده باشند:

app.listen(PORT, () => {
    if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
    console.log(`Started service on port ${PORT}`);
});

۷. به صورت محلی آزمایش کنید

قبل از انتشار در فضای ابری، کد را به صورت محلی آزمایش کنید تا از عملکرد آن مطمئن شوید.

درون پوشه garbage-collector/nodejs ، وابستگی‌های npm را نصب کرده و سرور را راه‌اندازی کنید:

export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT

npm install; npm start

اگر همه چیز خوب پیش رفته باشد، باید سرور روی پورت ۸۰۸۰ شروع به کار کند:

Started service on port 8080

برای خروج از CTRL-C استفاده کنید.

۸. ساخت و استقرار در Cloud Run

قبل از استقرار در Cloud Run، منطقه Cloud Run را روی یکی از مناطق پشتیبانی شده و پلتفرم را روی managed تنظیم کنید:

REGION=europe-west1
gcloud config set run/region $REGION
gcloud config set run/platform managed

می‌توانید بررسی کنید که پیکربندی تنظیم شده است:

gcloud config list

...
[run]
platform = managed
region = europe-west1

به جای ساخت و انتشار تصویر کانتینر با استفاده از Cloud Build به صورت دستی، می‌توانید به Cloud Run نیز تکیه کنید تا با استفاده از Google Cloud Buildpacks تصویر کانتینر را برای شما بسازد.

دستور زیر را برای ساخت تصویر کانتینر با استفاده از Google Cloud Buildpack s اجرا کنید و سپس تصویر کانتینر را در Cloud Run مستقر کنید:

SERVICE_NAME=garbage-collector-service

gcloud run deploy $SERVICE_NAME \
    --source . \
    --no-allow-unauthenticated \
    --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS

به پرچم –-source توجه کنید. این پرچم، Cloud Run را طوری تنظیم می‌کند که از Google Cloud Buildpacks برای ساخت تصویر کانتینر بدون Dockerfile. پرچم --no-allow-unauthenticated سرویس Cloud Run را به یک سرویس داخلی تبدیل می‌کند که فقط توسط حساب‌های سرویس خاص فعال می‌شود. بعداً، یک Trigger با حساب سرویس محاسباتی پیش‌فرض ایجاد خواهید کرد که نقش run.invoker را برای فراخوانی سرویس‌های داخلی Cloud Run دارد.

۹. یک محرک ایجاد کنید

در Eventarc، یک Trigger تعریف می‌کند که چه سرویسی باید چه نوع رویدادهایی را دریافت کند. در این مورد، شما می‌خواهید سرویس رویدادهایی را دریافت کند که یک فایل در یک سطل حذف می‌شود.

مکان Trigger را در همان منطقه‌ی تصاویر آپلود شده تنظیم کنید:

gcloud config set eventarc/location eu

یک تریگر AuditLog برای فیلتر کردن رویدادهای storage.objects.delete ایجاد کنید و آن را به سرویس Cloud Run ارسال کنید:

BUCKET_IMAGES=uploaded-pictures-$GOOGLE_CLOUD_PROJECT

gcloud eventarc triggers create trigger-$SERVICE_NAME \
  --destination-run-service=$SERVICE_NAME \
  --destination-run-region=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.deleted" \
  --event-filters="bucket=$BUCKET_IMAGES" \
  --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

می‌توانید با استفاده از این دستور، دوباره بررسی کنید که Trigger ایجاد شده است:

gcloud eventarc triggers list

۱۰. سرویس را آزمایش کنید

برای آزمایش اینکه آیا سرویس کار می‌کند، به بخش uploaded-pictures بروید و یکی از تصاویر را حذف کنید. باید در گزارش‌های سرویس مشاهده کنید که تصویر مربوطه را در بخش thumbnails حذف کرده و همچنین سند آن را از مجموعه pictures Firestore حذف کرده است.

519abf90e7ea4d12.png

۱۱. تمیز کردن (اختیاری)

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

سرویس را حذف کنید:

gcloud run services delete $SERVICE_NAME -q

ماشه Eventarc را حذف کنید:

gcloud eventarc triggers delete trigger-$SERVICE_NAME -q

روش دیگر، حذف کل پروژه است:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

۱۲. تبریک می‌گویم!

تبریک! شما یک سرویس Cloud Run، یک جمع‌کننده‌ی زباله‌ی تصاویر، ایجاد کردید که توسط Eventarc، یک سرویس جدید برای دریافت رویدادها در Cloud Run، فعال می‌شود. وقتی تصویری از سطل تصاویر حذف می‌شود، این سرویس یک رویداد از Eventarc دریافت می‌کند. سپس، تصویر را از سطل تصاویر کوچک حذف می‌کند و همچنین آن را از مجموعه تصاویر Firestore حذف می‌کند.

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

  • اجرای ابری
  • فضای ذخیره‌سازی ابری
  • فروشگاه ابری فایر استور
  • ایونتارک