1. بررسی اجمالی
در این آزمایشگاه کد، یک سرویس Cloud Run جدید، سرویس کلاژ ایجاد میکنید که توسط Cloud Scheduler در یک بازه زمانی منظم راهاندازی میشود. این سرویس آخرین تصاویر آپلود شده را واکشی می کند و کلاژی از آن تصاویر ایجاد می کند: لیست تصاویر اخیر را در Cloud Firestore پیدا می کند و سپس فایل های تصویر واقعی را از Cloud Storage دانلود می کند.
چیزی که یاد خواهید گرفت
- Cloud Run
- Cloud Scheduler
- فضای ذخیره سازی ابری
- Cloud Firestore
2. راه اندازی و الزامات
تنظیم محیط خود به خود
- به Google Cloud Console وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. اگر قبلاً یک حساب Gmail یا Google Workspace ندارید، باید یک حساب ایجاد کنید .
- نام پروژه نام نمایشی برای شرکت کنندگان این پروژه است. این یک رشته کاراکتری است که توسط API های Google استفاده نمی شود و می توانید هر زمان که بخواهید آن را به روز کنید.
- شناسه پروژه باید در تمام پروژههای Google Cloud منحصربهفرد باشد و تغییرناپذیر باشد (پس از تنظیم نمیتوان آن را تغییر داد). Cloud Console به طور خودکار یک رشته منحصر به فرد تولید می کند. معمولاً برای شما مهم نیست که چیست. در اکثر کدها، باید به شناسه پروژه ارجاع دهید (و معمولاً به عنوان
PROJECT_ID
شناخته میشود)، بنابراین اگر آن را دوست ندارید، یک نمونه تصادفی دیگر ایجاد کنید، یا میتوانید شناسه پروژه را امتحان کنید و ببینید در دسترس است. سپس پس از ایجاد پروژه "یخ زده" می شود. - یک مقدار سوم وجود دارد، یک شماره پروژه که برخی از API ها از آن استفاده می کنند. در مورد هر سه این مقادیر در مستندات بیشتر بیاموزید.
- در مرحله بعد، برای استفاده از منابع Cloud/APIها، باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. برای اینکه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید، دستورالعملهای «پاکسازی» را که در انتهای Codelab یافت میشود دنبال کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.
Cloud Shell را راه اندازی کنید
در حالی که Google Cloud را می توان از راه دور از لپ تاپ شما کار کرد، در این کد لبه از Google Cloud Shell استفاده خواهید کرد، یک محیط خط فرمان که در Cloud اجرا می شود.
از کنسول GCP روی نماد Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:
تهیه و اتصال به محیط فقط چند لحظه طول می کشد. وقتی تمام شد، باید چیزی شبیه به این را ببینید:
این ماشین مجازی با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد و احراز هویت شبکه را تا حد زیادی افزایش می دهد. تمام کارهای شما در این آزمایشگاه به سادگی با یک مرورگر قابل انجام است.
3. API ها را فعال کنید
برای راه اندازی سرویس Cloud Run در یک بازه زمانی منظم به Cloud Scheduler نیاز دارید. مطمئن شوید که فعال است:
gcloud services enable cloudscheduler.googleapis.com
برای اتمام موفقیت آمیز باید عملیات را مشاهده کنید:
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
4. کد را شبیه سازی کنید
اگر قبلاً در آزمایشگاه کد قبلی نبوده اید، کد را شبیه سازی کنید:
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
سپس می توانید به دایرکتوری حاوی سرویس بروید:
cd serverless-photosharing-workshop/services/collage/nodejs
شما طرح بندی فایل زیر را برای سرویس خواهید داشت:
services | ├── collage | ├── nodejs | ├── Dockerfile ├── index.js ├── package.json
در داخل پوشه، شما 3 فایل دارید:
-
index.js
حاوی کد Node.js است -
package.json
وابستگی های کتابخانه را تعریف می کند -
Dockerfile
تصویر ظرف را تعریف می کند
5. کد را کاوش کنید
وابستگی ها
فایل package.json
وابستگی های کتابخانه مورد نیاز را تعریف می کند:
{
"name": "collage_service",
"version": "0.0.1",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"bluebird": "^3.7.2",
"express": "^4.17.1",
"imagemagick": "^0.1.3",
"@google-cloud/firestore": "^4.9.9",
"@google-cloud/storage": "^5.8.3"
}
}
ما برای خواندن و ذخیره فایلهای تصویری در فضای ذخیرهسازی ابری به کتابخانه Cloud Storage وابسته هستیم. ما یک وابستگی به Cloud Firestore اعلام می کنیم تا متادیتای تصویری را که قبلاً ذخیره کرده بودیم واکشی کنیم. Express یک چارچوب وب جاوا اسکریپت / Node است. Bluebird برای مدیریت وعده ها استفاده می شود و imagemagick یک کتابخانه برای دستکاری تصاویر است.
Dockerfile
Dockerfile
تصویر ظرف را برای برنامه تعریف می کند:
FROM node:14-slim
# installing Imagemagick
RUN set -ex; \
apt-get -y update; \
apt-get -y install imagemagick; \
rm -rf /var/lib/apt/lists/*
WORKDIR /picadaily/services/collage
COPY package*.json ./
RUN npm install --production
COPY . .
CMD [ "npm", "start" ]
ما از یک تصویر پایه Node 14 سبک استفاده می کنیم. ما در حال نصب کتابخانه imagemagick هستیم. سپس ماژول های NPM مورد نیاز کد خود را نصب می کنیم و کد گره خود را با شروع npm اجرا می کنیم.
index.js
بیایید نگاهی دقیق تر به کد index.js
خود داشته باشیم:
const express = require('express');
const imageMagick = require('imagemagick');
const Promise = require("bluebird");
const path = require('path');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
ما به وابستگی های مختلف مورد نیاز برای اجرای برنامه خود نیاز داریم: Express چارچوب وب Node است که از آن استفاده خواهیم کرد، ImageMagick کتابخانه ای برای انجام دستکاری تصویر، Bluebird کتابخانه ای برای مدیریت وعده های جاوا اسکریپت، Path برای رسیدگی به مسیرهای فایل ها و دایرکتوری ها استفاده می شود. و سپس Storage و Firestore به ترتیب برای کار با Google Cloud Storage (سطل های تصاویر ما) و Cloud Firestore datastore هستند.
const app = express();
app.get('/', async (req, res) => {
try {
console.log('Collage request');
/* ... */
} catch (err) {
console.log(`Error: creating the collage: ${err}`);
console.error(err);
res.status(500).send(err);
}
});
در بالا، ساختار Node handler خود را داریم: برنامه ما به درخواستهای HTTP GET پاسخ میدهد. و در صورتی که مشکلی پیش بیاید، کمی مدیریت خطا را انجام می دهیم. حال بیایید نگاهی به آنچه در داخل این ساختار وجود دارد بیاندازیم.
const thumbnailFiles = [];
const pictureStore = new Firestore().collection('pictures');
const snapshot = await pictureStore
.where('thumbnail', '==', true)
.orderBy('created', 'desc')
.limit(4).get();
if (snapshot.empty) {
console.log('Empty collection, no collage to make');
res.status(204).send("No collage created.");
} else {
/* ... */
}
سرویس کلاژ ما حداقل به چهار عکس نیاز دارد (که تصاویر کوچک آنها ایجاد شده است)، بنابراین حتماً ابتدا 4 عکس را آپلود کنید.
ما 4 آخرین عکس آپلود شده توسط کاربران خود را از ابرداده های ذخیره شده در Cloud Firerstore بازیابی می کنیم. بررسی می کنیم که آیا مجموعه به دست آمده خالی است یا نه، و سپس در شاخه else کد ما ادامه می دهیم.
بیایید لیستی از نام فایل ها را جمع آوری کنیم:
snapshot.forEach(doc => {
thumbnailFiles.push(doc.id);
});
console.log(`Picture file names: ${JSON.stringify(thumbnailFiles)}`);
ما میخواهیم هر یک از آن فایلها را از سطل بندانگشتی دانلود کنیم که نام آن از یک متغیر محیطی است که در زمان استقرار تنظیم کردهایم:
const thumbBucket = storage.bucket(process.env.BUCKET_THUMBNAILS);
await Promise.all(thumbnailFiles.map(async fileName => {
const filePath = path.resolve('/tmp', fileName);
await thumbBucket.file(fileName).download({
destination: filePath
});
}));
console.log('Downloaded all thumbnails');
هنگامی که جدیدترین تصاویر کوچک آپلود شدند، از کتابخانه ImageMagick برای ایجاد یک شبکه 4×4 از آن تصاویر بند انگشتی استفاده می کنیم. ما از کتابخانه Bluebird و اجرای Promise آن برای تبدیل کد مبتنی بر تماس به کد async
/ await
دوستانه استفاده می کنیم، سپس منتظر قولی هستیم که کلاژ تصویر را می سازد:
const collagePath = path.resolve('/tmp', 'collage.png');
const thumbnailPaths = thumbnailFiles.map(f => path.resolve('/tmp', f));
const convert = Promise.promisify(im.convert);
await convert([
'(', ...thumbnailPaths.slice(0, 2), '+append', ')',
'(', ...thumbnailPaths.slice(2), '+append', ')',
'-size', '400x400', 'xc:none', '-background', 'none', '-append',
collagePath]);
console.log("Created local collage picture");
از آنجایی که تصویر کلاژ به صورت محلی در پوشه موقت در دیسک ذخیره شده است، اکنون باید آن را در فضای ذخیره سازی ابری آپلود کنیم و سپس یک پاسخ موفق را برگردانیم (کد وضعیت 2xx):
await thumbBucket.upload(collagePath);
console.log("Uploaded collage to Cloud Storage bucket ${process.env.BUCKET_THUMBNAILS}");
res.status(204).send("Collage created.");
اکنون زمان آن است که اسکریپت Node خود را به درخواست های دریافتی گوش دهد:
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Started collage service on port ${PORT}`);
});
در پایان فایل منبع، دستورالعملهایی داریم که Express واقعاً برنامه وب ما را روی پورت پیشفرض 8080 راهاندازی کند.
6. تست محلی
قبل از استقرار در فضای ابری، کد را به صورت محلی تست کنید تا مطمئن شوید که کار می کند.
در داخل پوشه collage/nodejs
، وابستگی های npm را نصب کنید و سرور را راه اندازی کنید:
npm install; npm start
اگر همه چیز خوب پیش رفت، باید سرور را روی پورت 8080 راه اندازی کند:
Started collage service on port 8080
برای خروج از CTRL-C
استفاده کنید.
7. ساخت و استقرار در Cloud Run
قبل از استقرار در Cloud Run، منطقه Cloud Run را روی یکی از مناطق پشتیبانی شده و پلتفرم برای managed
تنظیم کنید:
gcloud config set run/region europe-west1 gcloud config set run/platform managed
می توانید بررسی کنید که پیکربندی تنظیم شده است:
gcloud config list ... [run] platform = managed region = europe-west1
به جای ساختن و انتشار تصویر کانتینر با استفاده از Cloud Build به صورت دستی، میتوانید برای ساختن تصویر کانتینر با استفاده از Google Cloud Buildpacks به Cloud Run نیز تکیه کنید.
برای ساختن تصویر کانتینر دستور زیر را اجرا کنید:
BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT SERVICE_NAME=collage-service gcloud run deploy $SERVICE_NAME \ --source . \ --no-allow-unauthenticated \ --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS
به پرچم –-source
توجه کنید. این استقرار مبتنی بر منبع در Cloud Run است. اگر یک Dockerfile
در فهرست کد منبع وجود داشته باشد، کد منبع بارگذاری شده با استفاده از آن Dockerfile
ساخته می شود. اگر هیچ Dockerfile
در فهرست کد منبع وجود نداشته باشد، بستههای ساخت Google Cloud بهطور خودکار زبانی را که استفاده میکنید شناسایی میکند و وابستگیهای کد را برای ایجاد یک تصویر ظرف آماده برای تولید، با استفاده از یک تصویر پایه امن که توسط Google مدیریت میشود، واکشی میکند. این Cloud Run را برای استفاده از Google Cloud Buildpacks برای ساخت تصویر کانتینر تعریفشده در Dockerfile
علامتگذاری میکند.
همچنین توجه داشته باشید که استقرار مبتنی بر منبع از Artifact Registry برای ذخیره کانتینرهای ساخته شده استفاده می کند. Artifact Registry یک نسخه مدرن از Google Container Registry است. اگر API قبلاً در پروژه فعال نشده باشد، CLI از شما درخواست میکند که API را فعال کند و یک مخزن با نام cloud-run-source-deploy
در منطقهای که در آن مستقر میشوید ایجاد میکند.
پرچم --no-allow-unauthenticated
سرویس Cloud Run را به یک سرویس داخلی تبدیل می کند که فقط توسط حساب های سرویس خاص راه اندازی می شود.
8. Cloud Scheduler را راه اندازی کنید
اکنون که سرویس Cloud Run آماده و مستقر شده است، وقت آن است که برنامه منظمی را ایجاد کنید، تا هر دقیقه سرویس را فراخوانی کنید.
ایجاد یک حساب خدمات:
SERVICE_ACCOUNT=collage-scheduler-sa gcloud iam service-accounts create $SERVICE_ACCOUNT \ --display-name "Collage Scheduler Service Account"
به حساب سرویس اجازه فراخوانی سرویس Cloud Run بدهید:
gcloud run services add-iam-policy-binding $SERVICE_NAME \ --member=serviceAccount:$SERVICE_ACCOUNT@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \ --role=roles/run.invoker
یک کار Cloud Scheduler ایجاد کنید تا هر 1 دقیقه اجرا شود:
SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --format 'value(status.url)') gcloud scheduler jobs create http $SERVICE_NAME-job --schedule "* * * * *" \ --http-method=GET \ --location=europe-west1 \ --uri=$SERVICE_URL \ --oidc-service-account-email=$SERVICE_ACCOUNT@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \ --oidc-token-audience=$SERVICE_URL
می توانید به بخش Cloud Scheduler در Cloud Console بروید تا ببینید که تنظیم شده است و به آدرس اینترنتی سرویس Cloud Run اشاره می کند:
9. سرویس را تست کنید
برای آزمایش اینکه آیا راهاندازی کار میکند، در سطل thumbnails
تصویر کلاژ (به نام collage.png
) را بررسی کنید. همچنین می توانید گزارش های سرویس را بررسی کنید:
10. تمیز کردن (اختیاری)
اگر قصد ندارید با دیگر آزمایشگاههای این سری ادامه دهید، میتوانید منابع را پاکسازی کنید تا در هزینهها صرفهجویی کنید و در کل شهروند ابری خوبی باشید. می توانید منابع را به صورت جداگانه به صورت زیر پاک کنید.
سرویس را حذف کنید:
gcloud run services delete $SERVICE_NAME -q
کار Cloud Scheduler را حذف کنید:
gcloud scheduler jobs delete $SERVICE_NAME-job -q
یا می توانید کل پروژه را حذف کنید:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
11. تبریک!
تبریک می گویم! شما یک سرویس زمانبندی شده ایجاد کردید: به لطف Cloud Scheduler، که هر دقیقه یک پیام را در یک موضوع Pub/Sub ارسال میکند، سرویس کلاژ Cloud Run شما فراخوانی میشود و میتواند تصاویر را به هم اضافه کند تا تصویر حاصل را ایجاد کند.
آنچه را پوشش داده ایم
- Cloud Run
- Cloud Scheduler
- فضای ذخیره سازی ابری
- Cloud Firestore