Cloud Functions'ın basitliği, kodları hızla geliştirmenizi ve sunucusuz bir ortamda çalıştırmanızı sağlar. Orta düzeyde, işlevleri çalıştırmanın maliyeti düşüktür ve kodunuzu optimize etmek yüksek bir öncelik gibi görünmeyebilir. Ancak dağıtımınız genişledikçe kodunuzu optimize etmek de giderek daha önemli hale gelir.
Bu dokümanda, işlevleriniz için ağ iletişiminin nasıl optimize edileceği açıklanmaktadır. Ağ iletişimini optimize etmenin avantajlarından bazıları şunlardır:
- Her işlev çağrısında yeni bağlantılar kurmak için harcanan CPU süresini azaltın.
- Bağlantı veya DNS kotalarının tükenmesi olasılığını azaltın.
Kalıcı Bağlantıları Koruma
Bu bölümde, bir işlevdeki kalıcı bağlantıların nasıl korunacağıyla ilgili örnekler yer almaktadır. Aksi takdirde bağlantı kotalarının hızla tükenmesine neden olabilir.
Bu bölümde aşağıdaki senaryolar ele alınmıştır:
- HTTP/S
- Google API'leri
HTTP/S İstekleri
Aşağıdaki optimize edilmiş kod snippet'i, her işlev çağrısında yeni bir bağlantı oluşturmak yerine kalıcı bağlantıların nasıl korunacağını gösterir:
Node.js
const http = require('http'); const functions = require('firebase-functions'); // Setting the `keepAlive` option to `true` keeps // connections open between function invocations const agent = new http.Agent({keepAlive: true}); exports.function = functions.https.onRequest((request, response) => { req = http.request({ host: '', port: 80, path: ' ', method: 'GET', agent: agent, // Holds the connection open after the first invocation }, res => { let rawData = ''; res.setEncoding('utf8'); res.on('data', chunk => { rawData += chunk; }); res.on('end', () => { response.status(200).send(`Data: ${rawData}`); }); }); req.on('error', e => { response.status(500).send(`Error: ${e.message}`); }); req.end(); });
Python
from firebase_functions import https_fn import requests # Create a global HTTP session (which provides connection pooling) session = requests.Session() @https_fn.on_request() def connection_pooling(request): # The URL to send the request to url = "http://example.com" # Process the request response = session.get(url) response.raise_for_status() return https_fn.Response("Success!")
Bu HTTP işlevi, HTTP isteklerinde bulunmak için bir bağlantı havuzu 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.
Google API'lerine erişme
Aşağıdaki örnekte Cloud Pub/Sub kullanılsa da bu yaklaşım Cloud Natural Language veya Cloud Spanner gibi diğer istemci kitaplıklarında da işe yarar. Performans iyileştirmelerinin, belirli istemci kitaplıklarının mevcut uygulamasına bağlı olabileceğini unutmayın.
Pub/Sub istemci nesnesi oluşturulduğunda çağrı başına bir bağlantı ve iki DNS sorgusu oluşturulur. Gereksiz bağlantıları ve DNS sorgularını önlemek için Pub/Sub istemci nesnesini aşağıdaki örnekte gösterildiği gibi global kapsamda oluşturun:
Düğüm.js
const PubSub = require('@google-cloud/pubsub'); const functions = require('firebase-functions'); const pubsub = PubSub(); exports.function = functions.https.onRequest((req, res) => { const topic = pubsub.topic(''); topic.publish('Test message', err => { if (err) { res.status(500).send(`Error publishing the message: ${err}`); } else { res.status(200).send('1 message published'); } }); });
Python
import os from firebase_functions import https_fn from google.cloud import pubsub_v1 # from firebase_functions import https_fn # Create a global Pub/Sub client to avoid unneeded network activity pubsub = pubsub_v1.PublisherClient() @https_fn.on_request() def gcp_api_call(request): project = os.getenv("GCP_PROJECT") request_json = request.get_json() topic_name = request_json["topic"] topic_path = pubsub.topic_path(project, topic_name) # Process the request data = b"Test message" pubsub.publish(topic_path, data=data) return https_fn.Response("1 message published")
Bu HTTP işlevi, işlev çağrısı başına gereken bağlantı sayısını azaltmak için önbelleğe alınmış bir istemci kitaplığı örneği 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.
GCP_PROJECT
ortam değişkeni, Python 3.7 çalışma zamanında otomatik olarak ayarlanır. Daha sonraki çalışma zamanlarında bunu işlev dağıtımında belirttiğinizden emin olun. Ortam değişkenlerini yapılandırma bölümüne bakın.
İşlevinizin Yük Testi
İşlevinizin ortalama kaç bağlantı gösterdiğini ölçmek için işlevi HTTP işlevi olarak dağıtın ve belirli QPS'de çağırmak için performans testi çerçevesi kullanın. Olası seçeneklerden biri, tek bir satırla çağırabileceğiniz Artillery'dir:
$ artillery quick -d 300 -r 30 URL
Bu komut, belirtilen URL'yi 300 saniye boyunca 30 QPS'de getirir.
Testi gerçekleştirdikten sonra bağlantı kotanızın kullanımını Cloud Console'daki Cloud Functions API kota sayfasından kontrol edin. Kullanım sürekli olarak 30 (veya birden fazla) civarındaysa her çağrıda bir (veya daha fazla) bağlantı oluşturursunuz. Kodunuzu optimize ettikten sonra, testin başında birkaç (10-30) bağlantının gerçekleştiğini görebilirsiniz.
Ayrıca aynı sayfadaki CPU kota grafiğinde optimizasyondan önceki ve sonraki CPU maliyetini karşılaştırabilirsiniz.