Sự đơn giản của Cloud Functions cho phép bạn nhanh chóng phát triển mã và chạy mã đó trong một môi trường phi máy chủ. Ở quy mô vừa phải, chi phí chạy các hàm là thấp và việc tối ưu hoá mã có thể không phải là ưu tiên hàng đầu. Tuy nhiên, khi quá trình triển khai của bạn tăng lên, việc tối ưu hoá mã sẽ trở nên ngày càng quan trọng.
Tài liệu này mô tả cách tối ưu hoá mạng cho các hàm. Dưới đây là một số lợi ích của việc tối ưu hoá mạng:
- Giảm thời gian CPU dành cho việc 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 hạn mức kết nối hoặc hạn mức DNS hạn mức.
Duy trì kết nối liên tục
Phần này đưa ra ví dụ về cách duy trì kết nối liên tục trong một hàm. Nếu không làm như vậy, bạn có thể nhanh chóng hết hạn mức kết nối.
Phần này đề cập đến các trường hợp sau:
- HTTP/S
- Google API
Yêu cầu HTTP/S
Đoạn mã được tối ưu hoá bên dưới cho biết cách duy trì kết nối liên tục thay vì tạo một kết nối mới khi mỗi hàm được gọi:
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 một nhóm kết nối để đưa ra các yêu cầu HTTP. Hàm này nhận một
đối tượng yêu cầu (flask.Request) và trả về văn bản phản hồi hoặc bất kỳ tập hợp
giá trị nào có thể được chuyển thành đối tượng Response bằng
make_response.
Truy cập vào các 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 hoạt động đối với các thư viện ứng dụng khác, chẳng hạn như Cloud Natural Language hoặc Cloud Spanner. Xin lưu ý rằng việc cải thiện hiệu suất có thể phụ thuộc vào cách triển khai hiện tại của các thư viện ứng dụng cụ thể.
Việc tạo đối tượng ứng dụng Pub/Sub sẽ dẫn đến một kết nối và hai 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ục như trong mẫu bên dưới:
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")
Hàm HTTP này sử dụng một thực thể 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ần gọi hàm. Hàm này nhận một đối tượng yêu cầu (flask.Request) và trả về văn bản phản hồi hoặc bất kỳ tập hợp giá trị nào
có thể được chuyển thành một Response đối tượng bằng
make_response.
Biến môi trường GCP_PROJECT được tự động đặt trong thời gian chạy Python 3.7. Trong các thời gian chạy sau này, hãy nhớ chỉ định biến này khi triển khai hàm. Xem phần Định cấu hình biến môi trường.
Kết nối đi
Thời gian chờ yêu cầu đi
Có một thời gian chờ sau 10 phút thời gian rảnh cho các yêu cầu từ hàm của bạn đến mạng VPC. Đối với các yêu cầu từ hàm của bạn đến Internet, có một thời gian chờ sau 20 phút thời gian rảnh.
Đặt lại kết nối đi
Các luồng kết nối từ hàm của bạn đến cả mạng VPC và Internet có thể bị chấm dứt và thay thế theo định kỳ khi cơ sở hạ tầng cơ bản được khởi động lại hoặc cập nhật. Nếu ứng dụng của bạn sử dụng lại các kết nối tồn tại lâu dài, bạn nên định cấu hình ứng dụng để thiết lập lại các kết nối nhằm tránh việc sử dụng lại một kết nối đã chết.
Kiểm thử tải hàm
Để đo lường số lượng kết nối mà hàm của bạn thực hiện trung bình, hãy triển khai hàm đó dưới dạng hàm HTTP và sử dụng một khung kiểm thử hiệu suất để gọi hàm đó ở một số QPS nhất định. Một lựa chọn có thể là Artillery, mà bạn có thể gọi bằng một dòng duy nhất:
$ artillery quick -d 300 -r 30 URL
Lệnh này tìm nạp URL đã cho ở 30 QPS trong 300 giây.
Sau khi thực hiện kiểm thử, hãy kiểm tra mức sử dụng hạn mức kết nối của bạn trên trang hạn mức API Cloud Functions trong Cloud Console. Nếu mức sử dụng luôn ở mức khoảng 30 (hoặc bội số của mức sử dụng), thì bạn đang thiết lập một (hoặc một số) kết nối trong mỗi lần gọi. Sau khi tối ưu hoá mã, bạn chỉ nên thấy một vài (10-30) kết nối xảy ra ở đầu bài kiểm thử.
Bạn cũng có thể so sánh chi phí CPU trước và sau khi tối ưu hoá trên biểu đồ hạn mức CPU trên cùng một trang.