شروع کار با کارهای Cloud Run

1. مقدمه

1965fab24c502bd5.png

نمای کلی

سرویس‌های Cloud Run برای کانتینرهایی که به‌طور نامحدود با گوش دادن به درخواست‌های HTTP اجرا می‌شوند، مناسب‌تر هستند، در حالی که کارهای Cloud Run برای کانتینرهایی که تا پایان (در حال حاضر حداکثر 24 ساعت ) اجرا می‌شوند و درخواست‌ها را ارائه نمی‌دهند، مناسب‌تر هستند. برای مثال، پردازش رکوردها از پایگاه داده، پردازش فهرستی از فایل‌ها از یک سطل ذخیره‌سازی ابری یا یک عملیات طولانی‌مدت، مانند محاسبه Pi، اگر به عنوان یک کار Cloud Run اجرا شود، به خوبی کار می‌کند.

مشاغل توانایی ارائه درخواست ها یا گوش دادن در پورت را ندارند. این بدان معناست که برخلاف سرویس‌های Cloud Run، شغل‌ها نباید یک وب سرور را بسته‌بندی کنند. در عوض، ظروف مشاغل باید پس از اتمام آنها خارج شوند.

در کارهای Cloud Run، می توانید با تعیین تعدادی کار، چندین نسخه از کانتینر خود را به صورت موازی اجرا کنید. هر وظیفه نشان دهنده یک کپی در حال اجرا از کانتینر است. اگر هر وظیفه بتواند به طور مستقل زیرمجموعه ای از داده های شما را پردازش کند، استفاده از چندین کار مفید است. به عنوان مثال، پردازش 10000 رکورد از Cloud SQL یا 10000 فایل از Cloud Storage با 10 وظیفه پردازش 1000 رکورد یا فایل، هر کدام به صورت موازی، سریعتر انجام می شود.

استفاده از Cloud Run Jobs یک فرآیند دو مرحله ای است:

  1. Create a job: تمام تنظیمات مورد نیاز برای اجرای کار، مانند تصویر ظرف، منطقه، متغیرهای محیط را در بر می گیرد.
  2. Run the job: این کار یک اجرای جدید از کار ایجاد می کند. در صورت تمایل، کار خود را به گونه‌ای تنظیم کنید که با استفاده از Cloud Scheduler طبق یک برنامه اجرا شود.

در این لبه کد، ابتدا یک برنامه Node.js را بررسی می کنید تا از صفحات وب اسکرین شات بگیرید و آنها را در فضای ابری ذخیره کنید. سپس یک تصویر ظرف برای برنامه می‌سازید، آن را روی کارهای Cloud Run اجرا می‌کنید، کار را به‌روزرسانی می‌کنید تا صفحات وب بیشتری را پردازش کنید، و کار را بر اساس یک زمان‌بندی با Cloud Scheduler اجرا می‌کنید.

چیزی که یاد خواهید گرفت

  • نحوه استفاده از برنامه برای گرفتن اسکرین شات از صفحات وب
  • چگونه یک تصویر ظرف برای برنامه بسازیم.
  • نحوه ایجاد یک کار Cloud Run برای برنامه
  • نحوه اجرای برنامه به عنوان یک کار Cloud Run.
  • چگونه کار را به روز کنیم.
  • نحوه برنامه ریزی کار با Cloud Scheduler.

2. راه اندازی و الزامات

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

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

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

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

Cloud Shell را راه اندازی کنید

در حالی که Google Cloud را می توان از راه دور از لپ تاپ شما کار کرد، در این کد لبه از Google Cloud Shell استفاده خواهید کرد، یک محیط خط فرمان که در Cloud اجرا می شود.

از Google Cloud Console ، روی نماد Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

84688aa223b1c3a2.png

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

320e18fedb7fbe0.png

این ماشین مجازی با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد و احراز هویت شبکه را تا حد زیادی افزایش می دهد. تمام کارهای شما در این کد لبه را می توان در یک مرورگر انجام داد. شما نیازی به نصب چیزی ندارید.

gcloud را راه اندازی کنید

