Quản lý chức năng


Bạn có thể triển khai, xoá và sửa đổi các hàm bằng các lệnh CLI Firebase hoặc bằng cách đặt các tuỳ chọn thời gian chạy trong mã nguồn hàm.

Triển khai hàm

Để triển khai các hàm, hãy chạy lệnh CLI Firebase sau:

firebase deploy --only functions

Theo mặc định, CLI Firebase sẽ triển khai tất cả các hàm bên trong nguồn cùng một lúc. Nếu dự án của bạn chứa nhiều hơn 5 hàm, bạn nên sử dụng cờ --only với tên hàm cụ thể để chỉ triển khai các hàm mà bạn đã chỉnh sửa. Việc triển khai các hàm cụ thể theo cách này sẽ đẩy nhanh quá trình triển khai và giúp bạn tránh gặp phải hạn mức triển khai. Ví dụ:

firebase deploy --only functions:addMessage,functions:makeUppercase

Khi triển khai nhiều hàm, bạn có thể vượt quá hạn mức tiêu chuẩn và nhận được thông báo lỗi HTTP 429 hoặc 500. Để giải quyết để triển khai các hàm theo nhóm tối đa 10 người.

Xem tài liệu tham khảo về CLI Firebase để biết danh sách đầy đủ các công cụ hiện có .

Theo mặc định, CLI Firebase sẽ tìm mã nguồn trong thư mục functions/. Nếu muốn, bạn có thể sắp xếp các hàm trong cơ sở mã hoặc nhiều tập hợp tệp.

Xoá hàm

Bạn có thể xoá các hàm đã triển khai trước đó theo những cách sau:

  • một cách rõ ràng trong CLI Firebase với functions:delete
  • rõ ràng trong bảng điều khiển Google Cloud.
  • ngầm ẩn bằng cách xoá hàm khỏi nguồn trước khi triển khai.

Tất cả thao tác xoá sẽ nhắc bạn xác nhận trước khi xoá hàm khỏi môi trường phát hành chính thức.

Thao tác xoá hàm tường minh trong CLI Firebase hỗ trợ nhiều đối số cũng như các nhóm hàm và cho phép bạn chỉ định một hàm chạy trong một khu vực cụ thể. Ngoài ra, bạn có thể ghi đè lời nhắc xác nhận.

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --force

Khi xoá hàm ngầm ẩn, firebase deploy sẽ phân tích cú pháp nguồn của bạn và xoá khỏi phiên bản chính thức mọi hàm đã bị xoá khỏi tệp.

Sửa đổi tên, khu vực hoặc điều kiện kích hoạt của hàm

Nếu bạn đang đổi tên hoặc thay đổi các khu vực hoặc điều kiện kích hoạt cho các hàm đang xử lý lưu lượng truy cập công khai, hãy làm theo các bước trong phần này để tránh mất sự kiện trong quá trình sửa đổi. Trước khi làm theo các bước này, trước tiên, hãy đảm bảo rằng hàm của bạn là không đổi, vì cả phiên bản mới và phiên bản cũ của hàm sẽ chạy cùng một lúc trong quá trình thay đổi.

Đổi tên hàm

Để đổi tên một hàm, hãy tạo một phiên bản mới được đổi tên của hàm đó trong nguồn rồi chạy hai lệnh triển khai riêng biệt. Lệnh đầu tiên triển khai hàm mới được đặt tên và lệnh thứ hai xoá các lệnh đã triển khai trước đó . Ví dụ: nếu bạn có một hàm Node.js tên là webhook mà bạn muốn thay đổi thành webhookNew, hãy sửa đổi mã như sau:

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

// after
const functions = require('firebase-functions/v1');

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

Sau đó, hãy chạy các lệnh sau để triển khai hàm mới:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

Thay đổi khu vực hoặc khu vực của hàm

Nếu bạn thay đổi khu vực đã chỉ định cho một xử lý lưu lượng truy cập thực tế, bạn có thể ngăn chặn tình trạng mất sự kiện bằng cách thực hiện các bước sau theo thứ tự:

  1. Đổi tên hàm rồi thay đổi vùng hoặc các vùng của hàm theo ý muốn.
  2. Triển khai hàm đã đổi tên, nhờ đó tạm thời chạy cùng một mã trong cả hai nhóm vùng.
  3. Xoá hàm trước đó.

