1. ภาพรวม
ใน Code Lab นี้ คุณสร้างบริการ 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 ของระบบคลาวด์ การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ให้ทำตาม "การล้าง" ดูได้ที่ตอนท้ายของ Codelab ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD
เริ่มต้น Cloud Shell
แม้ว่าคุณจะดำเนินการ Google Cloud จากระยะไกลได้จากแล็ปท็อป แต่คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานในระบบคลาวด์ใน Codelab นี้
จากคอนโซล GCP ให้คลิกไอคอน Cloud Shell บนแถบเครื่องมือด้านขวาบนดังนี้
การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมนี้ควรใช้เวลาเพียงครู่เดียว เมื่อเสร็จแล้ว คุณจะเห็นข้อมูลต่อไปนี้
เครื่องเสมือนนี้เต็มไปด้วยเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักขนาด 5 GB ที่ใช้งานได้ต่อเนื่องและทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานทั้งหมดใน Lab นี้สามารถทำได้โดยใช้เบราว์เซอร์
3. เปิดใช้ API
คุณจะต้องใช้ Cloud Scheduler เพื่อทริกเกอร์บริการ Cloud Run ในช่วงเวลาที่สม่ำเสมอ ตรวจสอบว่าได้เปิดใช้แล้ว โดยทำดังนี้
gcloud services enable cloudscheduler.googleapis.com
คุณควรเห็นการดำเนินการที่เสร็จสิ้นเรียบร้อยแล้ว
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
4. โคลนโค้ด
โคลนโค้ดหากยังไม่ได้ทำใน Code Lab ก่อนหน้านี้:
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. สำรวจโค้ด
การขึ้นต่อกัน
ไฟล์ 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 / โหนด 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" ]
เราใช้อิมเมจฐาน 14 แบบสว่าง เรากำลังติดตั้งไลบรารีรูปภาพ จากนั้นเราจะติดตั้งโมดูล 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');
เราต้องการทรัพยากร Dependency ต่างๆ ที่จำเป็นต่อการเรียกใช้โปรแกรม ได้แก่ Express คือเฟรมเวิร์กเว็บของโหนดที่เราจะใช้, ImageMagick ไลบรารีสำหรับจัดการรูปภาพ, Bluebird เป็นไลบรารีสำหรับจัดการคำขอของ JavaScript, เส้นทางใช้เพื่อจัดการกับไฟล์และเส้นทางไดเรกทอรี จากนั้น Storage และ Firestore สำหรับการทำงานร่วมกับ Google Cloud Storage (ที่เก็บข้อมูลรูปภาพของเรา) และพื้นที่เก็บข้อมูล 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);
}
});
ด้านบนเรามีโครงสร้างของเครื่องจัดการโหนด โดยแอปของเราตอบสนองต่อคำขอ 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 Firerstore ตรวจสอบว่าคอลเล็กชันที่ได้ว่างเปล่าหรือไม่ จากนั้นจึงดําเนินการต่อในโค้ดของเราส่วนอื่น
เรามารวบรวมรายชื่อชื่อไฟล์กัน
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 เพื่อเปลี่ยนโค้ดที่มาจาก Callback ให้เป็นโค้ด friendly 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");
เนื่องจากระบบได้บันทึกภาพคอลลาจไปยังดิสก์ในโฟลเดอร์ชั่วคราวภายในเครื่องแล้ว เราจึงต้องอัปโหลดไปยัง 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.");
ตอนนี้ถึงเวลาทำให้สคริปต์โหนดของเราฟังคำขอที่เข้ามาแล้ว:
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 ด้วยตนเอง คุณยังใช้ Cloud Run สร้างอิมเมจคอนเทนเนอร์ให้คุณโดยใช้ Google Cloud Buildpack ได้ด้วย
เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างอิมเมจคอนเทนเนอร์
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 Buildpacks จะตรวจหาภาษาที่คุณใช้อยู่โดยอัตโนมัติและดึงทรัพยากร Dependency ของโค้ดเพื่อสร้างอิมเมจคอนเทนเนอร์ที่พร้อมใช้งานจริง โดยใช้อิมเมจฐานที่ปลอดภัยที่จัดการโดย Google การดำเนินการนี้จะแจ้ง Cloud Run ให้ใช้ Google Cloud Buildpack เพื่อสร้างอิมเมจคอนเทนเนอร์ที่กำหนดไว้ใน 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 ใน 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