İpuçları ve püf noktaları

Bu belgede Cloud Functions'ı tasarlama, uygulama, test etme ve dağıtmayla ilgili en iyi uygulamalar açıklanmaktadır.

Doğruluk

Bu bölümde, Cloud Functions'ı tasarlama ve uygulamayla ilgili genel en iyi uygulamalar açıklanmaktadır.

Değişken fonksiyonları yazma

Fonksiyonlarınız birden çok kez çağrılsa bile aynı sonucu vermelidir. Bu sayede, önceki çağrı kodunuzda başarısız olursa bir çağrıyı yeniden deneyebilirsiniz. Daha fazla bilgi için etkinlik odaklı işlevleri yeniden deneme bölümüne bakın.

Arka plan etkinliklerini başlatma

Arka plan etkinliği, işleviniz sonlandırıldıktan sonra gerçekleşen her şeydir. Node.js etkinliğe dayalı işlevlerde callback bağımsız değişkenini çağırmak gibi, işlev geri döndüğünde veya başka bir şekilde tamamlandığına dair sinyal gönderildikten sonra işlev çağrısı tamamlanır. Kontrollü sonlandırmadan sonra çalıştırılan hiçbir kod CPU'ya erişemez ve herhangi bir ilerleme yapamaz.

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

Arka plan etkinliği, genellikle çağrının tamamlandığını belirten satırdan sonra günlüğe kaydedilen herhangi bir şey bularak tek tek çağrılara ait günlüklerde tespit edilebilir. Özellikle geri çağırma veya zamanlayıcı gibi eşzamansız işlemler mevcut olduğunda, arka plan etkinliği bazen kodun daha derinlerine gömülebilir. İşlevi sonlandırmadan önce tüm eşzamansız işlemlerin tamamlandığından emin olmak için kodunuzu inceleyin.

Geçici dosyaları her zaman sil

Geçici dizindeki yerel disk depolaması, bellek içi bir dosya sistemidir. Yazdığınız dosyalar, işleviniz için kullanılabilir olan belleği tüketir ve bazen çağrılar arasında devam eder. Bu dosyaların açıkça silinememesi, nihayetinde bellek yetersiz hatasına ve müteakip baştan başlatmaya neden olabilir.

Belirli bir işlevin kullandığı belleği, GCP Console'daki işlev listesinden seçip Bellek kullanımı grafiğini seçerek görebilirsiniz.

Geçici dizinin dışına yazmaya çalışmayın ve dosya yolları oluşturmak için platform/OS'tan 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şturup bunu akış tabanlı bir işlemden geçirerek ve çıkış akışını doğrudan Cloud Storage'a yazarak Cloud Storage'daki bir dosyayı işleyebilirsiniz.

Functions Framework

Bir işlevi dağıttığınızda Functions Çerçevesi, geçerli sürümü kullanılarak otomatik şekilde bağımlılık şeklinde eklenir. Aynı bağımlılıkların farklı ortamlarda tutarlı bir şekilde yüklendiğinden emin olmak için işlevinizi Functions Framework'ün 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 bunlarla etkileşimde bulunmak için araçların nasıl kullanılacağı ile ilgili yönergeler yer almaktadır.

Yerel geliştirme

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

Firebase geliştiricileri Firebase CLI Cloud Functions Emulator'ı kullanabilir.

E-posta göndermek için Sendgrid'i kullanın

Cloud Functions, 25 numaralı bağlantı noktasında giden bağlantılara izin vermez. Bu nedenle, bir SMTP sunucusuyla güvenli olmayan bağlantılar yapamazsınız. E-posta göndermek için önerilen yol SendGrid'i kullanmaktır. E-posta göndermeye ilişkin diğer seçenekleri Google Compute Engine için Örnekten E-posta Gönderme eğiticisinde 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 bilgisiz olduğundan, yürütme ortamı genellikle sıfırdan başlatılır (baştan başlatma olarak bilinen işlem sırasında). Baştan başlatma gerçekleştiğinde, işlevin küresel bağlamı değerlendirilir.

İşlevleriniz modülleri içe aktarıyorsa bu modüllerin yükleme süresi, baştan başlatma sırasında çağrı gecikmesine neden olabilir. 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.

Gelecekteki çağrılarda nesneleri yeniden kullanmak için genel değişkenler kullan

Cloud Functions işlevinin durumunun gelecekteki çağrılarda korunacağına dair bir garanti yoktur. Ancak Cloud Functions genellikle önceki bir çağrının yürütme ortamını geri dönüştürür. Genel kapsamda bir değişken bildirirseniz değişkenin değeri, sonraki çağrılarda yeniden hesaplanmaya gerek kalmadan yeniden kullanılabilir.

Bu şekilde, her işlev çağrısında yeniden oluşturulması maliyetli olabilecek nesneleri önbelleğe alabilirsiniz. Bu tür nesneleri işlev gövdesinden küresel kapsama taşımak performansta önemli iyileşmeler sağlayabilir. Aşağıdaki örnek, ağır bir nesneyi işlev örneği başına yalnızca bir kez oluşturur ve bu nesneyi belirli bir ö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 kullanılarak Response nesnesine dönüştürülebilen değer gruplarını döndürür.

Ağ bağlantılarını, kitaplık referanslarını ve API istemci nesnelerini global kapsamda önbelleğe almak özellikle önemlidir. Örnekler için Ağ İletişimini Optimize Etme bölümüne bakın.

Genel değişkenlerin geç başlatılmasını sağlama

Değişkenleri genel kapsamda başlatırsanız başlatma kodu her zaman bir soğuk başlatma çağrısı aracılığıyla yürütülür ve bu nedenle işlevinizin gecikmesini artırır. Bu durum, bazı durumlarda bir try/catch bloğunda uygun şekilde ele alınmadıkları takdirde çağrılan hizmetlerde aralıklı olarak zaman aşımlarına neden olur. Bazı nesneler tüm kod yollarında kullanılmıyorsa bunları isteğe bağlı olarak geç başlatın:

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, geç başlatılan genel değerleri kullanır. Bir istek nesnesini (flask.Request) alır ve yanıt metnini veya make_response kullanılarak Response nesnesine dönüştürülebilen değer gruplarını döndürür.

Bu, özellikle tek bir dosyada birkaç işlev tanımlarsanız ve farklı işlevler farklı değişkenler kullanıyorsa önemlidir. Geç başlatma kullanmadığınız sürece, başlatılmış ancak hiç kullanılmayan değişkenler için kaynakları boşa harcayabilirsiniz.

Minimum örnek sayısını ayarlayarak baştan başlatma sayısını azaltın

Varsayılan olarak Cloud Functions, örnek sayısını gelen isteklerin sayısına göre ölçeklendirir. Cloud Functions'ın istekleri sunmaya hazır hale getirmesi gereken minimum örnek sayısını ayarlayarak bu varsayılan davranışı değiştirebilirsiniz. Minimum örnek sayısını ayarlamak, uygulamanızın baştan başlatma sayısını azaltır. Uygulamanız gecikmeye duyarlıysa minimum örnek sayısı ayarlamanızı öneririz.

Bu çalışma zamanı seçenekleri hakkında daha fazla bilgi için Ölçeklendirme davranışını kontrol etme bölümüne bakın.

Ek kaynaklar

Cloud Functions Cold Boot Time adlı "Google Cloud Performance Atlas" videosunda performansı optimize etme hakkında daha fazla bilgi edinin.