我已经尝试了几件事情来解决这个问题,但我一无所知。
Here's the Go program.它只是一个文件,并且有一个/api/sign
端点,可以接受POST请求。这些POST请求在正文中有三个字段,它们记录在sqlite3数据库中。非常基本的东西。
I wrote a simple Dockerfile to containerize it.使用golang:1.7.4
构建二进制文件并将其复制到alpine:3.6
以获取最终图像。再一次,没什么特别的。
我使用wrk
来衡量效果。使用8个线程和1k个连接50秒(wrk -t8 -c1000 -d50s -s post.lua http://server.com/api/sign
)和a lua script来创建发布请求,我测量了不同情况之间每秒的请求数。在所有情况下,我从我的笔记本电脑运行wrk
,服务器在DigitalOcean VPS(2个vCPU,2 GB RAM,SSD,Debian 9.4)中,非常接近我。
直接运行二进制文件 2979次请求/秒。
Docker(docker run -it -v $(pwd):/data -p 8080:8080 image
)产生了 179个请求/秒。
如您所见,Docker版本比直接运行二进制文件慢16倍。在两个实验中,其他一切都是一样的。
我已尝试过以下方法,Docker版本的性能几乎没有任何改进:
尝试使用主机网络而不是网桥。稍微增加到大约190个请求/秒,但它仍然很悲惨。
尝试使用--ulimit nofile=262144:262144
增加容器版本中文件描述符数量的限制。没有改善。
尝试了不同的版本,没有。
尝试debian:9.4
代替alpine:3.7
而不是SingletonClass.getInstance().executeMethod("MainThread");
,希望它的表现非常糟糕。这里也没什么。
(编辑)尝试在没有安装卷的情况下运行容器,但仍然没有性能改进。
我现在没有想法。任何帮助将不胜感激!
答案 0 :(得分:1)
使用内存中的sqlite3数据库完全解决了所有性能问题!
db, err = sql.Open("sqlite3", "file=dco.sqlite3?mode=memory")
我知道有一个磁盘I / O惩罚与Docker的抽象相关(即使在Linux上;我已经听说过它在macOS上更糟糕),但我没有知道它会是~16倍。
编辑:在大多数情况下,使用内存数据库并不是一个真正的选择。所以我找到了另一个特定于sqlite的解决方案。在所有数据库操作之前,执行此操作将sqlite切换到WAL模式而不是默认的回滚日志:
PRAGMA journal_mode=WAL;
PRAGMA synchronous=NORMAL;
这极大地改善了Docker版本的性能,超过2.7k请求/秒!