我有一个在 400MB SQLite 文件上运行 SQL 查询的 Golang 进程。
我正在使用带有连接字符串的https://github.com/mattn/go-sqlite3 :
file:mydb.sqlite?mode=ro&_journal=DELETE
在我的 Docker 开发机器上运行时,它只需要 20MB 的 RAM,但在 Google Run 上,任何小于 512MB 的实例都将返回 HTTP 代码 500,并memory exceeded
在日志中有限制。
docker diff x
显示未修改 DB 文件(我认为这会导致 gVisor 将整个二进制 SQLite db 文件复制到 RAM 以对其进行修改)。
docker 镜像是如何构建的
我正在使用源代码将 SQLite DB 文件复制到图像中:
FROM golang:latest
...
COPY . /go/src/api
我的 Golang 文件中有一个全局变量:var db *sqlx.DB
这在主 fn 中设置,之前ListenAndServe
:
conStr := fmt.Sprintf("file:%s?mode=ro&_journal=DELETE", *fileName)
dbConn, err := sqlx.Open("sqlite3", conStr)
db = dbConn
我在 HTTP 请求中查询数据库:
err := db.Selectv(&outDataSet, "SELECT...", arg1, arg2)
为什么这一定是 Cloud Run 环境的问题
docker stats
在本地运行时永远不会超过 20MB。
限制docker run
为 20MB RAM 在我的开发机器上也可以正常运行:
docker run \
--memory=20m \
--memory-swap=20m \
Cloud Run“容器内存分配”指标也远低于 128M:
https://console.cloud.google.com/monitoring/metrics-explorer
谢谢。