در Cloud Shell، شناسه پروژه و منطقه ای را که می خواهید کار Cloud Run را در آن مستقر کنید، تنظیم کنید. آنها را به عنوان متغیرهای PROJECT_ID و REGION ذخیره کنید. در آینده، می‌توانید منطقه‌ای را از یکی از مکان‌های Cloud Run انتخاب کنید.

PROJECT_ID=[YOUR-PROJECT-ID]
REGION=us-central1
gcloud config set core/project $PROJECT_ID

API ها را فعال کنید

فعال کردن تمام خدمات لازم:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com

3. کد را دریافت کنید

ابتدا یک برنامه Node.js را بررسی می کنید تا از صفحات وب اسکرین شات بگیرید و آنها را در فضای ذخیره سازی ابری ذخیره کنید. بعداً یک تصویر ظرف برای برنامه می‌سازید و آن را به‌عنوان کار در Cloud Run اجرا می‌کنید.

از Cloud Shell، دستور زیر را برای کلون کردن کد برنامه از این مخزن اجرا کنید:

git clone https://github.com/GoogleCloudPlatform/jobs-demos.git

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

cd jobs-demos/screenshot

شما باید این طرح بندی فایل را ببینید:

screenshot
 |
 ├── Dockerfile
 ├── README.md
 ├── screenshot.js
 ├── package.json

در اینجا توضیح مختصری از هر فایل آورده شده است:

  • screenshot.js حاوی کد Node.js برای برنامه است.
  • package.json وابستگی های کتابخانه را تعریف می کند.
  • Dockerfile تصویر ظرف را تعریف می کند.

4. کد را کاوش کنید

برای کشف کد، با کلیک بر روی دکمه Open Editor در بالای پنجره Cloud Shell از ویرایشگر متن داخلی استفاده کنید.

15a2cdc9b7f6dfc6.png

در اینجا توضیح مختصری در مورد هر فایل آورده شده است.

screenshot.js

screenshot.js ابتدا Puppeteer و Cloud Storage را به عنوان وابستگی اضافه می کند. Puppeteer یک کتابخانه Node.js است که از آن برای گرفتن اسکرین شات از صفحات وب استفاده می کنید:

const puppeteer = require('puppeteer');
const {Storage} = require('@google-cloud/storage');

یک تابع initBrowser برای مقداردهی اولیه Puppeteer و تابع takeScreenshot برای گرفتن اسکرین شات از یک URL مشخص وجود دارد:

async function initBrowser() {
  console.log('Initializing browser');
  return await puppeteer.launch();
}

async function takeScreenshot(browser, url) {
  const page = await browser.newPage();

  console.log(`Navigating to ${url}`);
  await page.goto(url);

  console.log(`Taking a screenshot of ${url}`);
  return await page.screenshot({
    fullPage: true
  });
}

در مرحله بعد، یک تابع برای دریافت یا ایجاد یک سطل فضای ذخیره سازی ابری و دیگری برای آپلود اسکرین شات یک صفحه وب در یک سطل وجود دارد:

async function createStorageBucketIfMissing(storage, bucketName) {
  console.log(`Checking for Cloud Storage bucket '${bucketName}' and creating if not found`);
  const bucket = storage.bucket(bucketName);
  const [exists] = await bucket.exists();
  if (exists) {
    // Bucket exists, nothing to do here
    return bucket;
  }

  // Create bucket
  const [createdBucket] = await storage.createBucket(bucketName);
  console.log(`Created Cloud Storage bucket '${createdBucket.name}'`);
  return createdBucket;
}

async function uploadImage(bucket, taskIndex, imageBuffer) {
  // Create filename using the current time and task index
  const date = new Date();
  date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
  const filename = `${date.toISOString()}-task${taskIndex}.png`;

  console.log(`Uploading screenshot as '${filename}'`)
  await bucket.file(filename).save(imageBuffer);
}

در نهایت، تابع main نقطه ورود است:

