C# dilindeki Google Cloud Functions

1. Giriş

Google Cloud Run işlevleri, etkinlik odaklı bir sunucusuz işlem platformudur. Cloud Run işlevleri, kaynak sağlama veya değişen gereksinimleri karşılamak için ölçeklendirme konusunda endişelenmeden kodunuzu yazmanıza olanak tanır.

İki tür Cloud Run işlevi vardır:

  • HTTP işlevleri, HTTP isteklerine yanıt verir.
  • Etkinlik işlevleri, Cloud Pub/Sub'a mesaj yayınlanması veya Cloud Storage'a dosya yüklenmesi gibi etkinliklerle tetiklenir.

efb3268e3b74ed4f.png

Bu codelab'de, C# ile kendi Cloud Run işlevlerinizi oluşturma adımları açıklanmaktadır. Daha spesifik olarak, çeşitli Google Cloud kaynaklarından gelen HTTP ve CloudEvents'e yanıt veren C# işlevleri dağıtacaksınız.

Neler öğreneceksiniz?

  • .NET için Functions Framework.
  • HTTP işlevi yazma
  • Cloud Storage etkinliklerine yanıt veren, etkinliğe dayalı işlev yazma
  • Cloud Pub/Sub etkinliklerine yanıt veren, etkinliğe dayalı işlev yazma
  • Herhangi bir etkinlik türüne yanıt veren bir etkinlik tetiklemeli işlev yazma

2. Kurulum ve Gereksinimler

Yönlendirmesiz ortam kurulumu

  1. Google Cloud Console'da oturum açın ve 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.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 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. Dilediğiniz zaman bunu güncelleyebilirsiniz.
  • Proje kimliği, tüm Google Cloud projelerinde benzersiz olmalı ve sabittir (ayarlandıktan sonra değiştirilemez). Cloud Console, benzersiz bir dizeyi otomatik olarak oluşturur. Genellikle bu dizenin ne olduğuyla ilgilenmezsiniz. Çoğu codelab'de proje kimliğine (genellikle PROJECT_ID olarak tanımlanır) başvurmanız gerekir. Oluşturulan kimliği beğenmezseniz başka bir rastgele kimlik oluşturabilirsiniz. Dilerseniz kendi adınızı deneyerek kullanılabilir olup olmadığını kontrol edebilirsiniz. Bu adımdan sonra değiştirilemez ve proje süresince geçerli kalır.
  • Bazı API'lerin kullandığı üçüncü bir değer olan Proje Numarası da vardır. Bu üç değer hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
  1. Ardından, Cloud kaynaklarını/API'lerini kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir. Bu codelab'i tamamlamak neredeyse hiç maliyetli değildir. Bu eğitimin ötesinde faturalandırma ücreti alınmaması için kaynakları kapatmak üzere oluşturduğunuz kaynakları veya projenin tamamını silebilirsiniz. Google Cloud'un yeni kullanıcıları 300 ABD doları değerinde ücretsiz deneme programından yararlanabilir.

Cloud Shell'i başlatma

Google Cloud, dizüstü bilgisayarınızdan uzaktan çalıştırılabilir. Ancak 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 Cloud Shell simgesini tıklayın:

55efc1aaa7a4d3ad.png

Ortamın temel hazırlığı ve bağlanması yalnızca birkaç dakikanızı alır. İşlem tamamlandığında aşağıdakine benzer bir sonuç görürsünüz:

7ffe5cbb04455448.png

Bu sanal makine, ihtiyaç duyacağınız tüm geliştirme araçlarını içerir. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud üzerinde çalışır. Bu sayede ağ performansı ve kimlik doğrulama önemli ölçüde güçlenir. Bu codelab'deki tüm çalışmalarınızı tarayıcıda yapabilirsiniz. Herhangi bir şey yüklemeniz gerekmez.

3. Başlamadan önce

Cloud Shell'de, gerekli hizmetleri etkinleştirmek için aşağıdaki komutu çalıştırın:

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

Ardından bölgenizi ayarlayın.

