简介
与 PHP 不同,没有“经典”的方式来部署 Go 应用程序。在 2022 年,Docker/Kubernetes 是部署非脚本式 Web 应用程序的黄金标准。此外,有些人喜欢在裸机上构建和部署 Go 应用程序(例如使用 Supervisor)。让我们找出,在裸机上运行的应用程序和作为 Docker 容器运行的相同应用程序之间的性能差异是否很大。
编写基准测试
我认为,模拟应用程序活动的最佳方法是执行使用内存,CPU 和文件系统的操作。我决定编写一段代码:读取具有复杂结构的大型 JSON 文件(约 1GB),并解码该 JSON。让结构为:
type Country struct {
Name string `json:"name"`
Code string `json:"code"`
States []State `json:"states"`
}
type State struct {
Name string `json:"name"`
Code string `json:"code"`
Population int `json:"population"`
Cities []City `json:"cities"`
}
type City struct {
Name string `json:"name"`
Population int `json:"population"`
Companies []Company `json:"companies"`
}
type Company struct {
Name string `json:"name"`
Description string `json:"description"`
Employees []Employee `json:"employees"`
}
type Employee struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
PhoneNumber string `json:"phone_number"`
BirthYear int `json:"birth_year"`
BirthMonth int `json:"birth_month"`
BirthDay int `json:"birth_day"`
PostalCode string `json:"postal_code"`
Street string `json:"street"`
Building int `json:"building"`
Resume string `json:"resume"`
}
解码文件的代码如下:
startTime := time.Now()
jsonData, err := os.ReadFile("data.bin")
if err != nil {
panic(err)
}
var countries []Country
err = json.Unmarshal(jsonData, &countries)
if err != nil {
panic(err)
}
fmt.Printf("Parsing complete in: %v\n", time.Since(startTime))
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Alloc = %v MiB\n", m.Alloc/1024/1024)
fmt.Printf("TotalAlloc = %v MiB\n", m.TotalAlloc/1024/1024)
fmt.Printf("Sys = %v MiB\n", m.Sys/1024/1024)
fmt.Printf("NumGC = %v\n", m.NumGC)
开始运行!
我将使用 go 1.18.1,docker engine 20.10.14,Mac OS 12.3.1(Intel)
首先,我将构建 main.go 以测试裸机版本。接下来,我将添加 Dockerfile 并构建映像来 Dockerize 应用程序。
因此,我知道缓存具有 JSON 的文件。为了防止这种情况,我将按以下顺序运行应用程序:
- 裸机版本
- Docker 化版本
- 裸机版本
- Docker 化版本
- 裸机版本
- Docker 化版本
- ….
应用程序的每次启动都会消耗约 2.5GB 的 RAM,因此每次启动都会长期防止缓存。让我们运行每个版本的应用程序 30 次,以确保可以正确解释结果。
结果
循环完成后,我们可以看到 30 次运行的结果。Y 轴上是解析 ~1GB JSON 所花费的时间(秒)。开始时不稳定的结果是由于笔记本电脑上的并行活动引起的。启动后,我让我的笔记本电脑保持空闲,以防止后台活动。
解析 1GB JSON 所花费的时间(以秒为单位)。每个版本都运行了 30 次。
你可以在图表上看到的差异。接下来,我将仅获取测量的第二部分(第 15-30 次迭代)并计算裸机应用程序和 Docker 化版本之间性能的差异(百分比):
Docker 化和裸机应用程序之间的性能差异(百分比)
文本版本:
结论:
计算平均性能差异后,我得到的结果是:Docker 化的 Go 应用程序比在裸机上运行的应用程序慢了 25.09%。我认为 Docker 为我们提供了一种通用和便捷的运行和管理应用程序的方式。更重要的是,大多数应用程序大部分时间都在等待数据库和 I/O 操作。对于这些事情,Docker 很适合。选择你的应用程序部署方式吧 😉
译自:https://waclawthedev.medium.com/how-docker-affects-your-go-app-performance-c63e6d02275b
评论(0)