async function main(urls) {
  console.log(`Passed in urls: ${urls}`);

  const taskIndex = process.env.CLOUD_RUN_TASK_INDEX || 0;
  const url = urls[taskIndex];
  if (!url) {
    throw new Error(`No url found for task ${taskIndex}. Ensure at least ${parseInt(taskIndex, 10) + 1} url(s) have been specified as command args.`);
  }
  const bucketName = process.env.BUCKET_NAME;
  if (!bucketName) {
    throw new Error('No bucket name specified. Set the BUCKET_NAME env var to specify which Cloud Storage bucket the screenshot will be uploaded to.');
  }

  const browser = await initBrowser();
  const imageBuffer = await takeScreenshot(browser, url).catch(async err => {
    // Make sure to close the browser if we hit an error.
    await browser.close();
    throw err;
  });
  await browser.close();

  console.log('Initializing Cloud Storage client')
  const storage = new Storage();
  const bucket = await createStorageBucketIfMissing(storage, bucketName);
  await uploadImage(bucket, taskIndex, imageBuffer);

  console.log('Upload complete!');
}

main(process.argv.slice(2)).catch(err => {
  console.error(JSON.stringify({severity: 'ERROR', message: err.message}));
  process.exit(1);
});

در مورد روش main به موارد زیر توجه کنید:

  • URL ها به عنوان آرگومان ارسال می شوند.
  • نام سطل به عنوان متغیر محیطی BUCKET_NAME تعریف شده توسط کاربر ارسال می شود. نام سطل باید در سراسر Google Cloud منحصربه‌فرد باشد.
  • یک متغیر محیطی CLOUD_RUN_TASK_INDEX توسط کارهای Cloud Run ارسال می شود. کارهای Cloud Run می توانند چندین نسخه از برنامه را به عنوان وظایف منحصر به فرد اجرا کنند. CLOUD_RUN_TASK_INDEX نمایه کار در حال اجرا را نشان می دهد. زمانی که کد خارج از وظایف Cloud Run اجرا می شود، به طور پیش فرض صفر می شود. هنگامی که برنامه به صورت چند کار اجرا می شود، هر وظیفه/کانتینر URL مربوط به آن را انتخاب می کند، یک اسکرین شات می گیرد و تصویر را در سطل ذخیره می کند.

package.json

فایل package.json برنامه را تعریف می کند و وابستگی های Cloud Storage و Puppeteer را مشخص می کند:

{
  "name": "screenshot",
  "version": "1.0.0",
  "description": "Create a job to capture screenshots",
  "main": "screenshot.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Google LLC",
  "license": "Apache-2.0",
  "dependencies": {
    "@google-cloud/storage": "^5.18.2",
    "puppeteer": "^13.5.1"
  }
}

Dockerfile

Dockerfile تصویر محفظه برنامه را با تمام کتابخانه ها و وابستگی های مورد نیاز تعریف می کند:

FROM ghcr.io/puppeteer/puppeteer:16.1.0
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENTRYPOINT ["node", "screenshot.js"]

5. یک شغل مستقر کنید

قبل از ایجاد شغل، باید یک حساب خدماتی ایجاد کنید که از آن برای اجرای کار استفاده کنید.

gcloud iam service-accounts create screenshot-sa --display-name="Screenshot app service account"

نقش storage.admin را به حساب سرویس اعطا کنید، بنابراین می توان از آن برای ایجاد سطل و اشیاء استفاده کرد.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --role roles/storage.admin \
  --member serviceAccount:screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com

اکنون آماده استقرار یک کار Cloud Run هستید که شامل پیکربندی لازم برای اجرای کار است.

gcloud beta run jobs deploy screenshot \
  --source=. \
  --args="https://example.com" \
  --args="https://cloud.google.com" \
  --tasks=2 \
  --task-timeout=5m \
  --region=$REGION \
  --set-env-vars=BUCKET_NAME=screenshot-$PROJECT_ID \
  --service-account=screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com

این از استقرار مبتنی بر منبع استفاده می کند و یک کار Cloud Run بدون اجرای آن ایجاد می کند.

توجه کنید که چگونه صفحات وب به عنوان آرگومان ارسال می شوند. نام سطل برای ذخیره اسکرین شات ها به عنوان یک متغیر محیطی ارسال می شود.

با تعیین تعدادی کار برای اجرا با پرچم --tasks می توانید چندین نسخه از کانتینر خود را به صورت موازی اجرا کنید. هر وظیفه نشان دهنده یک کپی در حال اجرا از کانتینر است. اگر هر وظیفه بتواند به طور مستقل زیرمجموعه ای از داده های شما را پردازش کند، استفاده از چندین کار مفید است. برای تسهیل این امر، هر کار از شاخص خود آگاه است، که در متغیر محیطی CLOUD_RUN_TASK_INDEX ذخیره می شود. کد شما مسئول تعیین تکلیف کدام زیر مجموعه از داده ها است. به --tasks=2 در این نمونه توجه کنید. این اطمینان حاصل می کند که 2 کانتینر برای 2 URL که می خواهیم پردازش کنیم اجرا می شود.