Ví dụ: nếu bạn có một hàm tên là webhook hiện đang nằm trong vùng hàm mặc định của us-central1 và bạn muốn di chuyển hàm đó sang asia-northeast1, trước tiên, bạn cần sửa đổi mã nguồn để đổi tên hàm và sửa đổi vùng.

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

// after
const functions = require('firebase-functions/v1');

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

Sau đó, hãy triển khai bằng cách chạy:

firebase deploy --only functions:webhookAsia

Hiện có 2 hàm giống hệt nhau đang chạy: webhook đang chạy trong us-central1, và webhookAsia đang chạy ở asia-northeast1.

Sau đó, xoá webhook:

firebase functions:delete webhook

Hiện chỉ có một hàm là webhookAsia, đang chạy trong asia-northeast1.

Thay đổi loại trình kích hoạt của hàm

Khi phát triển quá trình triển khai Cloud Functions for Firebase theo thời gian, bạn có thể cần thay đổi loại trình kích hoạt của một hàm vì nhiều lý do. Ví dụ: bạn có thể muốn thay đổi từ một loại sự kiện Firebase Realtime Database hoặc Cloud Firestore sang một loại khác.

Bạn không thể thay đổi loại sự kiện của một hàm chỉ bằng cách thay đổi mã nguồn và chạy firebase deploy. Để tránh lỗi, thay đổi loại điều kiện kích hoạt của hàm theo quy trình sau:

  1. Sửa đổi mã nguồn để bao gồm một hàm mới có loại điều kiện kích hoạt mong muốn.
  2. Triển khai hàm, kết quả là sẽ tạm thời chạy cả hàm cũ và hàm mới.
  3. Xoá rõ ràng hàm cũ khỏi phiên bản chính thức bằng cách sử dụng CLI Firebase.

Ví dụ: nếu bạn có một hàm Node.js có tên là objectChanged có loại sự kiện onChange cũ và bạn muốn thay đổi loại sự kiện này thành onFinalize, trước tiên, hãy đổi tên hàm và chỉnh sửa hàm đó để có loại sự kiện onFinalize.

// before
const functions = require('firebase-functions/v1');

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

// after
const functions = require('firebase-functions/v1');

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

Sau đó, hãy chạy các lệnh sau để tạo hàm mới trước khi xoá hàm cũ:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

Đặt tuỳ chọn thời gian chạy

Cloud Functions for Firebase cho phép bạn chọn các tuỳ chọn thời gian chạy, chẳng hạn như phiên bản thời gian chạy Node.js và thời gian chờ cho mỗi hàm, mức phân bổ bộ nhớ và các thực thể hàm tối thiểu/tối đa.

Tốt nhất là bạn nên đặt các tuỳ chọn này (ngoại trừ phiên bản Node.js) trên đối tượng cấu hình bên trong mã hàm. Đối tượng RuntimeOptions này là nguồn đáng tin cậy cho các tuỳ chọn thời gian chạy của hàm và sẽ ghi đè các tuỳ chọn được đặt thông qua bất kỳ phương thức nào khác (chẳng hạn như thông qua bảng điều khiển Google Cloud hoặc gcloud CLI).

Nếu quy trình phát triển của bạn liên quan đến việc đặt các tuỳ chọn thời gian chạy theo cách thủ công thông qua Google Cloud Console hoặc gcloud CLI và bạn không muốn các giá trị này bị ghi đè trên mỗi lần triển khai, hãy đặt tuỳ chọn preserveExternalChanges thành true. Khi bạn đặt tuỳ chọn này thành true, Firebase sẽ hợp nhất các tuỳ chọn thời gian chạy được đặt trong cùng với các chế độ cài đặt của phiên bản hàm đang được triển khai bằng mức độ ưu tiên sau:

  1. Tuỳ chọn được đặt trong mã hàm: ghi đè các thay đổi bên ngoài.
  2. Tuỳ chọn được đặt thành RESET_VALUE trong mã hàm: ghi đè các thay đổi bên ngoài bằng giá trị mặc định.
  3. Tuỳ chọn không được đặt trong mã hàm, nhưng được đặt trong hàm hiện đang được triển khai: sử dụng tuỳ chọn được chỉ định trong hàm được triển khai.

