Bắt đầu sử dụng các công việc trên Cloud Run

1. Giới thiệu

1965fab24c502bd5.pngs

Tổng quan

Các dịch vụ Cloud Run phù hợp với những vùng chứa chạy vô thời hạn các yêu cầu HTTP, trong khi công việc Cloud Run phù hợp hơn với những vùng chứa chạy đến hết (hiện lên đến 24 giờ) và không phân phát yêu cầu. Ví dụ: xử lý bản ghi từ cơ sở dữ liệu, xử lý danh sách tệp trong bộ chứa Cloud Storage hoặc một thao tác diễn ra trong thời gian dài, chẳng hạn như tính toán số Pi, sẽ hoạt động tốt nếu được triển khai dưới dạng công việc trong Cloud Run.

Công việc không có khả năng đáp ứng các yêu cầu hoặc lắng nghe trên cổng. Điều này có nghĩa là không giống như các dịch vụ Cloud Run, công việc không nên gói máy chủ web. Thay vào đó, vùng chứa công việc sẽ thoát khi hoàn tất.

Trong các công việc trên Cloud Run, bạn có thể chạy song song nhiều bản sao vùng chứa của mình bằng cách chỉ định một số tác vụ. Mỗi tác vụ đại diện cho một bản sao đang chạy của vùng chứa. Việc sử dụng nhiều công việc sẽ hữu ích nếu mỗi công việc có thể xử lý độc lập một nhóm nhỏ dữ liệu của bạn. Ví dụ: việc xử lý 10.000 bản ghi từ Cloud SQL hoặc 10.000 tệp từ Cloud Storage có thể được thực hiện nhanh hơn với 10 tác vụ xử lý 1.000 bản ghi hoặc tệp, mỗi bản ghi hoặc tệp song song.

Sử dụng công việc trên Cloud Run là quy trình 2 bước:

  1. Tạo công việc: Thao tác này sẽ đóng gói tất cả cấu hình cần thiết để chạy công việc, chẳng hạn như hình ảnh vùng chứa, khu vực, các biến môi trường.
  2. Chạy công việc: Thao tác này sẽ tạo ra một quy trình thực thi công việc mới. Bạn có thể thiết lập công việc của mình để chạy theo lịch biểu bằng Trình lập lịch biểu đám mây (không bắt buộc).

Trong lớp học lập trình này, trước tiên bạn sẽ khám phá ứng dụng Node.js để chụp ảnh màn hình các trang web và lưu trữ chúng vào Cloud Storage. Sau đó, bạn sẽ tạo hình ảnh vùng chứa cho ứng dụng, chạy công việc đó trong các công việc trên Cloud Run, cập nhật công việc để xử lý nhiều trang web hơn và chạy công việc theo lịch bằng Cloud Scheduler.

Kiến thức bạn sẽ học được

  • Cách dùng ứng dụng để chụp ảnh màn hình trang web.
  • Cách tạo hình ảnh vùng chứa cho ứng dụng.
  • Cách tạo công việc trên Cloud Run cho ứng dụng.
  • Cách chạy ứng dụng ở dạng một công việc trên Cloud Run.
  • Cách cập nhật việc làm.
  • Cách lên lịch công việc bằng Cloud Scheduler.

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tiến độ riêng

  1. Đăng nhập vào Google Cloud Console rồi tạo dự án mới hoặc sử dụng lại dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

295004821bab6a87.pngS

37d264871000675d.png.

