首页 > 解决方案 > 使用 Docker 对简单的 Go 服务器造成巨大的性能影响

问题描述

我已经尝试了几件事来解决这个问题,但我一无所知。

这是 Go 程序。它只是一个文件,并且有一个/api/sign接受 POST 请求的端点。这些 POST 请求在正文中有三个字段,它们记录在 sqlite3 数据库中。很基本的东西。

我写了一个简单的 Dockerfile 来容器化它。用于golang:1.7.4构建二进制文件并将其复制到alpine:3.6最终图像。再一次,没有什么特别的。

我用来wrk对性能进行基准测试。使用8 个线程wrk -t8 -c1000 -d50s -s post.lua http://server.com/api/sign和1k 个连接,持续 50 秒在所有情况下,我都是wrk从我的笔记本电脑上运行的,服务器位于离我很近的 DigitalOcean VPS(2 个 vCPU、2 GB RAM、SSD、Debian 9.4)中。

如您所见,Docker 版本比直接运行二进制文件慢 16 倍以上。在这两个实验中,其他一切都是相同的。

我尝试了以下方法,但 Docker 版本的性能几乎没有改善:

在这一点上我没有想法。任何帮助将非常感激!

标签: performancedockergo

解决方案


使用内存中的 sqlite3 数据库完全解决了所有性能问题!

db, err = sql.Open("sqlite3", "file=dco.sqlite3?mode=memory")

我知道有一个与 Docker 的抽象相关的磁盘 I/O 损失(即使在 Linux 上;我听说它在 macOS 上更糟),但我不知道它会是 ~16 倍。

编辑:大多数时候使用内存数据库并不是一个真正的选择。所以我找到了另一个特定于 sqlite 的解决方案。在所有数据库操作之前,将 sqlite 切换到 WAL 模式而不是默认的回滚日志:

PRAGMA journal_mode=WAL;
PRAGMA synchronous=NORMAL;

这极大地提高了 Docker 版本的性能,超过 2.7k 请求/秒!


推荐阅读