Tối ưu hoá kết nối mạng

Tính đơn giản của Cloud Functions giúp bạn nhanh chóng phát triển mã và chạy mã đó trong môi trường không máy chủ. Ở quy mô vừa phải, chi phí chạy các hàm thấp, và việc tối ưu hoá mã có vẻ không phải là ưu tiên cao. Là đợt triển khai của bạn mở rộng quy mô, tuy nhiên, việc tối ưu hoá mã ngày càng trở nên quan trọng.

Tài liệu này mô tả cách tối ưu hoá kết nối mạng cho các hàm của bạn. Một số lợi ích của việc tối ưu hoá mạng như sau:

  • Giảm thời gian của CPU để thiết lập các kết nối đi mới ở mỗi lệnh gọi hàm.
  • Giảm khả năng hết kết nối hoặc hết DNS hạn mức.

Duy trì sự kết nối bền vững

Phần này đưa ra ví dụ về cách duy trì kết nối bền vững trong . Nếu không, chúng tôi có thể nhanh chóng hết hạn mức kết nối.

Các trường hợp sau được đề cập trong phần này:

  • HTTP/S
  • Google API

Yêu cầu HTTP/S

Đoạn mã được tối ưu hoá dưới đây cho biết cách duy trì các kết nối liên tục thay vì tạo kết nối mới dựa trên mỗi lệnh gọi hàm:

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

Hàm HTTP này sử dụng nhóm kết nối để thực hiện các yêu cầu HTTP. Phương thức này nhận một đối tượng yêu cầu (flask.Request) rồi trả về nội dung phản hồi hoặc bất kỳ tập hợp giá trị nào có thể chuyển thành Đối tượng Response đang sử dụng make_response.

Truy cập API của Google

Ví dụ bên dưới sử dụng Cloud Pub/Sub, nhưng phương pháp này cũng hiệu quả với các thư viện ứng dụng khác—ví dụ: Ngôn ngữ tự nhiên của Cloud hoặc Cloud Spanner. Lưu ý rằng hiệu suất những điểm cải tiến có thể tuỳ thuộc vào việc triển khai hiện tại của ứng dụng cụ thể thư viện.

Việc tạo đối tượng máy khách Pub/Sub sẽ dẫn đến 1 kết nối và 2 truy vấn DNS cho mỗi lần gọi. Để tránh các kết nối và truy vấn DNS không cần thiết, hãy tạo Đối tượng ứng dụng Pub/Sub trong phạm vi toàn cầu như trong mẫu bên dưới:

nút.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")
    

Hàm HTTP này sử dụng phiên bản thư viện ứng dụng được lưu vào bộ nhớ đệm để giảm số lượng kết nối cần thiết cho mỗi lệnh gọi hàm. Phương thức này nhận một đối tượng yêu cầu (flask.Request) rồi trả về nội dung phản hồi hoặc bất kỳ tập hợp giá trị nào có thể chuyển thành Đối tượng Response đang sử dụng make_response.

Biến môi trường GCP_PROJECT được đặt tự động trong Python Thời gian chạy 3.7. Trong thời gian chạy sau này, hãy nhớ chỉ định chế độ này trên triển khai hàm. Xem Định cấu hình các biến môi trường.

Kiểm thử tải hàm của bạn

Để đo lường số lượng kết nối trung bình mà chức năng của bạn thực hiện, chỉ cần triển khai nó dưới dạng một hàm HTTP và sử dụng khung kiểm thử hiệu suất để gọi hàm đó tại QPS nhất định. Bạn có thể chọn Pháo có thể gọi bằng một dòng đơn:

$ artillery quick -d 300 -r 30 URL

Lệnh này tìm nạp URL đã cho với tốc độ 30 QPS trong 300 giây.

Sau khi kiểm tra, hãy kiểm tra việc sử dụng hạn mức kết nối trên Trang hạn mức API Cloud Functions trong Cloud Console. Nếu mức sử dụng nhất quán trong khoảng 30 (hoặc bội số), bạn đang thiết lập một (hoặc nhiều) kết nối trong mỗi lệnh gọi. Sau khi tối ưu hoá mã của mình, bạn sẽ thấy một vài (10-30) kết nối xuất hiện chỉ ở đầu thử nghiệm.

Bạn cũng có thể so sánh chi phí CPU trước và sau khi tối ưu hoá cho CPU biểu đồ hạn mức trên cùng một trang.