1. Giriş
Genel Bakış
Cloud Run hizmetleri, HTTP isteklerini süresiz olarak dinleyen container'lar için uygundur. Cloud Run işleri ise sonuna kadar çalışan (şu anda 24 saate kadar) ve istek sunmayan container'lar için daha uygundur. Örneğin, bir veritabanından kayıtları işlemek, Cloud Storage paketindeki dosya listesini işlemek veya Pi'yi hesaplama gibi uzun süreli bir işlem, Cloud Run işi olarak uygulandığında iyi sonuç verir.
İşler, istek sunma veya bir bağlantı noktasında dinleme yetkisine sahip değildir. Yani, Cloud Run hizmetlerinin aksine işlerin bir web sunucusu paket halinde sunulmaması gerekir. Bunun yerine, iş kapsayıcıları tamamlandığında çıkış yapmalıdır.
Cloud Run işlerinde, bir dizi görev belirterek container'ınızın birden fazla kopyasını paralel olarak çalıştırabilirsiniz. Her görev, kapsayıcının çalışan bir kopyasını temsil eder. Her görev verilerinizin bir alt kümesini bağımsız olarak işleyebiliyorsa birden fazla görev kullanmak yararlıdır. Örneğin, her biri paralel olarak 1.000 kayıt veya dosya işleyen 10 görevle, Cloud SQL'den 10.000 kayıt veya Cloud Storage'dan 10.000 dosya işleme süreci daha hızlı tamamlanabilir.
Cloud Run işlerini kullanmak iki adımlı bir işlemdir:
- İş oluşturma: Bu, işi çalıştırmak için gereken tüm yapılandırmayı (ör. container görüntüsü, bölge, ortam değişkenleri) içerir.
- İşi çalıştırma: İşin yeni bir yürütülmesini sağlar. İsteğe bağlı olarak, Cloud Scheduler kullanarak işinizi bir plana göre çalışacak şekilde ayarlayın.
Bu codelab'de, web sayfalarının ekran görüntülerini almak ve Cloud Storage'da depolamak için önce bir Node.js uygulamasını keşfedeceksiniz. Ardından, uygulama için bir container görüntüsü derler, Cloud Run işlerinde çalıştırır, daha fazla web sayfası işlemek için işi güncellersiniz ve Cloud Scheduler ile işi plana göre çalıştırırsınız.
Neler öğreneceksiniz?
- Web sayfalarının ekran görüntülerini almak için bir uygulama nasıl kullanılır?
- Uygulama için container görüntüsü derleme.
- Uygulama için Cloud Run işi oluşturma.
- Uygulamanın Cloud Run işi olarak nasıl çalıştırılacağını öğreneceksiniz.
- İşin güncellenmesi
- Cloud Scheduler ile işin nasıl planlanacağı.
2. Kurulum ve Gereksinimler
Kendi hızınızda ortam kurulumu
- Google Cloud Console'da oturum açıp yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Gmail veya Google Workspace hesabınız yoksa hesap oluşturmanız gerekir.
- Proje adı, bu projenin katılımcıları için görünen addır. Google API'leri tarafından kullanılmayan bir karakter dizesidir. İstediğiniz zaman güncelleyebilirsiniz.
- Proje Kimliği, tüm Google Cloud projelerinde benzersizdir ve değiştirilemez (belirlendikten sonra değiştirilemez). Cloud Console, otomatik olarak benzersiz bir dize oluşturur. bunun ne olduğunu umursamıyorsunuz. Çoğu codelab'de proje kimliğinizi (genellikle
PROJECT_ID
olarak tanımlanır) belirtmeniz gerekir. Oluşturulan kimliği beğenmezseniz rastgele bir kimlik daha oluşturabilirsiniz. Alternatif olarak, kendi ölçümünüzü deneyip mevcut olup olmadığına bakabilirsiniz. Bu adımdan sonra değiştirilemez ve proje süresince kalır. - Bilginiz olması açısından, bazı API'lerin kullandığı üçüncü bir değer, yani Proje Numarası daha vardır. Bu değerlerin üçü hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
- Sonraki adımda, Cloud kaynaklarını/API'lerini kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir. Bu codelab'i çalıştırmanın maliyeti, yüksek değildir. Bu eğitim dışında faturalandırmanın tekrarlanmasını önlemek amacıyla kaynakları kapatmak için oluşturduğunuz kaynakları silebilir veya projeyi silebilirsiniz. Yeni Google Cloud kullanıcıları 300 ABD doları değerindeki ücretsiz denemeden yararlanabilir.
Cloud Shell'i Başlatma
Google Cloud dizüstü bilgisayarınızdan uzaktan çalıştırılabilse de bu codelab'de, Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacaksınız.
Google Cloud Console'da, sağ üstteki araç çubuğunda bulunan Cloud Shell simgesini tıklayın:
Ortamı sağlamak ve bağlamak yalnızca birkaç dakika sürer. Tamamlandığında şuna benzer bir sonuç görmeniz gerekir:
İhtiyacınız olan tüm geliştirme araçlarını bu sanal makinede bulabilirsiniz. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud üzerinde çalışarak ağ performansını ve kimlik doğrulamasını büyük ölçüde iyileştirir. Bu codelab'deki tüm çalışmalarınız tarayıcıda yapılabilir. Herhangi bir şey yüklemeniz gerekmez.
gcloud'u kurun
Cloud Shell'de proje kimliğinizi ve Cloud Run işini dağıtmak istediğiniz bölgeyi ayarlayın. Bunları PROJECT_ID
ve REGION
değişkenleri olarak kaydedin. Gelecekte Cloud Run konumlarından birinden bölge seçebileceksiniz.
PROJECT_ID=[YOUR-PROJECT-ID] REGION=us-central1 gcloud config set core/project $PROJECT_ID
API'leri etkinleştir
Gerekli tüm hizmetleri etkinleştirin:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ run.googleapis.com
3. Kodu alın
Öncelikle web sayfalarının ekran görüntülerini almak ve Cloud Storage'da depolamak için bir Node.js uygulamasını keşfedeceksiniz. Daha sonra uygulama için bir container görüntüsü derleyecek ve Cloud Run'da iş olarak çalıştıracaksınız.
Bu depodaki uygulama kodunu klonlamak için Cloud Shell'den aşağıdaki komutu çalıştırın:
git clone https://github.com/GoogleCloudPlatform/jobs-demos.git
Uygulamayı içeren dizine gidin:
cd jobs-demos/screenshot
Şu dosya düzenini görürsünüz:
screenshot | ├── Dockerfile ├── README.md ├── screenshot.js ├── package.json
Aşağıda her dosyanın kısa bir açıklaması verilmiştir:
screenshot.js
, uygulamanın Node.js kodunu içerir.package.json
, kitaplık bağımlılıklarını tanımlar.Dockerfile
, container görüntüsünü tanımlar.
4. Kodu inceleyin
Kodu keşfetmek için Cloud Shell penceresinin üst kısmındaki Open Editor
düğmesini tıklayarak yerleşik metin düzenleyiciyi kullanın.
Aşağıda her dosyanın kısa bir açıklaması verilmiştir.
screenshot.js
screenshot.js
, ilk olarak Puppeteer ve Cloud Storage'ı bağımlılık olarak ekler. Puppeteer, web sayfalarının ekran görüntülerini almak için kullandığınız bir Node.js kitaplığıdır:
const puppeteer = require('puppeteer'); const {Storage} = require('@google-cloud/storage');
Puppeteer'ı başlatmak için initBrowser
ve belirli bir URL'nin ekran görüntüsünü almak için takeScreenshot
işlevi vardır:
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 }); }
Ardından, Cloud Storage paketi almak veya oluşturmak için bir işlev ve web sayfasının ekran görüntüsünü pakete yüklemek için bir işlev daha vardır:
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); }
Son olarak, main
işlevi giriş noktasıdır:
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
yöntemiyle ilgili aşağıdaki noktalara dikkat edin:
- URL'ler bağımsız değişken olarak aktarılır.
- Paket adı, kullanıcı tanımlı
BUCKET_NAME
ortam değişkeni olarak iletilir. Paket adı, tüm Google Cloud'da global olarak benzersiz olmalıdır. - Cloud Run işleri tarafından
CLOUD_RUN_TASK_INDEX
ortam değişkeni iletilir. Cloud Run işleri, benzersiz görevler olarak uygulamanın birden fazla kopyasını çalıştırabilir.CLOUD_RUN_TASK_INDEX
, çalışan görevin dizinini temsil eder. Kod, Cloud Run işlerinin dışında çalıştırıldığında varsayılan olarak sıfır olur. Uygulama birden çok görev olarak çalıştırıldığında, her görev/kapsayıcı sorumlu olduğu URL'yi alır, bir ekran görüntüsü alır ve görüntüyü pakete kaydeder.
package.json
package.json
dosyası uygulamayı tanımlar ve Cloud Storage ile Puppeteer için bağımlılıkları belirtir:
{ "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
, gerekli tüm kitaplıklar ve bağımlılıklarla birlikte uygulama için container görüntüsünü tanımlar:
FROM ghcr.io/puppeteer/puppeteer:16.1.0 COPY package*.json ./ RUN npm ci --omit=dev COPY . . ENTRYPOINT ["node", "screenshot.js"]
5. İş dağıtma
Bir iş oluşturmadan önce işi çalıştırmak için kullanacağınız bir hizmet hesabı oluşturmanız gerekir.
gcloud iam service-accounts create screenshot-sa --display-name="Screenshot app service account"
Paket ve nesne oluşturmak için kullanılabilmesi için hizmet hesabına storage.admin
rolü verin.
gcloud projects add-iam-policy-binding $PROJECT_ID \ --role roles/storage.admin \ --member serviceAccount:screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com
Artık işi çalıştırmak için gereken yapılandırmayı içeren bir Cloud Run işi dağıtmaya hazırsınız.
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
Bu yöntem, kaynak tabanlı dağıtım kullanır ve yürütmeden Cloud Run işi oluşturur.
Web sayfalarının nasıl bağımsız değişken olarak aktarıldığına dikkat edin. Ekran görüntülerinin kaydedileceği paket adı, bir ortam değişkeni olarak iletilir.
--tasks
işaretiyle çalıştırılacak bir dizi görev belirterek kapsayıcınızın birden fazla kopyasını paralel olarak çalıştırabilirsiniz. Her görev, kapsayıcının çalışan bir kopyasını temsil eder. Her görev verilerinizin bir alt kümesini bağımsız olarak işleyebiliyorsa birden fazla görev kullanmak yararlıdır. Bunu kolaylaştırmak için her görev, CLOUD_RUN_TASK_INDEX
ortam değişkeninde depolanan dizinini bilir. Hangi görevin hangi veri alt kümesini işleyeceğini belirlemekten kodunuz sorumludur. Bu örnekte --tasks=2
konusuna dikkat edin. Böylece, işlemek istediğimiz 2 URL için 2 kapsayıcının çalışmasını sağlar.
Her görev 24 saate kadar çalıştırılabilir. Bu örnekte yaptığımız gibi, --task-timeout
işaretini kullanarak bu zaman aşımını azaltabilirsiniz. İşin başarıyla tamamlanabilmesi için tüm görevlerin başarılı olması gerekir. Varsayılan olarak, başarısız görevler yeniden denenmez. Görevleri, başarısız olduklarında yeniden denenecek şekilde yapılandırabilirsiniz. Herhangi bir görev, yeniden deneme sayısını aşarsa tüm iş başarısız olur.
Varsayılan olarak işiniz paralel olarak mümkün olduğunca çok sayıda görevle yürütülür. Bu, işiniz için en fazla 100 görev sayısına eşit olacaktır. Sınırlı ölçeklenebilirliğe sahip bir arka uca erişen işler için paralelliği daha düşük bir değere ayarlamak isteyebilirsiniz. Örneğin, sınırlı sayıda etkin bağlantıyı destekleyen bir veritabanı. --parallelism
işaretini kullanarak paralelliği azaltabilirsiniz.
6. İş çalıştırma
İşi çalıştırmadan önce, işin oluşturulup oluşturulmadığını listeleyin:
gcloud run jobs list ✔ JOB: screenshot REGION: us-central LAST RUN AT: CREATED: 2022-02-22 12:20:50 UTC
İşi aşağıdaki komutla çalıştırın:
gcloud run jobs execute screenshot --region=$REGION
Bu işlem, işi yürütür. Mevcut ve geçmiş yürütme işlemlerini listeleyebilirsiniz:
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
Yürütme sürecini tanımlayın. Yeşil onay işareti ve tasks completed successfully
mesajı gösterilir:
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
Durumu görmek için Cloud Console'un Cloud Run işleri sayfasını da kontrol edebilirsiniz:
Cloud Storage paketini kontrol ederseniz oluşturulan iki ekran görüntüsü dosyasını görürsünüz:
Bazen bir yürütme işlemi tamamlanmadan önce durdurmanız gerekebilir. Bunun nedeni, işi farklı parametrelerle çalıştırmanız gerektiğini fark etmeniz veya kodda bir hata olması ve gereksiz işlem süresini kullanmak istememeniz olabilir.
İşinizin yürütülmesini durdurmak için yürütmeyi silmeniz gerekir:
gcloud run jobs executions delete screenshot-znkmm --region=$REGION
7. İş güncelleme
Container'ınızın yeni sürümleri, bir sonraki yürütmede Cloud Run işleri tarafından otomatik olarak alınmaz. İşinizin kodunu değiştirirseniz container'ı yeniden oluşturmanız ve işinizi güncellemeniz gerekir. Etiketli resimler kullanmak, o anda resmin hangi sürümünün kullanılmakta olduğunu belirlemenize yardımcı olur.
Benzer şekilde, bazı yapılandırma değişkenlerini güncellemek istiyorsanız işi de güncellemeniz gerekir. İşin sonraki yürütmelerinde yeni kapsayıcı ve yapılandırma ayarları kullanılır.
İşi güncelleyin ve uygulamanın ekran görüntüsü aldığı sayfaları --args
işaretinde değiştirin. Ayrıca, sayfa sayısını yansıtmak için --tasks
işaretini güncelleyin.
gcloud run jobs update screenshot \ --args="https://www.pinterest.com" \ --args="https://www.apartmenttherapy.com" \ --args="https://www.google.com" \ --region=$REGION \ --tasks=3
İşi yeniden çalıştırın. Yürütmelerin bitmesini beklemek için --wait
işaretinde bu süre geçti:
gcloud run jobs execute screenshot --region=$REGION --wait
Birkaç saniye sonra, pakete 3 ekran görüntüsü daha eklendiğini görürsünüz:
8. İş planlayın
Şu ana kadar işleri manuel olarak çalıştırıyorsunuz. Gerçek dünyaya ait bir senaryoda işleri bir olaya göre veya bir plana göre yürütmek isteyebilirsiniz. Cloud Scheduler kullanarak ekran görüntüsü işinin planlı olarak nasıl çalıştırılacağını görelim.
İlk olarak, Cloud Scheduler API'nin etkinleştirildiğinden emin olun:
gcloud services enable cloudscheduler.googleapis.com
Cloud Run işlerinin ayrıntılar sayfasına gidin ve Triggers
bölümünü tıklayın:
Add Scheduler Trigger
düğmesini seçin:
Sağ tarafta bir panel açılır. Bu yapılandırmayla her gün saat 09:00'da çalışacak bir Scheduler işi oluşturun ve Continue
öğesini seçin:
Sonraki sayfada varsayılan Compute hizmet hesabını belirleyip Create
değerini seçin:
Şimdi yeni bir Cloud Scheduler tetikleyicisinin oluşturulduğunu göreceksiniz:
Cloud Scheduler sayfasına gitmek için View Details
bağlantısını tıklayın.
Planlayıcının devreye girmesi için saat 09:00'a kadar bekleyebilir veya Force Run
öğesini seçerek Cloud Scheduler'ı manuel olarak tetikleyebilirsiniz:
Birkaç saniye sonra Cloud Scheduler işinin başarıyla yürütüldüğünü görürsünüz:
Ayrıca Cloud Scheduler'ın çağrısıyla eklenen 3 ekran görüntüsü daha göreceksiniz:
9. Tebrikler
Tebrikler, codelab'i tamamladınız.
Temizlik (İsteğe bağlı)
Ücretlerin tekrarlanmasını önlemek için kaynakları temizlemeniz önerilir.
Projeye ihtiyacınız yoksa projeyi silmeniz yeterlidir:
gcloud projects delete $PROJECT_ID
Projeye ihtiyacınız varsa kaynakları tek tek silebilirsiniz.
Kaynak kodu silin:
rm -rf ~/jobs-demos/
Artifact Registry deposunu silin:
gcloud artifacts repositories delete containers --location=$REGION
Hizmet hesabını silin:
gcloud iam service-accounts delete screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com
Cloud Run işini silin:
gcloud run jobs delete screenshot --region=$REGION
Cloud Scheduler işini silin:
gcloud scheduler jobs delete screenshot-scheduler-trigger --location=$REGION
Cloud Storage paketini silin:
gcloud storage rm --recursive gs://screenshot-$PROJECT_ID
İşlediğimiz konular
- Web sayfalarının ekran görüntülerini almak için bir uygulama nasıl kullanılır?
- Uygulama için container görüntüsü derleme.
- Uygulama için Cloud Run işi oluşturma.
- Uygulamanın Cloud Run işi olarak nasıl çalıştırılacağını öğreneceksiniz.
- İşin güncellenmesi
- Cloud Scheduler ile işin nasıl planlanacağı.