هر کار می تواند تا 24 ساعت اجرا شود. همانطور که در این مثال انجام دادیم، می توانید با استفاده از پرچم --task-timeout این زمان را کاهش دهید. همه وظایف باید موفقیت آمیز باشند تا کار با موفقیت انجام شود. به طور پیش فرض، کارهای ناموفق دوباره امتحان نمی شوند. می‌توانید وظایف را به گونه‌ای پیکربندی کنید که در صورت شکست، دوباره امتحان شوند. اگر هر کاری از تعداد دفعات مجدد آن بیشتر شود، کل کار با شکست مواجه می شود.

به طور پیش فرض، کار شما تا حد امکان با تعداد زیادی کار به صورت موازی اجرا می شود. این برابر با تعداد وظایف شغل شما حداکثر تا 100 خواهد بود. ممکن است بخواهید برای مشاغلی که به یک Backend با مقیاس پذیری محدود دسترسی دارند، موازی سازی کمتری تنظیم کنید. به عنوان مثال، پایگاه داده ای که از تعداد محدودی از اتصالات فعال پشتیبانی می کند. می توانید موازی بودن را با پرچم --parallelism کاهش دهید.

6. یک کار را اجرا کنید

قبل از اجرای کار، کار را فهرست کنید تا ببینید ایجاد شده است:

gcloud run jobs list

✔
JOB: screenshot
REGION: us-central
LAST RUN AT:
CREATED: 2022-02-22 12:20:50 UTC

کار را با دستور زیر اجرا کنید:

gcloud run jobs execute screenshot --region=$REGION

این کار را اجرا می کند. می توانید اجرای فعلی و گذشته را فهرست کنید:

gcloud run jobs executions list --job screenshot --region=$REGION

...
JOB: screenshot
EXECUTION: screenshot-znkmm
REGION: $REGION
RUNNING: 1
COMPLETE: 1 / 2
CREATED: 2022-02-22 12:40:42 UTC

اعدام را شرح دهید. باید تیک سبز رنگ و پیام tasks completed successfully ببینید:

gcloud run jobs executions describe screenshot-znkmm --region=$REGION

✔ Execution screenshot-znkmm in region $REGION
2 tasks completed successfully


Image:           $REGION-docker.pkg.dev/$PROJECT_ID/containers/screenshot at 311b20d9...
Tasks:           2
Args:            https://example.com https://cloud.google.com
Memory:          1Gi
CPU:             1000m
Task Timeout:    3600s
Parallelism:     2
Service account: 11111111-compute@developer.gserviceaccount.com
Env vars:
  BUCKET_NAME    screenshot-$PROJECT_ID

همچنین می‌توانید صفحه مشاغل Cloud Run را در Cloud Console بررسی کنید تا وضعیت را ببینید:

1afde14d65f0d9ce.png

اگر سطل Cloud Storage را بررسی کنید، باید دو فایل اسکرین شات ایجاد شده را ببینید:

7c4d355f6f65106.png

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

برای متوقف کردن اجرای کار خود، باید اجرا را حذف کنید:

gcloud run jobs executions delete screenshot-znkmm --region=$REGION

7. یک شغل را به روز کنید

نسخه‌های جدید کانتینر شما در اجرای بعدی به‌طور خودکار توسط کارهای Cloud Run انتخاب نمی‌شوند. اگر کد شغل خود را تغییر دهید، باید ظرف را دوباره بسازید و کار خود را به روز کنید. استفاده از تصاویر برچسب گذاری شده به شما کمک می کند تا تشخیص دهید که در حال حاضر از کدام نسخه تصویر استفاده می شود.

به طور مشابه، اگر می‌خواهید برخی از متغیرهای پیکربندی را به‌روزرسانی کنید، باید کار را به‌روزرسانی کنید. در اجرای بعدی کار از کانتینر و تنظیمات پیکربندی جدید استفاده می شود.