96d86d3d5655cdbe.png.

  • Tên dự án là tên hiển thị của những người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn luôn có thể cập nhật ứng dụng.
  • Mã dự án là duy nhất trong tất cả các dự án Google Cloud và không thể thay đổi (không thể thay đổi sau khi đã đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường bạn không quan tâm đến sản phẩm đó là gì. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham khảo Mã dự án của mình (thường được xác định là PROJECT_ID). Nếu không thích mã đã tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Ngoài ra, bạn có thể thử cách riêng của mình để xem có thể sử dụng hay không. Bạn không thể thay đổi mã này sau bước này và mã vẫn giữ nguyên trong thời gian dự án.
  • Đối với thông tin của bạn, có giá trị thứ ba, Project Number (Số dự án), mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu này.
  1. Tiếp theo, bạn sẽ phải bật tính năng thanh toán trong Cloud Console để sử dụng API/tài nguyên trên đám mây. Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Để tắt các tài nguyên nhằm tránh phát sinh việc thanh toán ngoài hướng dẫn này, bạn có thể xoá các tài nguyên bạn đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

Khởi động Cloud Shell

Mặc dù bạn có thể vận hành Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trong Đám mây.

Trong Google Cloud Console, hãy nhấp vào biểu tượng Cloud Shell ở thanh công cụ trên cùng bên phải:

84688aa223b1c3a2.pngS

Sẽ chỉ mất một chút thời gian để cấp phép và kết nối với môi trường. Sau khi hoàn tất, bạn sẽ thấy như sau:

320e18fb7fbe0.pngs

Máy ảo này chứa tất cả các công cụ phát triển mà bạn cần. Phiên bản này cung cấp thư mục gốc có dung lượng ổn định 5 GB và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Bạn có thể thực hiện mọi công việc trong lớp học lập trình này trong trình duyệt. Bạn không cần cài đặt gì cả.

Thiết lập gcloud

Trong Cloud Shell, hãy đặt mã dự án và khu vực mà bạn muốn triển khai công việc Cloud Run. Hãy lưu các biến này dưới dạng biến PROJECT_IDREGION. Trong tương lai, bạn có thể chọn một khu vực từ một trong các địa điểm Cloud Run.

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

Bật API

Bật tất cả dịch vụ cần thiết:

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

3. Lấy mã

Trước tiên, bạn sẽ khám phá ứng dụng Node.js để chụp ảnh màn hình các trang web và lưu trữ chúng vào Cloud Storage. Sau đó, bạn tạo hình ảnh vùng chứa cho ứng dụng và chạy ứng dụng đó như một công việc trên Cloud Run.

Trên Cloud Shell, hãy chạy lệnh sau để sao chép mã xử lý ứng dụng từ kho lưu trữ này:

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

Chuyển đến thư mục chứa ứng dụng:

cd jobs-demos/screenshot

Bạn sẽ thấy bố cục tệp này:

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

Dưới đây là nội dung mô tả ngắn gọn về từng tệp:

  • screenshot.js chứa mã Node.js cho ứng dụng này.
  • package.json xác định các phần phụ thuộc của thư viện.
  • Dockerfile xác định hình ảnh vùng chứa.

4. Khám phá đoạn mã

Để khám phá mã này, hãy sử dụng trình chỉnh sửa văn bản tích hợp sẵn bằng cách nhấp vào nút Open Editor ở đầu cửa sổ Cloud Shell.

15a2cdc9b7f6dfc6.png.

Dưới đây là nội dung giải thích ngắn gọn về từng tệp.

screenshot.js

Trước tiên, screenshot.js sẽ thêm Puppeteer và Cloud Storage làm phần phụ thuộc. Puppeteer là một thư viện Node.js mà bạn sử dụng để chụp ảnh màn hình các trang web:

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

Có một hàm initBrowser để khởi chạy Puppeteer và hàm takeScreenshot để chụp ảnh màn hình của một URL nhất định:

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
  });
}

Tiếp theo, có một chức năng để tải hoặc tạo một bộ chứa Cloud Storage và một hàm khác để tải ảnh chụp màn hình của một trang web lên một bộ chứa:

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);
}

Cuối cùng, hàm main là điểm vào:

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);
});

Hãy lưu ý những điều sau về phương thức main:

  • URL được truyền dưới dạng đối số.
  • Tên bộ chứa được truyền vào dưới dạng biến môi trường BUCKET_NAME do người dùng xác định. Tên bộ chứa phải là duy nhất trên toàn hệ thống trên tất cả Google Cloud.
  • Biến môi trường CLOUD_RUN_TASK_INDEX được các công việc trong Cloud Run truyền qua. Các công việc trên Cloud Run có thể chạy nhiều bản sao của ứng dụng dưới dạng các tác vụ riêng biệt. CLOUD_RUN_TASK_INDEX biểu thị chỉ mục của tác vụ đang chạy. Giá trị mặc định là 0 khi mã được chạy bên ngoài các công việc trên Cloud Run. Khi ứng dụng chạy dưới nhiều tác vụ, mỗi tác vụ/vùng chứa sẽ chọn URL chịu trách nhiệm, chụp ảnh màn hình và lưu hình ảnh vào bộ chứa.

package.json

Tệp package.json xác định ứng dụng và chỉ định các phần phụ thuộc cho Cloud Storage và 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"
  }
}

