Ağ iletişimini optimize etme

Cloud Functions basitliği sayesinde hızlıca kod geliştirebilir ve aynı sunucusuz ortama gidebilmektedir. Orta ölçekte, işlevleri çalıştırmanın maliyeti düşüktür, ve kodunuzu optimize etmek yüksek bir öncelik görünmeyebilir. Dağıtımınız olarak Ancak kodunuzu optimize etmenin önemi gittikçe artıyor.

Bu dokümanda, işlevleriniz için ağ iletişiminin nasıl optimize edileceği açıklanmaktadır. Bazı Ağ iletişimini optimize etmenin avantajları şunlardır:

  • Her birinde yeni giden bağlantılar oluştururken harcanan CPU süresini azaltın işlev çağrısında bulunmamalıdır.
  • Bağlantının bitmesi veya DNS olasılığını azaltma kotalar için geçerlidir.

Kalıcı Bağlantıları Koruma

Bu bölümde, işlevini kullanın. Bunu yapmamanız, 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, kalıcı bağlantıların nasıl korunacağını gösterir oluşturmak yerine her işlev çağrısında yeni bir bağlantı oluşturmanız gerekir:

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 istekleri oluşturmak için bir bağlantı havuzu kullanır. Bir istek nesnesini (flask.Request) alır ve şunu döndürür: veya yanıt metnine dönüştürülebilecek herhangi bir değer kümesi Response nesne kullanılıyor make_response.

Google API'lerine erişme

Aşağıdaki örnekte Cloud Pub/Sub kullanılmaktadır, ancak bu yaklaşım diğer istemci kitaplıklarında da işe yarar; örneğin, Cloud Natural Language veya Cloud Spanner. Performansın iyileştirmeleri, belirli bir müşterinin şu anki uygulamasına bağlı olarak kitaplıklar.

Pub/Sub istemci nesnesi oluşturulduğunda bir bağlantı ve iki DNS sorgusu oluşur çağrı başına gelir. Gereksiz bağlantıları ve DNS sorgularını önlemek için Aşağıdaki örnekte gösterildiği gibi global kapsamdaki Pub/Sub istemci nesnesi:

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, önbelleğe alınmış bir istemci kitaplığı örneğini kullanarak işlev çağrısı başına gereken bağlantı sayısını azaltır. Bir istek nesnesini (flask.Request) alır ve şunu döndürür: veya yanıt metnine dönüştürülebilecek herhangi bir değer kümesi Response nesne kullanılıyor make_response.

GCP_PROJECT ortam değişkeni Python'da otomatik olarak ayarlanır 3.7 çalışma zamanı. Daha sonraki çalışma zamanlarında bunu işlev dağıtımı. Görüntüleyin Ortam değişkenlerini yapılandırın.

Giden bağlantı sıfırlamaları

İşlevinizden hem VPC'ye hem de internete bağlantı akışları altyapı yeniden başlatıldığında zaman zaman sonlandırılır ve değiştirilir veya güncellenir. Uygulamanız uzun süreli bağlantıları yeniden kullanırsa yeniden bağlantı kuracak şekilde uygulamanızı yapılandırmanızı yeniden kullanımından kaçının.

İşlevinizi Yük Testi

Fonksiyonunuzun ortalama kaç bağlantı gerçekleştirdiğini ölçmek için işlevini yerine getirmek için HTTP işlevi olarak kullanabilir ve işlevi sağlayabilir. Olası seçeneklerden biri Artillery'dir. tek bir satırla çağırabilir:

$ artillery quick -d 300 -r 30 URL

Bu komut, belirtilen URL'yi 300 saniye boyunca 30 QPS'de getirir.

Testi gerçekleştirdikten sonra, Cloud Functions API kota sayfası inceleyebilirsiniz. Kullanım sürekli olarak 30 civarında (veya birden fazlaysa) her çağrıda bir (veya birkaç) bağlantı kurar. Siz birçok (10-30) bağlantının gerçekleştiğini görürsünüz. her zaman uygun olmayabilir.

Ayrıca, CPU optimizasyonundan önceki ve sonraki CPU maliyetini de kota grafiğini görebilirsiniz.