Không nên sử dụng tuỳ chọn preserveExternalChanges: true trong hầu hết các trường hợp vì mã sẽ không còn là nguồn đáng tin cậy cho các tuỳ chọn thời gian chạy cho . Nếu bạn sử dụng, hãy kiểm tra bảng điều khiển Google Cloud hoặc sử dụng gcloud CLI để xem cấu hình đầy đủ của một hàm.

Đặt phiên bản Node.js

SDK Firebase cho Cloud Functions cho phép chọn thời gian chạy Node.js. Bạn có thể chọn chạy tất cả hàm trong một dự án chỉ trên môi trường thời gian chạy tương ứng với một trong các phiên bản Node.js được hỗ trợ sau:

  • Node.js 20 (bản xem trước)
  • Node.js 18
  • Node.js 16
  • Node.js 14

Cách đặt phiên bản Node.js:

Bạn có thể đặt phiên bản trong trường engines trong tệp package.json được tạo trong thư mục functions/ trong quá trình khởi chạy. Ví dụ: để chỉ sử dụng phiên bản 18, hãy chỉnh sửa dòng này trong package.json:

  "engines": {"node": "18"}

Nếu đang sử dụng trình quản lý gói Yarn hoặc có các yêu cầu cụ thể khác đối với trường engines, bạn có thể đặt thời gian chạy cho SDK Firebase cho Cloud Functions trong firebase.json:

  {
    "functions": {
      "runtime": "nodejs18" // or nodejs14, nodejs16 or nodejs20
    }
  }

CLI sử dụng giá trị được đặt trong firebase.json thay vì bất kỳ giá trị hoặc phạm vi nào mà bạn đặt riêng trong package.json.

Nâng cấp môi trường thời gian chạy Node.js

Cách nâng cấp môi trường thời gian chạy Node.js:

  1. Đảm bảo dự án của bạn đang sử dụng gói giá Blaze.
  2. Hãy đảm bảo rằng bạn đang sử dụng Firebase CLI phiên bản 11.18.0 trở lên.
  3. Thay đổi giá trị engines trong tệp package.json đã được tạo trong thư mục functions/ của bạn trong quá trình khởi tạo. Ví dụ: nếu bạn đang nâng cấp từ phiên bản 16 lên phiên bản 18, mục nhập sẽ có dạng như sau: "engines": {"node": "18"}
  4. Nếu muốn, hãy kiểm tra các thay đổi của bạn bằng cách sử dụng Firebase Local Emulator Suite.
  5. Triển khai lại tất cả các chức năng.

Kiểm soát hành vi điều chỉnh theo tỷ lệ

Theo mặc định, Cloud Functions for Firebase điều chỉnh số lượng thực thể đang chạy dựa trên số lượng yêu cầu đến, có thể điều chỉnh xuống 0 thực thể trong thời gian lưu lượng truy cập giảm. Tuy nhiên, nếu ứng dụng của bạn yêu cầu giảm độ trễ và bạn muốn giới hạn số lần khởi động nguội, bạn có thể thay đổi hành vi mặc định này bằng cách chỉ định số lượng thực thể vùng chứa tối thiểu để giữ ấm và sẵn sàng phân phát yêu cầu.

Tương tự, bạn có thể đặt một số tối đa để giới hạn tỷ lệ của các thực thể trong các yêu cầu gửi đến. Hãy sử dụng chế độ cài đặt này để kiểm soát chi phí của bạn hoặc để giới hạn số lượng kết nối với dịch vụ sao lưu, chẳng hạn như với cơ sở dữ liệu.

Giảm số lần khởi động nguội

Để đặt số lượng thực thể tối thiểu cho một hàm trong mã nguồn, hãy sử dụng phương thức runWith. Phương thức này chấp nhận đối tượng JSON tuân theo RuntimeOptions giao diện, xác định giá trị cho minInstances. Ví dụ: hàm này sẽ đặt tối thiểu 5 thực thể để giữ ấm:

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

