在AWS Lambda中使用相同的MySQL连接与Golang的例子

172 阅读1分钟

在这个例子中,我们将使用AWS Lambda函数来向MySQL数据库插入数据。这里的重点是证明你不需要做任何特别的事情来重复使用相同的连接(阅读这里),但关键的一点是,不要在代码中手动关闭连接。

前提条件

创建一个名为lambda 的数据库和一个表request

我的MySQL服务器作为docker容器在主机操作系统中运行,因此下面使用docker DSN:

package main

import (
	"context"
	"database/sql"
	"log"
	"time"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-lambda-go/lambdacontext"

	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func init() {
	var err error
	db, err = sql.Open("mysql", "root:root@tcp(host.docker.internal:3306)/lambda")
	if err != nil {
		log.Fatalln(err)
	}

	// Do not use this!
	// defer db.Close()
}

func main() {
	lambda.Start(handle)
}

func handle(ctx context.Context) error {
	lc, _ := lambdacontext.FromContext(ctx)

	qry := `INSERT INTO request (uuid, created_at) VALUES (?, ?)`

	if _, err := db.ExecContext(ctx, qry, lc.AwsRequestID, time.Now().UTC()); err != nil {
		return err
	}

	return nil
}

设置

$ GOOS=linux CGO_ENABLED=0 go build -ldflags "-s -w" -o main main.go

zip lambda.zip main

aws --profile localstack --endpoint-url http://localhost:4566 lambda create-function \
    --function-name test-lambda \
    --handler main \
    --runtime go1.x \
    --role test-role \
    --zip-file fileb://lambda.zip

测试

你可以在MySQL服务器中使用以下查询来观察变化。结果应该与你看到的相似:

mysql> SHOW PROCESSLIST;
+-----+------+------------------+----------+---------+------+----------+------------------+
| Id  | User | Host             | db       | Command | Time | State    | Info             |
+-----+------+------------------+----------+---------+------+----------+------------------+
|   4 | root | 172.23.0.1:55642 | lambda   | Sleep   |   11 |          | NULL             |
|   5 | root | 172.23.0.1:55646 | NULL     | Sleep   |   21 |          | NULL             |
| 305 | root | localhost        | lambda   | Query   |    0 | starting | SHOW PROCESSLIST |
+-----+------+------------------+----------+---------+------+----------+------------------+
4 rows in set (0.00 sec)

mysql> SHOW STATUS WHERE `variable_name` = 'Max_used_connections';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Max_used_connections | 8     |
+----------------------+-------+
1 row in set (0.01 sec)

mysql> SHOW STATUS WHERE `variable_name` = 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 4     |
+-------------------+-------+
1 row in set (0.01 sec)

这将运行Lambda函数1000次。在运行过程中观察上面的查询结果:

$ for ((i=1;i<=1000;i++)); do aws --profile localstack --endpoint-url http://localhost:4566 lambda invoke --function-name test-lambda lambda.json; done