Tệp Docker

Dockerfile xác định hình ảnh vùng chứa cho ứng dụng với tất cả các thư viện và phần phụ thuộc bắt buộc:

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

5. Triển khai công việc

Trước khi tạo công việc, bạn cần tạo một tài khoản dịch vụ mà bạn sẽ dùng để chạy công việc đó.

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

Cấp vai trò storage.admin cho tài khoản dịch vụ để tài khoản dịch vụ có thể được dùng để tạo nhóm và đối tượng.

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

Giờ đây, bạn đã sẵn sàng triển khai công việc trên Cloud Run có cấu hình cần thiết để chạy công việc đó.

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

Tính năng này sử dụng phương thức triển khai dựa trên nguồn và tạo một công việc trên Cloud Run mà không cần thực thi.

Hãy lưu ý cách các trang web được truyền vào dưới dạng đối số. Tên bộ chứa để lưu ảnh chụp màn hình được truyền vào dưới dạng biến môi trường.

Bạn có thể chạy song song nhiều bản sao vùng chứa bằng cách chỉ định một số tác vụ để chạy bằng cờ --tasks. Mỗi tác vụ đại diện cho một bản sao đang chạy của vùng chứa. Việc sử dụng nhiều công việc sẽ hữu ích nếu mỗi công việc có thể xử lý độc lập một nhóm nhỏ dữ liệu của bạn. Để hỗ trợ việc này, mỗi tác vụ đều nhận biết được chỉ mục riêng được lưu trữ trong biến môi trường CLOUD_RUN_TASK_INDEX. Mã của bạn chịu trách nhiệm xác định tác vụ nào sẽ xử lý tập hợp con dữ liệu nào. Hãy chú ý --tasks=2 trong mẫu này. Việc này giúp đảm bảo 2 vùng chứa sẽ chạy cho 2 URL mà chúng ta muốn xử lý.

Mỗi tác vụ có thể chạy trong tối đa 24 giờ. Bạn có thể giảm thời gian chờ này bằng cách sử dụng cờ --task-timeout như chúng ta đã làm trong ví dụ này. Tất cả các nhiệm vụ đều cần phải thành công thì công việc mới có thể hoàn tất thành công. Theo mặc định, những tác vụ không thành công sẽ không được thử lại. Bạn có thể định cấu hình để thử lại các tác vụ khi chúng không thành công. Nếu bất kỳ tác vụ nào vượt quá số lần thử lại thì toàn bộ tác vụ sẽ không thành công.

Theo mặc định, công việc của bạn sẽ chạy cùng lúc nhiều tác vụ nhất có thể. Số lượng việc cần làm này sẽ bằng số lượng công việc của bạn, tối đa là 100. Bạn nên đặt mức độ song song thấp hơn cho các công việc truy cập vào phần phụ trợ có khả năng mở rộng hạn chế. Ví dụ: một cơ sở dữ liệu chỉ hỗ trợ một số ít kết nối đang hoạt động. Bạn có thể giảm tính song song bằng cờ --parallelism.

6. Chạy tác vụ

Trước khi chạy công việc, hãy liệt kê công việc để xem nó đã được tạo chưa:

gcloud run jobs list

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

Chạy công việc bằng lệnh sau:

gcloud run jobs execute screenshot --region=$REGION

Thao tác này sẽ thực thi công việc. Bạn có thể liệt kê các quá trình thực thi hiện tại và trước đây:

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

Mô tả quá trình thực thi. Bạn sẽ thấy dấu kiểm màu xanh lục và thông báo 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

Bạn cũng có thể truy cập trang công việc trên Cloud Run của Cloud Console để xem trạng thái:

1afde14d65f0d9ce.png.

Nếu kiểm tra bộ chứa Cloud Storage, bạn sẽ thấy hai tệp ảnh chụp màn hình được tạo:

7c4d355f6f65106.pngS

Đôi khi, bạn có thể cần dừng quá trình thực thi trước khi hoàn tất, có thể là do bạn nhận ra rằng mình cần chạy công việc bằng các tham số khác nhau hoặc có lỗi trong mã và bạn không muốn sử dụng thời gian tính toán không cần thiết.

Để dừng thực thi công việc của mình, bạn cần xoá thực thi:

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

7. Cập nhật việc làm

