İpuçları ve püf noktaları

Bu belgede Cloud Functions tasarımı, uygulanması, test edilmesi ve dağıtımıyla ilgili en iyi uygulamalar açıklanmaktadır.

Doğruluk

Bu bölümde, Cloud Functions tasarımı ve uygulanmasıyla ilgili genel en iyi uygulamalar açıklanmaktadır.

Tekil fonksiyonlar yazma

İşlevleriniz, birden fazla kez çağrılsa bile aynı sonucu üretmelidir. Bu sayede, önceki çağrı kodunuzun ortasında başarısız olursa çağrıyı yeniden deneyebilirsiniz. Daha fazla bilgi için etkinlik odaklı işlevleri yeniden deneme konusuna bakın.

Arka plan etkinlikleri başlatma

Arka plan etkinliği, işleviniz sona erdikten sonra gerçekleşen her şeydir. Bir işlev çağrısı, işlev döndürdüğünde veya başka bir şekilde tamamlandığını belirttiğinde (ör. Node.js etkinlik odaklı işlevlerinde callback bağımsız değişkeni çağrılarak) sona erer. Sorunsuz sonlandırmadan sonra çalıştırılan kodlar CPU'ya erişemez ve herhangi bir ilerleme kaydedemez.

Ayrıca, aynı ortamda sonraki bir çağrı yürütüldüğünde arka plan etkinliğiniz devam ederek yeni çağrıyı engeller. Bu durum, beklenmedik davranışlara ve teşhis edilmesi zor hatalara yol açabilir. Bir işlev sona erdikten sonra ağa erişmek genellikle bağlantıların sıfırlanmasına neden olur (ECONNRESET hata kodu).

Arka plan etkinliği, genellikle bağımsız çağrılardan gelen günlüklerde, çağrının sona erdiğini belirten satırdan sonra günlüğe kaydedilen her şey bulunarak tespit edilebilir. Arka plan etkinliği bazen kodun daha derinlerine gömülebilir. Özellikle de geri çağırma veya zamanlayıcı gibi eşzamansız işlemler söz konusu olduğunda bu işlemler yararlı olur. İşlevi sonlandırmadan önce tüm zaman uyumsuz işlemlerin tamamlandığından emin olmak için kodunuzu inceleyin.

Geçici dosyaları her zaman sil

Geçici dizindeki yerel disk depolama alanı, bellek içi bir dosya sistemidir. Yazdığınız dosyalar, işleviniz için kullanılabilir olan belleği kullanır ve bazen çağrılar arasında devam eder. Bu dosyaları açıkça silmemek, zaman içinde bellek yetersizliği hatasına ve ardından soğuk başlatmaya neden olabilir.

Tek bir işlev tarafından kullanılan belleği, Google Cloud Console'daki işlev listesinde ve Bellek kullanımı grafiğinde seçerek görebilirsiniz.

Geçici dizinin dışına yazmaya çalışmayın ve dosya yolları oluşturmak için platformdan/işletim sisteminden bağımsız yöntemler kullandığınızdan emin olun.

Ardışık düzen kullanarak daha büyük dosyaları işlerken bellek gereksinimlerini azaltabilirsiniz. Örneğin, bir okuma akışı oluşturarak, bu akışı akış tabanlı bir işleme geçirerek ve çıkış akışını doğrudan Cloud Storage'a yazarak Cloud Storage'da bir dosyayı işleyebilirsiniz.

Functions Framework

Bir işlevi dağıttığınızda Functions Framework, mevcut sürümü kullanılarak otomatik olarak bağımlılık olarak eklenir. Aynı bağımlıların farklı ortamlarda tutarlı bir şekilde yüklenmesini sağlamak için işlevinizi Functions Framework'in belirli bir sürümüne sabitlemenizi öneririz.

Bunu yapmak için tercih ettiğiniz sürümü ilgili kilit dosyasına ekleyin (örneğin, Node.js için package-lock.json veya Python için requirements.txt).

Araçlar

Bu bölümde, Cloud Functions'ü uygulamak, test etmek ve bu araçla etkileşime geçmek için araçları nasıl kullanacağınızla ilgili yönergeler verilmiştir.

Yerel geliştirme

İşlev dağıtımı biraz zaman aldığından işlevinizin kodunu yerel olarak test etmek genellikle daha hızlıdır.

Firebase geliştiricileri Firebase CLI Cloud Functions Emülatörü kullanabilir.

E-posta göndermek için SendGrid'i kullanma

Cloud Functions, bağlantı noktası 25 üzerinde giden bağlantılara izin vermediğinden bir SMTP sunucusuyla güvenli olmayan bağlantılar oluşturamazsınız. E-posta göndermek için SendGrid'i kullanmanız önerilir. E-posta göndermeyle ilgili diğer seçenekleri Google Compute Engine'e yönelik Bir Birimden E-posta Gönderme eğitiminde bulabilirsiniz.

Performans

Bu bölümde, performansı optimize etmeye yönelik en iyi uygulamalar açıklanmaktadır.

Bağımlılıkları akıllıca kullanın

İşlevler durum bilgisi içermediğinden yürütme ortamı genellikle sıfırdan başlatılır (soğuk başlatma olarak bilinen işlem sırasında). Sıfırdan başlatma işlemi gerçekleştiğinde işlevin genel bağlamı değerlendirilir.