REGION=<YOUR_REGION>

Bu codelab'de, Cloud Storage'dan etkinlik almak ve Cloud Run işlevini çağırmak için gerekli EventArc izinlerine ve Cloud Run invoker rolüne sahip bir hizmet hesabı oluşturacaksınız.

Öncelikle hizmet hesabını oluşturun.

PROJECT_ID=$(gcloud config get-value core/project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

SERVICE_ACCOUNT="cloud-run-functions"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run functions Eventarc service account"

Ardından, tetikleyicinin etkinlik sağlayıcılardan etkinlik alabilmesi için projede Eventarc Etkinlik Alıcısı rolünü (roles/eventarc.eventReceiver) Eventarc tetikleyicinizle ilişkili hizmet hesabına verin.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/eventarc.eventReceiver

Ardından, hizmet hesabına Cloud Run Invoker rolünü vererek işlevi çağırmasına izin verin.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

4. .NET için Functions Framework

.NET için Functions Framework, taşınabilir .NET işlevleri yazmak için kullanılan açık kaynaklı bir FaaS (hizmet olarak işlev) çerçevesidir ve Google Cloud Functions ekibi tarafından geliştirilmiştir.

Functions Framework, aşağıdakiler de dahil olmak üzere birçok farklı ortamda çalışan basit işlevler yazmanıza olanak tanır:

  • Google Cloud Run işlevleri
  • Yerel geliştirme makineniz
  • Cloud Run ve GKE'de Cloud Run
  • Knative tabanlı ortamlar

Bu codelab'de, C# dilinde Cloud Functions işlevleri oluşturmak ve dağıtmak için .NET için Functions Framework'ü ve şablonlarını kullanacaksınız.

Cloud Shell'de, dotnet için Cloud Functions şablonlarını yüklemek üzere aşağıdaki komutu çalıştırın:

dotnet new install Google.Cloud.Functions.Templates

Bu işlem, dotnet için 3 şablon yükler. Her şablon C#, F# ve VB'de kullanılabilir (ancak bu laboratuvarda yalnızca C# kullanacaksınız). Şablonların yüklendiğini doğrulamak için aşağıdaki komutu çalıştırabilirsiniz:

dotnet new list

Templates                                                 Short Name            
-----------------------------------------------------------------------
Google Cloud Functions CloudEvent Function                gcf-event
Google Cloud Functions CloudEvent Function (Untyped)      gcf-untyped-event
Google Cloud Functions HttpFunction                       gcf-http

5. HTTP İşlevi

HTTP isteklerine yanıt veren bir HTTP işlevi oluşturup dağıtacaksınız.

gcf-http şablonunu kullanarak bir HTTP işlevi oluşturun:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

Bu komut bir proje ve HTTP isteklerine yanıt veren bir Function.cs dosyası oluşturur.

.csproj dosyasında hedef çerçeveyi net8.0 olarak değiştirin:

<TargetFramework>net8.0</TargetFramework>

Cloud Run işlevini doğrudan Cloud Run'a dağıtmak için aşağıdaki komutu çalıştırın:

gcloud beta run deploy hello-http-function \
    --source . \
    --function HelloHttp.Function \
    --base-image dotnet8 \
    --region $REGION \
    --allow-unauthenticated

Cloud Functions 2. nesil olarak dağıtmayı tercih ederseniz aşağıdaki komutu kullanın:

gcloud functions deploy hello-http-function \
    --allow-unauthenticated \
    --entry-point HelloHttp.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-http

İşleviniz dağıtıldıktan sonra aşağıdaki curl komutunu kullanarak işlevinizi çağırabilirsiniz:

SERVICE_URL=$(gcloud run services describe hello-http-function --platform managed --region $REGION --format 'value(status.url)')

curl $SERVICE_URL

6. CloudEvent Function - GCS

Google Cloud Storage (GCS) etkinliklerine yanıt veren bir CloudEvent işlevi oluşturup dağıtacaksınız.

Öncelikle bir Cloud Storage paketi oluşturun. Bu, daha sonra etkinlikleri dinleyeceğiniz pakettir:

BUCKET_NAME="cloud-functions-bucket-${PROJECT_ID}"
gsutil mb -l us-central1 gs://${BUCKET_NAME}

gcf-event şablonunu kullanarak CloudEvent işlevi oluşturun:

cd ..
mkdir HelloGcs
cd HelloGcs
dotnet new gcf-event

Bu komut, bir proje ve CloudEvent isteklerine yanıt veren bir Function.cs dosyası oluşturur. Ayrıca CloudEvent verilerini StorageObjectData olarak ayrıştırır.

.csproj dosyasında hedef çerçeveyi net8.0 olarak değiştirin:

<TargetFramework>net8.0</TargetFramework>

Cloud Run işlevini doğrudan Cloud Run'a dağıtmak için önce işlevi dağıtır, ardından işlev için bir tetikleyici oluşturursunuz.

gcloud beta run deploy hello-gcs-function \
      --source . \
      --function HelloGcs.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Şimdi Cloud Run işlevi için tetikleyici oluşturun.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-gcs-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-gcs-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

İşlevi 2. nesil Cloud Functions olarak dağıtmayı tercih ederseniz trigger-event ve trigger-resource işaretlerini kullanarak dağıtmak için aşağıdaki komutu kullanabilirsiniz:

gcloud functions deploy hello-gcs-function \
    --allow-unauthenticated \
    --entry-point HelloGcs.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME} \
    --service-account=$SERVICE_ACCOUNT_ADDRESS

