最佳化網路
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
Cloud Functions 的簡便性可讓您快速開發程式碼,並在無伺服器環境中執行。在中等規模下,執行函式的成本很低,因此最佳化程式碼可能不是優先要務。不過,隨著部署作業擴大,程式碼最佳化也變得越來越重要。
本文件說明如何針對您的函式最佳化網路。最佳化網路的部分優點如下所述:
- 減少在每次函式呼叫時建立新傳出連線所耗費的 CPU 時間。
- 降低連線或 DNS 配額用盡的可能性。
保持永久連線
本節提供如何在函式中保持永久連線的範例。如果不能永久連線,會導致快速用盡連線配額。
本節介紹下列情境:
HTTP/S 要求
以下經過最佳化的程式碼片段顯示如何保持永久連線,而不必在每次叫用函式時建立新連線:
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!")
這個 HTTP 函式會使用連線集區提出 HTTP 要求。這個函式會採用要求物件 (flask.Request
),並傳回回應文字,或可使用 make_response
轉換為 Response
物件的任何值集。
存取 Google API
以下範例使用 Cloud Pub/Sub,但這個方法也適用於其他用戶端程式庫,例如 Cloud Natural Language 或 Cloud Spanner。請注意,成效提升幅度可能取決於特定用戶端程式庫的目前實作方式。
建立 Pub/Sub 用戶端物件時,每次叫用都會產生一個連線和兩項 DNS 查詢。為避免不必要的連線和 DNS 查詢,請在全域範圍內建立 Pub/Sub 用戶端物件,如下列範例所示:
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")
這個 HTTP 函式會使用快取用戶端程式庫執行個體,減少每次函式呼叫所需的連線數量。這個函式會採用要求物件 (flask.Request
),並傳回回應文字,或可使用 make_response
轉換為 Response
物件的任何值組合。
Python 3.7 執行階段會自動設定 GCP_PROJECT
環境變數。在後續執行階段中,請務必在函式部署作業中指定此值。請參閱「設定環境變數」。
外連
傳出要求逾時
函式向虛擬私有雲網路發出要求後,如果閒置 10 分鐘,就會逾時。如果函式要求存取網際網路,閒置 20 分鐘後就會逾時。
重設外送連線
當基礎架構重新啟動或更新時,函式與 VPC 網路和網際網路之間的連線串流可能會終止並遭到取代。如果應用程式重複使用長期連線,建議您設定應用程式重新建立連線,避免重複使用已失效的連線。
對函式進行負載測試
如要評估函式平均執行的連線數,請將函式部署為 HTTP 函式,並使用效能測試架構以特定 QPS 叫用函式。其中一個可能的選擇是 Artillery,您可以使用單行叫用:
$ artillery quick -d 300 -r 30 URL
這個指令會以 30 QPS 的頻率擷取指定網址 300 秒。
執行測試後,請前往 Cloud 控制台的
API 配額頁面,查看連線配額用量。Cloud Functions如果用量持續在 30 左右 (或 30 的倍數),表示您在每次叫用時建立一或多個連線。程式碼最佳化後,您應該只會在測試開始時看到幾次 (10 到 30 次) 連線。
您也可以在同一頁面的 CPU 配額圖中比較最佳化前後的 CPU 費用。
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。
上次更新時間:2025-08-17 (世界標準時間)。
[null,null,["上次更新時間:2025-08-17 (世界標準時間)。"],[],[],null,["\u003cbr /\u003e\n\nThe simplicity of Cloud Functions lets you quickly develop code and run it in\na serverless environment. At moderate scale, the cost of running functions is\nlow, and optimizing your code might not seem like a high priority. As your\ndeployment scales up, however, optimizing your code becomes increasingly\nimportant.\n\nThis document describes how to optimize networking for your functions. Some of\nthe benefits of optimizing networking are as follows:\n\n- Reduce CPU time spent in establishing new outbound connections at each function call.\n- Reduce the likelihood of running out of connection or DNS [quotas](https://cloud.google.com/functions/quotas).\n\nMaintaining Persistent Connections\n\nThis section gives examples of how to maintain persistent connections in a\nfunction. Failure to do so can result in quickly exhausting connection quotas.\n\nThe following scenarios are covered in this section:\n\n- HTTP/S\n- Google APIs\n\nHTTP/S Requests\n\nThe optimized code snippet below shows how to maintain persistent connections\ninstead of creating a new connection upon every function invocation: \n\nNode.js \n\n```javascript\nconst http = require('http');\nconst functions = require('firebase-functions');\n\n// Setting the `keepAlive` option to `true` keeps\n// connections open between function invocations\nconst agent = new http.Agent({keepAlive: true});\n\nexports.function = functions.https.onRequest((request, response) =\u003e {\n req = http.request({\n host: '',\n port: 80,\n path: '',\n method: 'GET',\n agent: agent, // Holds the connection open after the first invocation\n }, res =\u003e {\n let rawData = '';\n res.setEncoding('utf8');\n res.on('data', chunk =\u003e { rawData += chunk; });\n res.on('end', () =\u003e {\n response.status(200).send(`Data: ${rawData}`);\n });\n });\n req.on('error', e =\u003e {\n response.status(500).send(`Error: ${e.message}`);\n });\n req.end();\n});\n```\n\nPython \n\n```python\nfrom firebase_functions import https_fn\nimport requests\n\n# Create a global HTTP session (which provides connection pooling)\nsession = requests.Session()\n\n@https_fn.on_request()\ndef connection_pooling(request):\n\n # The URL to send the request to\n url = \"http://example.com\"\n\n # Process the request\n response = session.get(url)\n response.raise_for_status()\n return https_fn.Response(\"Success!\")\n \n```\n\nThis HTTP function uses a connection pool to make HTTP requests. It takes a\nrequest object (`flask.Request`) and returns the response text, or any set\nof values that can be turned into a `Response` object using\n[`make_response`](https://flask.palletsprojects.com/en/3.0.x/api/#flask.make_response).\n\nAccessing Google APIs\n\nThe example below uses [Cloud\nPub/Sub](//cloud.google.com/pubsub/docs/reference/libraries), but this approach\nalso works for other client libraries---for example, [Cloud Natural\nLanguage](//cloud.google.com/natural-language/docs/reference/libraries) or\n[Cloud Spanner](//cloud.google.com/spanner/docs/reference/libraries). Note that\nperformance improvements may depend on the current implementation of particular\nclient libraries.\n\nCreating a Pub/Sub client object results in one connection and two DNS queries\nper invocation. To avoid unnecessary connections and DNS queries, create the\nPub/Sub client object in global scope as shown in the sample below: \n\nnode.js \n\n```javascript\nconst PubSub = require('@google-cloud/pubsub');\nconst functions = require('firebase-functions');\nconst pubsub = PubSub();\n\nexports.function = functions.https.onRequest((req, res) =\u003e {\n const topic = pubsub.topic('');\n\n topic.publish('Test message', err =\u003e {\n if (err) {\n res.status(500).send(`Error publishing the message: ${err}`);\n } else {\n res.status(200).send('1 message published');\n }\n });\n});\n```\n\nPython \n\n```python\nimport os\n\nfrom firebase_functions import https_fn\nfrom google.cloud import pubsub_v1\n\n# from firebase_functions import https_fn\n# Create a global Pub/Sub client to avoid unneeded network activity\npubsub = pubsub_v1.PublisherClient()\n\n@https_fn.on_request()\ndef gcp_api_call(request):\n\n project = os.getenv(\"GCP_PROJECT\")\n request_json = request.get_json()\n\n topic_name = request_json[\"topic\"]\n topic_path = pubsub.topic_path(project, topic_name)\n\n # Process the request\n data = b\"Test message\"\n pubsub.publish(topic_path, data=data)\n\n return https_fn.Response(\"1 message published\")\n \n```\n\nThis HTTP function uses a cached client library instance to reduce the\nnumber of connections required per function invocation. It takes a request\nobject (`flask.Request`) and returns the response text, or any set of values\nthat can be turned into a `Response` object using\n[`make_response`](https://flask.palletsprojects.com/en/3.0.x/api/#flask.make_response).\n\nThe `GCP_PROJECT` environment variable is set automatically in the Python\n3.7 runtime. In later runtimes, make sure to specify it on function\ndeployment. See [Configure environment\nvariables](https://cloud.google.com/run/docs/configuring/services/environment-variables).\n\nOutbound connections\n\nOutbound request timeouts\n\nThere is a timeout after 10 minutes of idle time for requests from your function\nto the VPC network. For requests from your function to the internet, there is a\ntimeout after 20 minutes of idle time.\n\nOutbound connection resets\n\nConnection streams from your function to both the [VPC\nnetwork](https://cloud.google.com/run/docs/configuring/connecting-vpc) and\ninternet can be occasionally terminated and replaced when underlying\ninfrastructure is restarted or updated. If your application reuses long-lived\nconnections, we recommend that you configure your application to re-establish\nconnections to avoid the reuse of a dead connection.\n\nLoad-testing Your Function\n\nTo measure how many connections your function performs on average, deploy\nit as a HTTP function and use a performance-testing framework to invoke it at\ncertain QPS. One possible choice is [Artillery](https://artillery.io/), which\nyou can invoke with a single line: \n\n```\n$ artillery quick -d 300 -r 30 URL\n```\n\nThis command fetches the given URL at 30 QPS for 300 seconds.\n\nAfter performing the test, check the usage of your connection quota on the [Cloud Functions API quota\npage](https://console.cloud.google.com/apis/api/cloudfunctions.googleapis.com/quotas) in Cloud\nConsole. If the usage is consistently around 30 (or its multiple), you are\nestablishing one (or several) connections in every invocation. After you\noptimize your code, you should see a few (10-30) connections occur only at the\nbeginning of the test.\n\nYou can also compare the CPU cost before and after the optimization on the CPU\nquota plot on the same page."]]