کار را به روز کنید و صفحاتی را که برنامه از آنها اسکرین شات می گیرد در پرچم --args تغییر دهید. همچنین پرچم --tasks را به روز کنید تا تعداد صفحات را منعکس کند.

gcloud run jobs update screenshot \
  --args="https://www.pinterest.com" \
  --args="https://www.apartmenttherapy.com" \
  --args="https://www.google.com" \
  --region=$REGION \
  --tasks=3

دوباره کار را اجرا کنید. این زمان در پرچم --wait می گذرد تا منتظر پایان اجراها باشیم:

gcloud run jobs execute screenshot --region=$REGION --wait

پس از چند ثانیه، باید 3 اسکرین شات دیگر را به سطل اضافه کنید:

ed0cbe0b5a5f9144.png

8. یک کار را برنامه ریزی کنید

تا کنون، شما کارها را به صورت دستی اجرا می کنید. در یک سناریوی دنیای واقعی، احتمالاً می خواهید مشاغل را در پاسخ به یک رویداد یا بر اساس یک برنامه اجرا کنید. بیایید ببینیم چگونه با استفاده از Cloud Scheduler، کار اسکرین شات را بر اساس یک برنامه زمانبندی اجرا کنیم.

ابتدا مطمئن شوید که Cloud Scheduler API فعال است:

gcloud services enable cloudscheduler.googleapis.com

به صفحه جزئیات کارهای Cloud Run بروید و روی بخش Triggers کلیک کنید:

3ae456368905472f.png

دکمه Add Scheduler Trigger انتخاب کنید:

48cbba777f75e1eb.png

یک پانل در سمت راست باز می شود. یک Job Scheduler ایجاد کنید تا هر روز ساعت 9:00 با این پیکربندی اجرا شود و Continue انتخاب کنید:

81fd098be0db216.png

در صفحه بعد، حساب پیش فرض سرویس محاسباتی را انتخاب کرده و Create انتخاب کنید:

fe479501dfb91f9f.png

اکنون باید یک محرک جدید Cloud Scheduler ایجاد شده را ببینید:

5a7bc6d96b970b92.png

برای رفتن به صفحه Cloud Scheduler روی View Details کلیک کنید.

می‌توانید تا ساعت 9 صبح منتظر بمانید تا زمان‌بندی شروع به کار کند یا می‌توانید به‌طور دستی Cloud Scheduler را با انتخاب Force Run فعال کنید:

959525f2c8041a6a.png

پس از چند ثانیه، باید ببینید که کار Cloud Scheduler با موفقیت اجرا شده است:

d64e03fc84d61145.png

همچنین باید 3 اسکرین شات دیگر را مشاهده کنید که با تماس از Cloud Scheduler اضافه شده است:

56398a0e827de8b0.png

9. تبریک می گویم

تبریک می گویم، شما نرم افزار کد را تمام کردید!

پاکسازی (اختیاری)

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

اگر به پروژه نیاز ندارید، می توانید به سادگی پروژه را حذف کنید:

gcloud projects delete $PROJECT_ID

اگر به پروژه نیاز دارید، می توانید منابع را به صورت جداگانه حذف کنید.

کد منبع را حذف کنید:

rm -rf ~/jobs-demos/

مخزن Artifact Registry را حذف کنید:

gcloud artifacts repositories delete containers --location=$REGION

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

gcloud iam service-accounts delete screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com

کار Cloud Run را حذف کنید:

gcloud run jobs delete screenshot --region=$REGION

کار Cloud Scheduler را حذف کنید:

gcloud scheduler jobs delete screenshot-scheduler-trigger --location=$REGION

سطل Cloud Storage را حذف کنید:

gcloud storage rm --recursive gs://screenshot-$PROJECT_ID

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

  • نحوه استفاده از برنامه برای گرفتن اسکرین شات از صفحات وب
  • چگونه یک تصویر ظرف برای برنامه بسازیم.
  • نحوه ایجاد یک کار Cloud Run برای برنامه
  • نحوه اجرای برنامه به عنوان یک کار Cloud Run.
  • چگونه کار را به روز کنیم.
  • نحوه برنامه ریزی کار با Cloud Scheduler.