1. ภาพรวม
ในโค้ดแล็บนี้ คุณจะได้สร้างบริการ Cloud Run ใหม่ ซึ่งก็คือบริการคอลลาจที่จะทริกเกอร์โดย Cloud Scheduler เป็นช่วงเวลาปกติ บริการจะดึงรูปภาพล่าสุดที่อัปโหลดและสร้างภาพคอลลาจจากรูปภาพเหล่านั้น โดยจะค้นหารายการรูปภาพล่าสุดใน Cloud Firestore แล้วดาวน์โหลดไฟล์รูปภาพจริงจาก Cloud Storage

สิ่งที่คุณจะได้เรียนรู้
- Cloud Run
- Cloud Scheduler
- Cloud Storage
- Cloud Firestore
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง
- ลงชื่อเข้าใช้ Google Cloud Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี



- ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ โดยเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ และคุณสามารถอัปเดตได้ทุกเมื่อ
- รหัสโปรเจ็กต์ต้องไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและเปลี่ยนแปลงไม่ได้ (เปลี่ยนไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (และโดยทั่วไปจะระบุเป็น
PROJECT_ID) ดังนั้นหากไม่ชอบรหัสที่สร้างขึ้น ให้สร้างรหัสแบบสุ่มอีกรหัส หรือจะลองใช้รหัสของคุณเองและดูว่ามีรหัสนั้นหรือไม่ก็ได้ จากนั้นจะ "หยุด" หลังจากสร้างโปรเจ็กต์แล้ว - นอกจากนี้ยังมีค่าที่ 3 คือหมายเลขโปรเจ็กต์ ซึ่ง API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 นี้ได้ในเอกสารประกอบ
- จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การทำตาม Codelab นี้ไม่ควรมีค่าใช้จ่ายมากนัก หรืออาจไม่มีเลย หากต้องการปิดแหล่งข้อมูลเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ให้ทำตามวิธีการ "ล้างข้อมูล" ที่ตอนท้ายของ Codelab ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD
เริ่มต้น Cloud Shell
แม้ว่าคุณจะใช้งาน Google Cloud จากระยะไกลจากแล็ปท็อปได้ แต่ใน Codelab นี้คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
จาก GCP Console ให้คลิกไอคอน Cloud Shell ในแถบเครื่องมือด้านขวาบน

การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมจะใช้เวลาเพียงไม่กี่นาที เมื่อเสร็จแล้ว คุณควรเห็นข้อความคล้ายกับตัวอย่างต่อไปนี้

เครื่องเสมือนนี้มาพร้อมเครื่องมือพัฒนาซอฟต์แวร์ทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักแบบถาวรขนาด 5 GB และทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก คุณสามารถทำงานทั้งหมดในห้องทดลองนี้ได้โดยใช้เพียงเบราว์เซอร์
3. เปิดใช้ API
คุณจะต้องมี Cloud Scheduler เพื่อทริกเกอร์บริการ Cloud Run เป็นช่วงเวลาปกติ ตรวจสอบว่าเปิดใช้แล้ว ดังนี้
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.jspackage.jsonกำหนดทรัพยากร Dependency ของไลบรารีDockerfileกำหนดอิมเมจคอนเทนเนอร์
5. สำรวจโค้ด
ทรัพยากร Dependency
ไฟล์ package.json จะกำหนดทรัพยากร Dependency ของไลบรารีที่จำเป็น
{
"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 Storage เราประกาศการขึ้นต่อกันใน Cloud Firestore เพื่อดึงข้อมูลเมตาของรูปภาพที่เราจัดเก็บไว้ก่อนหน้านี้ Express เป็นเฟรมเวิร์กเว็บ JavaScript / Node Bluebird ใช้สำหรับจัดการ Promise และ 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 ที่โค้ดของเราต้องการ และเรียกใช้โค้ด Node ด้วย npm start
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');
เรากำหนดให้มีทรัพยากร Dependency ต่างๆ ที่จำเป็นต่อการเรียกใช้โปรแกรมของเรา โดย Express คือเฟรมเวิร์กเว็บ Node ที่เราจะใช้, ImageMagick คือไลบรารีสำหรับจัดการรูปภาพ, Bluebird คือไลบรารีสำหรับจัดการสัญญา JavaScript, Path ใช้สำหรับจัดการเส้นทางไฟล์และไดเรกทอรี จากนั้น Storage และ Firestore ใช้สำหรับทำงานร่วมกับ Google Cloud Storage (Bucket รูปภาพของเรา) และที่เก็บข้อมูล Cloud Firestore ตามลำดับ
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 ของเรา ซึ่งแอปจะตอบสนองต่อคำขอ 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 รูปก่อน
เราดึงรูปภาพ 4 รูปภาพล่าสุดที่ผู้ใช้อัปโหลดจากข้อมูลเมตาที่จัดเก็บไว้ใน Cloud Firestore เราจะตรวจสอบว่าคอลเล็กชันที่ได้ว่างเปล่าหรือไม่ จากนั้นจะดำเนินการต่อในกิ่ง 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 เพื่อสร้างตาราง 4x4 ของภาพปกเหล่านั้น เราใช้ไลบรารี Bluebird และการใช้งาน Promise เพื่อเปลี่ยนโค้ดที่ขับเคลื่อนด้วยการเรียกกลับให้เป็นโค้ดที่ใช้งานได้กับ async / await จากนั้นเราจะรอ Promise ที่สร้างภาพคอลลาจ
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");
เนื่องจากระบบได้บันทึกรูปภาพคอลลาจลงในดิสก์ในเครื่องในโฟลเดอร์ชั่วคราวแล้ว ตอนนี้เราจึงต้องอัปโหลดรูปภาพดังกล่าวไปยัง Cloud Storage แล้วส่งคืนการตอบกลับที่สำเร็จ (รหัสสถานะ 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 ให้ติดตั้งทรัพยากร Dependency ของ 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 Run เพื่อสร้างอิมเมจคอนเทนเนอร์ให้คุณได้โดยใช้ Google Cloud Buildpacks แทนการสร้างและเผยแพร่อิมเมจคอนเทนเนอร์โดยใช้ Cloud Build ด้วยตนเอง
เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างอิมเมจคอนเทนเนอร์
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 ในไดเรกทอรีซอร์สโค้ด Buildpack ของ Google Cloud จะตรวจหาภาษาที่คุณใช้โดยอัตโนมัติและดึงข้อมูลการอ้างอิงของโค้ดเพื่อสร้างอิมเมจคอนเทนเนอร์ที่พร้อมใช้งานจริง โดยใช้อิมเมจฐานที่ปลอดภัยซึ่ง Google จัดการ ซึ่งจะแจ้งให้ Cloud Run ใช้ Google Cloud Buildpacks เพื่อสร้างอิมเมจคอนเทนเนอร์ที่กำหนดไว้ใน Dockerfile
นอกจากนี้ โปรดทราบว่าการติดตั้งใช้งานตามแหล่งที่มาจะใช้ Artifact Registry เพื่อจัดเก็บคอนเทนเนอร์ที่สร้างขึ้น Artifact Registry เป็น Google Container Registry เวอร์ชันที่ทันสมัย 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 เพื่อดูว่าได้ตั้งค่าและชี้ไปยัง URL ของบริการ 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 Storage
- Cloud Firestore