1 回答

TA貢獻(xiàn)1966條經(jīng)驗(yàn) 獲得超4個(gè)贊
我們需要解決兩個(gè)問(wèn)題
正確管理 lambda 調(diào)用之間的狀態(tài)
配置連接池
正確管理狀態(tài)
讓我們稍微了解一下 AWS 是如何管理容器的。來(lái)自AWS 文檔:
執(zhí)行 Lambda 函數(shù)后,AWS Lambda 會(huì)在一段時(shí)間內(nèi)維護(hù)執(zhí)行上下文,以等待另一個(gè) Lambda 函數(shù)調(diào)用。實(shí)際上,如果 AWS Lambda 選擇在再次調(diào)用 Lambda 函數(shù)時(shí)重用上下文,服務(wù)會(huì)在 Lambda 函數(shù)完成后凍結(jié)執(zhí)行上下文,并解凍上下文以供重用。這種執(zhí)行上下文重用方法具有以下含義:
Lambda 函數(shù)代碼中的任何聲明(在處理程序代碼之外,請(qǐng)參閱編程模型)保持初始化狀態(tài),從而在再次調(diào)用該函數(shù)時(shí)提供額外的優(yōu)化。例如,如果您的 Lambda 函數(shù)建立數(shù)據(jù)庫(kù)連接,而不是重新建立連接,則在后續(xù)調(diào)用中使用原始連接。我們建議在您的代碼中添加邏輯以在創(chuàng)建連接之前檢查連接是否存在。
每個(gè)執(zhí)行上下文在 /tmp 目錄中提供 500MB 的額外磁盤(pán)空間。當(dāng)執(zhí)行上下文被凍結(jié)時(shí),目錄內(nèi)容仍然存在,提供可用于多次調(diào)用的臨時(shí)緩存。您可以添加額外的代碼來(lái)檢查緩存是否包含您存儲(chǔ)的數(shù)據(jù)。有關(guān)部署限制的信息,請(qǐng)參閱 AWS Lambda 限制。
如果 AWS Lambda 選擇重用執(zhí)行上下文,則由您的 Lambda 函數(shù)啟動(dòng)但在函數(shù)結(jié)束時(shí)未完成的后臺(tái)進(jìn)程或回調(diào)將恢復(fù)。您應(yīng)該確保代碼中的任何后臺(tái)進(jìn)程或回調(diào)(在 Node.js 的情況下)在代碼退出之前完成。
第一個(gè)要點(diǎn)表示狀態(tài)在執(zhí)行之間保持不變。讓我們看看實(shí)際效果:
let?counter?=?0 module.exports.handler?=?(event,?context,?callback)?=>?{ ??counter++ ??callback(null,?{?count:?counter?}) }
如果您部署它并連續(xù)多次調(diào)用,您將看到計(jì)數(shù)器將在兩次調(diào)用之間遞增。
現(xiàn)在您知道了 - 您不應(yīng)該調(diào)用defer db.Close()
,而應(yīng)該重用數(shù)據(jù)庫(kù)實(shí)例。您可以通過(guò)簡(jiǎn)單地創(chuàng)建db
一個(gè)包級(jí)變量來(lái)做到這一點(diǎn)。
首先,創(chuàng)建一個(gè)將導(dǎo)出Open
函數(shù)的數(shù)據(jù)庫(kù)包:
package database
import (
? ? "fmt"
? ? "os"
? ? _ "github.com/go-sql-driver/mysql"
? ? "github.com/jinzhu/gorm"
)
var (
? ? host = os.Getenv("DB_HOST")
? ? port = os.Getenv("DB_PORT")
? ? user = os.Getenv("DB_USER")
? ? name = os.Getenv("DB_NAME")
? ? pass = os.Getenv("DB_PASS")
)
func Open() (db *gorm.DB) {
? ? args := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true", user, pass, host, port, name)
? ? // Initialize a new db connection.
? ? db, err := gorm.Open("mysql", args)
? ? if err != nil {
? ? ? ? panic(err)
? ? }
? ? return
}
然后在你的 handler.go 文件中使用它:
package main
import (
? ? "context"
? ? "github.com/aws/aws-lambda-go/events"
? ? "github.com/aws/aws-lambda-go/lambda"
? ? "github.com/jinzhu/gorm"
? ? "github.com/<username>/<name-of-lib>/database"
)
var db *gorm.DB
func init() {
? ? db = database.Open()
}
func Handler() (events.APIGatewayProxyResponse, error) {
? ? // You can use db here.
? ? return events.APIGatewayProxyResponse{
? ? ? ? StatusCode: 201,
? ? }, nil
}
func main() {
? ? lambda.Start(Handler)
}
OBS:不要忘記替換github.com/<username>/<name-of-lib>/database
為正確的路徑。
現(xiàn)在,您可能仍然會(huì)看到too many connections
錯(cuò)誤。如果發(fā)生這種情況,您將需要一個(gè)連接池。
配置連接池
在軟件工程中,連接池是維護(hù)的數(shù)據(jù)庫(kù)連接的緩存,以便在以后需要對(duì)數(shù)據(jù)庫(kù)的請(qǐng)求時(shí)可以重用這些連接。連接池用于增強(qiáng)在數(shù)據(jù)庫(kù)上執(zhí)行命令的性能。
您將需要一個(gè)連接池,允許的連接數(shù)必須等于運(yùn)行的并行 lambda 數(shù),您有兩種選擇:
MySQL 代理
MySQL Proxy 是一個(gè)簡(jiǎn)單的程序,位于您的客戶端和 MySQL 服務(wù)器之間,可以監(jiān)視、分析或轉(zhuǎn)換它們的通信。它的靈活性允許廣泛的用途,包括負(fù)載平衡、故障轉(zhuǎn)移、查詢(xún)分析、查詢(xún)過(guò)濾和修改等等。
AWS 極光:
Amazon Aurora Serverless 是 Amazon Aurora(MySQL 兼容版本)的按需自動(dòng)擴(kuò)展配置,其中數(shù)據(jù)庫(kù)將根據(jù)您的應(yīng)用程序的需要自動(dòng)啟動(dòng)、關(guān)閉和擴(kuò)展或縮減容量。它使您能夠在云中運(yùn)行數(shù)據(jù)庫(kù)而無(wú)需管理任何數(shù)據(jù)庫(kù)實(shí)例。對(duì)于不頻繁、間歇性或不可預(yù)測(cè)的工作負(fù)載,這是一種簡(jiǎn)單、經(jīng)濟(jì)高效的選擇。
無(wú)論您選擇哪種方式,互聯(lián)網(wǎng)上都有大量關(guān)于如何配置兩者的教程。
- 1 回答
- 0 關(guān)注
- 173 瀏覽
添加回答
舉報(bào)