Mengoptimalkan jaringan

Dengan Cloud Functions yang mudah digunakan, Anda dapat mengembangkan kode dengan cepat dan menjalankannya di lingkungan serverless. Pada skala sedang, biaya untuk menjalankan fungsi masih rendah dan pengoptimalan kode tidak dianggap sebagai prioritas tinggi. Akan tetapi seiring peningkatan skala penerapan Anda, pengoptimalan kode akan semakin penting.

Dokumen ini menjelaskan cara mengoptimalkan jaringan fungsi Anda. Beberapa manfaat mengoptimalkan jaringan adalah sebagai berikut:

  • Mengurangi waktu CPU yang diperlukan untuk membuat koneksi keluar baru di setiap panggilan fungsi.
  • Mengurangi kemungkinan kehabisan kuota koneksi atau DNS.

Mempertahankan Koneksi Persisten

Bagian ini menunjukkan contoh cara mempertahankan koneksi persisten dalam suatu fungsi. Jika cara ini tidak diikuti, Anda bisa kehabisan kuota koneksi dengan cepat.

Skenario yang dibahas pada bagian ini:

  • HTTP/S
  • Google API

Permintaan HTTP/S

Cuplikan kode yang dioptimalkan di bawah ini menunjukkan cara mempertahankan koneksi yang persisten, bukan membuat koneksi baru pada setiap pemanggilan fungsi:

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!")
    

Fungsi HTTP ini menggunakan kumpulan koneksi untuk membuat permintaan HTTP. Fungsi ini mengambil objek permintaan (flask.Request) dan menampilkan teks respons, atau kumpulan nilai apa pun yang dapat diubah menjadi objek Response menggunakan make_response.

Mengakses Google API

Contoh di bawah menggunakan Cloud Pub/Sub, tetapi pendekatan ini juga dapat diterapkan untuk library klien lainnya, seperti Cloud Natural Language atau Cloud Spanner. Perhatikan bahwa peningkatan performa dapat bergantung pada library klien tertentu yang diimplementasikan saat ini.

Pembuatan objek klien Pub/Sub akan menghasilkan satu koneksi dan dua kueri DNS di setiap panggilan. Untuk menghindari koneksi dan kueri DNS yang tidak diperlukan, buat objek klien Pub/Sub dalam cakupan global, seperti yang ditunjukkan pada contoh di bawah ini:

node.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")
    

Fungsi HTTP ini menggunakan instance library klien yang di-cache untuk mengurangi jumlah koneksi yang diperlukan per pemanggilan fungsi. Fungsi ini mengambil objek permintaan (flask.Request) dan menampilkan teks respons, atau kumpulan nilai apa pun yang dapat diubah menjadi objek Response menggunakan make_response.

Variabel lingkungan GCP_PROJECT ditetapkan secara otomatis di runtime Python 3.7. Pada runtime berikutnya, pastikan untuk menentukannya pada deployment fungsi. Lihat Mengonfigurasi variabel lingkungan.

Koneksi keluar

Waktu tunggu permintaan keluar

Terdapat waktu tunggu setelah 10 menit waktu tidak ada aktivitas untuk permintaan dari fungsi Anda ke jaringan VPC. Untuk permintaan dari fungsi ke internet, diberikan waktu tunggu setelah 20 menit tidak ada aktivitas.

Koneksi keluar direset

Streaming koneksi dari fungsi Anda ke jaringan VPC dan internet terkadang dapat dihentikan dan diganti ketika infrastruktur dasar dimulai ulang atau diperbarui. Jika aplikasi Anda menggunakan kembali koneksi yang memakan waktu lama, sebaiknya konfigurasikan aplikasi Anda agar menghubungkan koneksi kembali guna menghindari penggunaan ulang koneksi yang tidak aktif.

Pengujian Muatan pada Fungsi Anda

Untuk mengukur rata-rata jumlah koneksi yang dijalankan fungsi Anda, cukup terapkan fungsi tersebut sebagai fungsi HTTP dan gunakan framework pengujian performa untuk memanggilnya di QPS tertentu. Salah satu pilihan yang dapat digunakan adalah Artillery, yang dapat Anda panggil dengan satu baris:

$ artillery quick -d 300 -r 30 URL

Perintah ini mengambil URL yang diberikan pada 30 QPS selama 300 detik.

Setelah menjalankan pengujian, periksa pemakaian kuota koneksi Anda di halaman kuota Cloud Functions API di Cloud Console. Jika pemakaian Anda sekitar 30 (atau kelipatannya) secara konsisten, berarti Anda membuat 1 (atau beberapa) koneksi di setiap pemanggilan. Setelah mengoptimalkan kode, seharusnya Anda akan melihat beberapa (10-30) koneksi saja yang terjadi di awal pengujian.

Anda juga bisa membandingkan biaya CPU sebelum dan setelah pengoptimalan plot kuota CPU di halaman yang sama.