İşlevleriniz modül içe aktarıyorsa bu modüllerin yükleme süresi, sıfırdan başlatma sırasındaki çağrı gecikmesine eklenebilir. Bağımlılıkları doğru şekilde yükleyerek ve işlevinizin kullanmadığı bağımlılıkları yüklemeyerek bu gecikmeyi ve işlevinizi dağıtmak için gereken süreyi azaltabilirsiniz.

Nesneleri gelecekteki çağrılarda yeniden kullanmak için genel değişkenleri kullanma

Bir işlevin durumunun gelecekteki çağrılar için korunacağı garanti edilmez. Ancak Cloud Functions genellikle önceki bir çağrının yürütme ortamını geri dönüştürür. Genel kapsamlı bir değişken tanımlarsanız bu değişkenin değeri, yeniden hesaplamaya gerek kalmadan sonraki çağrılarda yeniden kullanılabilir.

Bu sayede, her işlev çağrısında yeniden oluşturulması pahalı olabilecek nesneleri önbelleğe alabilirsiniz. Bu tür nesneleri işlev gövdesinden genel kapsama taşımak önemli performans iyileştirmelerine neden olabilir. Aşağıdaki örnek, işlev örneği başına yalnızca bir kez ağır nesne oluşturur ve bunu belirtilen örneğe ulaşan tüm işlev çağrılarında paylaşır:

Node.js

console.log('Global scope');
const perInstance = heavyComputation();
const functions = require('firebase-functions');

exports.function = functions.https.onRequest((req, res) => {
  console.log('Function invocation');
  const perFunction = lightweightComputation();

  res.send(`Per instance: ${perInstance}, per function: ${perFunction}`);
});

Python

import time

from firebase_functions import https_fn

# Placeholder
def heavy_computation():
  return time.time()

# Placeholder
def light_computation():
  return time.time()

# Global (instance-wide) scope
# This computation runs at instance cold-start
instance_var = heavy_computation()

@https_fn.on_request()
def scope_demo(request):

  # Per-function scope
  # This computation runs every time this function is called
  function_var = light_computation()
  return https_fn.Response(f"Instance: {instance_var}; function: {function_var}")
  

Bu HTTP işlevi, bir istek nesnesini (flask.Request) alır ve yanıt metnini veya make_response kullanarak Response nesnesine dönüştürülebilecek herhangi bir değer grubunu döndürür.

Ağ bağlantılarını, kitaplık referanslarını ve API istemci nesnelerini genel kapsamda önbelleğe almak özellikle önemlidir. Örnekler için Ağ bağlantısını optimize etme başlıklı makaleyi inceleyin.

Genel değişkenleri yavaş başlatma

Değişkenleri global kapsamda başlatırsanız başlatma kodu her zaman soğuk başlatma çağrısı aracılığıyla yürütülür ve işlevinizin gecikmesi artar. Bazı durumlarda, try/catch bloğunda uygun şekilde işlenmezse çağrılan hizmetlerde aralıklı zaman aşımına neden olur. Bazı nesneler tüm kod yollarında kullanılmıyorsa bunları isteğe bağlı olarak yavaşça başlatmayı düşünebilirsiniz:

Node.js

const functions = require('firebase-functions');
let myCostlyVariable;

exports.function = functions.https.onRequest((req, res) => {
  doUsualWork();
  if(unlikelyCondition()){
      myCostlyVariable = myCostlyVariable || buildCostlyVariable();
  }
  res.status(200).send('OK');
});

Python

from firebase_functions import https_fn

# Always initialized (at cold-start)
non_lazy_global = file_wide_computation()

# Declared at cold-start, but only initialized if/when the function executes
lazy_global = None

@https_fn.on_request()
def lazy_globals(request):

  global lazy_global, non_lazy_global

  # This value is initialized only if (and when) the function is called
  if not lazy_global:
      lazy_global = function_specific_computation()

  return https_fn.Response(f"Lazy: {lazy_global}, non-lazy: {non_lazy_global}.")
  

Bu HTTP işlevi, tembel başlatılmış genel değişkenler kullanır. Bir istek nesnesi (flask.Request) alır ve yanıt metnini veya make_response kullanılarak Response nesnesine dönüştürülebilecek herhangi bir değer grubunu döndürür.

Bu, özellikle tek bir dosyada birden fazla işlev tanımlarsanız ve farklı işlevler farklı değişkenler kullanıyorsa önemlidir. Tembel başlatma özelliğini kullanmazsanız, başlatılan ancak hiç kullanılmayan değişkenler için kaynak israf edebilirsiniz.

Minimum örnek sayısı belirleyerek baştan başlatma işlemlerini azaltma

Varsayılan olarak Cloud Functions, örnek sayısını gelen isteklerin sayısına göre ölçeklendirir. Cloud Functions'ün istek sunmak için hazır tutması gereken minimum örnek sayısını ayarlayarak bu varsayılan davranışı değiştirebilirsiniz. Minimum sayıda örnek belirlemek, uygulamanızın baştan başlatılmasını azaltır. Uygulamanız gecikmeye duyarlıysa minimum sayıda örnek belirlemenizi öneririz.

Bu çalışma zamanı seçenekleri hakkında daha fazla bilgi için Ölçeklendirme davranışını kontrol etme başlıklı makaleyi inceleyin.

Ek kaynaklar

Performansı optimize etme hakkında daha fazla bilgi edinmek için "Google Cloud Performance Atlas" videosundaki Cloud Functions Soğuk Başlatma Süresi bölümünü inceleyin.