Các công việc trên Cloud Run sẽ không tự động chọn các phiên bản mới của vùng chứa trong lần thực thi tiếp theo. Nếu thay đổi mã cho công việc của mình, bạn cần xây dựng lại vùng chứa và cập nhật công việc của mình. Bằng cách sử dụng hình ảnh được gắn thẻ, bạn sẽ xác định phiên bản hình ảnh nào đang được sử dụng.

Tương tự, bạn cũng cần cập nhật công việc nếu muốn cập nhật một số biến cấu hình. Các lần thực thi công việc tiếp theo sẽ sử dụng các chế độ cài đặt cấu hình và vùng chứa mới.

Cập nhật công việc và thay đổi các trang mà ứng dụng chụp ảnh màn hình trong cờ --args. Ngoài ra, hãy cập nhật cờ --tasks để phản ánh số lượng trang.

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

Chạy lại công việc. Thời gian này chuyển vào cờ --wait để chờ các lượt thực thi hoàn tất:

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

Sau vài giây, bạn sẽ thấy thêm 3 ảnh chụp màn hình được thêm vào bộ chứa:

ed0cbe0b5a5f9144.png

8. Lên lịch làm việc

Cho đến nay, bạn đang chạy các công việc theo cách thủ công. Trong tình huống thực tế, có thể bạn sẽ muốn chạy các công việc theo một sự kiện hoặc theo một lịch trình. Hãy xem cách chạy tác vụ chụp ảnh màn hình theo lịch bằng Trình lập lịch biểu trên đám mây.

Trước tiên, hãy đảm bảo bạn đã bật Cloud Scheduler API:

gcloud services enable cloudscheduler.googleapis.com

Truy cập trang chi tiết công việc trong Cloud Run rồi nhấp vào mục Triggers:

3ae456368905472f.png.

Chọn nút Add Scheduler Trigger:

48cbba777f75e1eb.png.

Một bảng điều khiển sẽ mở ra ở bên phải. Tạo công việc Trình lập lịch biểu để chạy lúc 9:00 hằng ngày bằng cấu hình này rồi chọn Continue:

81fd098be0db216.pngS

Trên trang tiếp theo, hãy chọn tài khoản dịch vụ mặc định của Compute Engine rồi chọn Create:

fe479501dfb91f9f.png

Bây giờ, bạn sẽ thấy một điều kiện kích hoạt Cloud Scheduler mới được tạo:

5a7bc6d96b970b92.pngS

Nhấp vào View Details để truy cập vào trang Cloud Scheduler.

Bạn có thể đợi đến 9 giờ sáng để trình lập lịch biểu bắt đầu hoạt động, hoặc bạn có thể kích hoạt Trình lập lịch biểu đám mây theo cách thủ công bằng cách chọn Force Run:

959525f2c8041a6a.pngS

Sau vài giây, bạn sẽ thấy công việc của Cloud Scheduler được thực thi thành công:

d64e03fc84d61145.png

Bạn cũng sẽ thấy 3 ảnh chụp màn hình khác có trong cuộc gọi từ Cloud Scheduler:

56398a0e827de8b0.pngS

9. Xin chúc mừng

Xin chúc mừng, bạn đã hoàn thành lớp học lập trình!

Dọn dẹp (Không bắt buộc)

Để tránh phát sinh chi phí, bạn nên dọn dẹp tài nguyên.

Nếu không cần dự án, bạn chỉ cần xoá dự án đó theo cách sau:

gcloud projects delete $PROJECT_ID

Nếu cần dự án, bạn có thể xoá từng tài nguyên.

Xoá mã nguồn:

rm -rf ~/jobs-demos/

Xoá kho lưu trữ Artifact Registry:

gcloud artifacts repositories delete containers --location=$REGION

Xoá tài khoản dịch vụ:

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

Xoá công việc trên Cloud Run:

gcloud run jobs delete screenshot --region=$REGION

Xoá công việc của Cloud Scheduler:

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

Xoá bộ chứa Cloud Storage:

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

Nội dung đã đề cập

  • Cách dùng ứng dụng để chụp ảnh màn hình trang web.
  • Cách tạo hình ảnh vùng chứa cho ứng dụng.
  • Cách tạo công việc trên Cloud Run cho ứng dụng.
  • Cách chạy ứng dụng ở dạng một công việc trên Cloud Run.
  • Cách cập nhật việc làm.
  • Cách lên lịch công việc bằng Cloud Scheduler.