Birkaç dakika sonra işlev Cloud Console'da görünür:

c28654d74bb31420.png

Depolama paketine dosya yükleyerek işlevi tetikleyin:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Günlükleri okuyarak işlevin tetiklendiğini doğrulayın:

Cloud Run işlevi için şu komutu çalıştırabilirsiniz:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

2. nesil bir işlev için şu komutu çalıştırabilirsiniz:

gcloud functions logs read hello-gcs-function \
    --gen2 \
    --region us-central1

7. CloudEvent işlevi - Pub/Sub

Cloud Pub/Sub etkinliklerine yanıt veren bir CloudEvent işlevi oluşturup dağıtacaksınız.

İlk olarak, etkinlik yayınlayacak bir Cloud Pub/Sub konusu oluşturun:

TOPIC_NAME=cloud-functions-topic
gcloud pubsub topics create ${TOPIC_NAME}

gcf-event şablonunu kullanarak CloudEvent işlevi oluşturun:

cd ..
mkdir HelloPubSub
cd HelloPubSub
dotnet new gcf-event

Bu komut, bir proje ve CloudEvent isteklerine yanıt veren bir Function.cs dosyası oluşturur. Ayrıca CloudEvent verilerini varsayılan olarak StorageObjectData'ye ayrıştırır.

.csproj dosyasında hedef çerçeveyi net8.0 olarak değiştirin:

<TargetFramework>net8.0</TargetFramework>

Pub/Sub mesajlarını ayrıştırmak için StorageObjectData değerini MessagePublishedData olarak değiştirin. Google.Events.Protobuf.Cloud.Storage.V1 kelimesini Google.Events.Protobuf.Cloud.PubSub.V1 olarak değiştirin.

Sonunda işleviniz aşağıdaki gibi görünmelidir:

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Cloud.PubSub.V1;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace HelloPubSub;

public class Function : ICloudEventFunction<MessagePublishedData>
{
    public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
    {
        var nameFromMessage = data.Message?.TextData;
        var name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage;
        Console.WriteLine($"Hello {name}");
        return Task.CompletedTask;
    }
}

Cloud Run işlevini doğrudan Cloud Run'a dağıtmak için önce işlevi dağıtır, ardından işlev için bir tetikleyici oluşturursunuz.

gcloud beta run deploy hello-pubsub-function \
      --source . \
      --function HelloPubSub.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated \
      --service-account=$SERVICE_ACCOUNT_ADDRESS

Şimdi Cloud Run işlevi için tetikleyiciyi oluşturun.