Sau đây là một số điều cần cân nhắc khi đặt giá trị cho minInstances:

  • Nếu Cloud Functions for Firebase mở rộng ứng dụng của bạn vượt quá chế độ cài đặt minInstances, bạn sẽ thấy trạng thái khởi động nguội cho mỗi thực thể vượt quá ngưỡng đó.
  • Khởi động nguội ảnh hưởng nghiêm trọng nhất đến những ứng dụng có lưu lượng truy cập tăng đột biến. Nếu ứng dụng có lưu lượng truy cập tăng đột biến và bạn đặt giá trị minInstances đủ cao để số lượt khởi động nguội sẽ giảm xuống mỗi khi lưu lượng truy cập tăng, bạn sẽ thấy đáng kể độ trễ thấp hơn. Đối với những ứng dụng có lưu lượng truy cập liên tục, việc khởi động nguội không có thể ảnh hưởng nghiêm trọng đến hiệu suất.
  • Việc đặt số thực thể tối thiểu là hợp lý đối với môi trường phát hành công khai, nhưng nên tránh trong môi trường kiểm thử. Để mở rộng quy mô đến 0 trong dự án kiểm thử nhưng vẫn giảm số lần khởi động nguội trong dự án sản xuất, bạn có thể đặt minInstances dựa trên biến môi trường FIREBASE_CONFIG:

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

Giới hạn số lượng thực thể tối đa cho một hàm

Để đặt số lượng thực thể tối đa trong mã nguồn hàm, hãy sử dụng phương thức runWith. Phương thức này chấp nhận một đối tượng JSON tuân thủ giao diện RuntimeOptions. Giao diện này xác định các giá trị cho maxInstances. Ví dụ: hàm này đặt giới hạn là 100 thực thể để không làm quá tải cơ sở dữ liệu cũ giả định:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

Nếu một hàm HTTP được mở rộng theo giới hạn maxInstances, thì các yêu cầu mới sẽ được đưa vào hàng đợi trong 30 giây, sau đó bị từ chối bằng mã phản hồi là 429 Too Many Requests nếu không có thực thể nào có sẵn vào thời điểm đó.

Để tìm hiểu thêm về các phương pháp hay nhất để sử dụng chế độ cài đặt số lượng thực thể tối đa, hãy xem các phương pháp hay nhất để sử dụng maxInstances.

Đặt thời gian chờ và phân bổ bộ nhớ

Trong một số trường hợp, các hàm của bạn có thể có các yêu cầu đặc biệt đối với giá trị thời gian chờ dài hoặc mức phân bổ bộ nhớ lớn. Bạn có thể đặt các giá trị này trong Google Cloud Console hoặc trong mã nguồn hàm (chỉ dành cho Firebase).

Để thiết lập quy trình phân bổ bộ nhớ và thời gian chờ trong mã nguồn của hàm, hãy sử dụng runWith được giới thiệu trong SDK Firebase cho Cloud Functions 2.0.0. Tuỳ chọn thời gian chạy này chấp nhận đối tượng JSON tuân theo RuntimeOptions giao diện, xác định các giá trị cho timeoutSecondsmemory. Ví dụ: chức năng lưu trữ này sử dụng 1 GB bộ nhớ và hết thời gian chờ sau 300 giây:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

Giá trị tối đa của timeoutSeconds540, tức là 9 phút. Dung lượng bộ nhớ được cấp cho một hàm tương ứng với CPU được phân bổ cho hàm đó, như được nêu chi tiết trong danh sách giá trị hợp lệ cho memory:

  • 128MB – 200 MHz
  • 256MB – 400 MHz
  • 512MB – 800 MHz
  • 1GB – 1,4 GHz
  • 2GB – 2,4 GHz
  • 4GB – 4,8 GHz
  • 8GB – 4,8 GHz

Cách thiết lập quy trình phân bổ bộ nhớ và thời gian chờ trong bảng điều khiển Google Cloud:

  1. Trong bảng điều khiển Google Cloud của Google, hãy chọn Cloud Functions (Hàm trên đám mây) trong trình đơn bên trái.
  2. Chọn một hàm bằng cách nhấp vào tên hàm đó trong danh sách hàm.
  3. Nhấp vào biểu tượng Chỉnh sửa trong trình đơn trên cùng.
  4. Chọn một mức phân bổ bộ nhớ trong trình đơn thả xuống có nhãn Memory allocated (Bộ nhớ được phân bổ).
  5. Nhấp vào Khác để hiển thị các tùy chọn nâng cao và nhập số giây vào hộp văn bản Thời gian chờ.
  6. Nhấp vào Lưu để cập nhật hàm.