gcloud eventarc triggers create my-pubsub-trigger \
    --location=$REGION \
    --service-account=$SERVICE_ACCOUNT_ADDRESS \
    --destination-run-service=hello-pubsub-function \
    --destination-run-region=$REGION \
    --destination-run-path="/" \
    --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
    --transport-topic=projects/$PROJECT_ID/topics/$TOPIC_NAME

2. nesil Cloud Functions olarak dağıtmayı tercih ederseniz trigger-topic işaretini kullanarak işlevi dağıtmak için aşağıdaki komutu kullanabilirsiniz:

gcloud functions deploy hello-pubsub-function \
    --allow-unauthenticated \
    --entry-point HelloPubSub.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-topic ${TOPIC_NAME}

Birkaç dakika sonra işlev Cloud Console'da görünür:

3443808da7caf3bc.png

Konuya mesaj yayınlayarak işlevi tetikleyin:

gcloud pubsub topics publish ${TOPIC_NAME} --message="World"

Günlükleri okuyarak işlevin tetiklendiğini doğrulayın.

Cloud Run işlevi için şu komutu çalıştırabilirsiniz:

gcloud logging read "resource.labels.service_name=hello-pubsub-function AND textPayload: World" --format=json

2. nesil bir işlev için şu komutu çalıştırabilirsiniz:

gcloud functions logs read hello-pubsub-function \
    --gen2 \
    --region us-central1

8. CloudEvent Function - Untyped

CloudEvents ile deneme yapıyorsanız ve henüz kullanmak istediğiniz bir yük veri modeliniz yoksa veya işlevinizin herhangi bir Cloud Event'i işleyebilmesini istiyorsanız türsüz bir CloudEvent işlevi kullanabilirsiniz.

gcf-untyped-event şablonunu kullanarak bir CloudEvent işlevi oluşturun:

cd ..
mkdir HelloUntyped
cd HelloUntyped
dotnet new gcf-untyped-event

Bu işlem, CloudEvent isteklerine yanıt veren bir proje ve Function.cs dosyası oluşturur. CloudEvent verilerini ayrıştırma girişimi yapılmaz.

.csproj dosyasında hedef çerçeveyi net8.0 olarak değiştirin:

<TargetFramework>net8.0</TargetFramework>

Cloud Run işlevini doğrudan Cloud Run'a dağıtmak için önce işlevi dağıtır, ardından işlev için bir tetikleyici oluşturursunuz.

gcloud beta run deploy hello-untyped-function \
      --source . \
      --function HelloUntyped.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Şimdi Cloud Run işlevi için tetikleyici oluşturun.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-untyped-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-untyped-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

İşlevi 2. nesil Cloud Functions olarak dağıtmayı tercih ederseniz trigger-event ve trigger-resource işaretlerini kullanarak dağıtmak için aşağıdaki komutu kullanabilirsiniz:

gcloud functions deploy hello-untyped-function \
    --allow-unauthenticated \
    --entry-point HelloUntyped.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME}

İşlev, bir depolama paketine dosya yüklendiğinde tetiklenir.

Birkaç dakika sonra işlev Cloud Console'da görünür:

afe56530826787c6.png

Depolama paketine dosya yükleyerek işlevi tetikleyin:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Günlükleri okuyarak işlevin tetiklendiğini doğrulayın.

Cloud Run işlevi için şu komutu çalıştırabilirsiniz:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

2. nesil bir işlev için şu komutu çalıştırabilirsiniz:

gcloud functions logs read hello-untyped-function \
    --gen2 \
    --region us-central1

9. Tebrikler!

Codelab'i tamamladığınız için tebrik ederiz.

İşlediğimiz konular

  • .NET için Functions Framework.
  • HTTP Cloud Functions işlevi yazma
  • Cloud Storage etkinliklerine yanıt veren bir CloudEvent işlevi yazma
  • Cloud Pub/Sub etkinliklerine yanıt veren bir CloudEvent işlevi yazma
  • Her tür etkinliğe yanıt veren bir CloudEvent işlevi yazma