性能比拼: Go vs Bun

news2025/4/21 18:17:32

本内容是对知名性能评测博主 Anton Putra Go (Golang) vs. Bun: Performance (Latency - Throughput - Saturation - Availability) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准

我对 Bun 在之前的基准测试中的出色表现感到惊讶,因此我决定将它与 Go 进行比较。在我看来,Go 与 JavaScript 相比属于不同的级别。

在以下内容中,我们将首先使用标准库来比较 Bun 和 Go。我们将使用标准库 API 的 /devices 端点,以 JSON 格式向客户端返回一个硬编码的设备信息。我们将重点关注四个黄金指标。

由于这些是面向用户的应用程序,我们的主要关注点将是延迟,特别是使用 P99 百分位(P99 percentile)。

接下来是吞吐量(Throughput),对于 Web 应用程序而言,这意味着每个应用程序每秒可以处理的请求数量。

然后,我们将通过测量服务的繁忙程度来考察饱和度(Saturation),更具体地说是应用程序相对于 Kubernetes 中定义的限制的 CPU 和内存使用情况。我们还需要测量 CPU 节流(CPU throttling),因为它在 Kubernetes 中扮演着重要角色。当一个服务被节流时,会立即增加延迟并降低整体性能。
最后,我们将通过查看特定时间段内失败请求数相对于总请求数的比例来衡量可用性(Availability)。

现在,大多数基准测试都侧重于综合测试(synthetic tests),但我也想看看这些应用程序在真实世界场景中的表现如何。我在不同的基准测试中使用了不同的用例。在这个测试中,我们将使用 MongoDB 数据库添加一个持久化层。每当应用程序收到一个 POST 请求时,它将解析请求体,生成 UUID,并将该项目保存到 MongoDB 中。

除了标准指标外,我还使用 Prometheus 指标(Prometheus Metrics)对每个应用程序进行了检测,以测量每个应用程序将设备保存到数据库所需的时间。此外,有人建议加入数据库指标,所以我还添加了 MongoDB 自身的 CPU 使用率。在这些测试中,我们将产生足够的负载以找到两个应用程序的崩溃点。

我将这两个应用程序部署到了 AWS 上的生产级 Kubernetes 集群中,为应用程序使用了大型实例,每个实例配备 2 个 CPU 和 8 GB 内存。由于 Bun 在大多数操作中使用单线程,我将每个应用程序限制为使用 1 个 CPU,这可以看作是一个无限重复的周期中 100 毫秒间隔的 100% 使用率,并由 cgroups 强制执行。此外,我分配了 256MB 的内存。我还对应用程序进行了水平扩展,在每个 EC2 实例上为每个应用程序部署了两个实例。

为了产生负载,我使用了 Graviton 实例(它们稍微便宜一些),并为每个应用程序部署了 20 个 Pod。这些 Pod 会逐渐增加虚拟客户端的数量,直到两个应用程序都失败为止。

欢迎提出任何关于如何改进任一应用程序的建议,也欢迎提交 Pull Request,我通常会在一天内合并。

好的,让我们开始吧。

在第一个测试中,我们评估每个应用程序处理 HTTP 请求并将硬编码值以 JSON 格式返回给客户端的能力。在右上方的图表中,我们将测量吞吐量,显示每个应用程序可以处理多少请求。在左侧,我们有延迟,测量响应所需的时间。从一开始你就可以看到,Bun 应用程序处理每个请求需要明显更多的时间。同样重要的是要注意,我们是从客户端测量延迟,以使其尽可能准确。

接下来,我们看饱和度,它表明服务的繁忙程度。你可以看到 CPU 使用率的趋势:Go 使用更多的 CPU 时间,并将首先经历节流。由于我为每个应用程序部署了两个副本,我们测量的是平均 CPU 使用率。在右侧,我们有内存使用率,这只在两个服务都过载时才变得关键。

接下来是可用性。在这个测试中,平均请求完成时间不到 1 毫秒,所以我将客户端超时设置为 100 毫秒。当超过该超时时间时,你会在可用性图表中看到下降。

直到 CPU 使用率达到 60% 到 70%,你不会看到任何节流。在大约每秒 23,000 个请求时,两个应用程序之间的 CPU 使用率差异变得更加明显。到这一点,Go 开始失去其在延迟方面的优势(对于这类应用程序)。一旦 CPU 使用率达到 40%,性能开始下降,延迟增加。

在大约每秒 46,000 个请求时,Go 在可处理的请求数量方面开始落后于 Bun。在每秒 61,000 个请求时,差异变得更加显著。Go 的延迟增加到 10 毫秒,Kubernetes 开始对其进行节流,这影响了性能。另一方面,Bun 保持着低延迟,尽管有些请求开始超时。数量不多,但你会在可用性图表中注意到下降。

在每秒 69,000 个请求时,情况变得很明显,Go 无法处理更多请求,并开始缓存(caching)其中一些请求。

好的,让我们继续。在大约每秒 90,000 个请求时,Bun 也达到了其极限,并被 Kubernetes 节流。

现在,让我打开每个图表以显示完整的测试持续时间。如你所见,测试耗时约 2 小时完成。

首先是每秒请求数。

接下来是客户端延迟。在 Go 于大约 40% CPU 使用率时开始性能下降后,其延迟超过了 Bun,但在此之前,它的延迟要低得多。

接下来是 CPU 使用率。

然后是内存使用率。你可以看到当 Go 无法处理所有请求并开始缓存它们时,内存使用量出现峰值。最终内存使用率达到 100%,Kubernetes 由于内存不足错误(out of memory errors)多次终止了该应用程序。

之后是可用性图表。

最后是 CPU 节流。

如果你正在构建延迟很重要的面向客户端的应用程序,你可能需要考虑 Go,因为在 CPU 使用率达到 40% 之前,它的性能要好得多。另一方面,如果你更关心吞吐量而延迟不那么关键(例如内部微服务),那么 Bun 可能是更好的选择。



现在,让我们开始第二个测试。大多数基准测试使用简单的任务和算法来衡量性能,但实际上,你会严重依赖外部库,并且你的应用程序性能将取决于这些库的开发水平。此外,几乎所有应用程序都需要某种持久化层,例如数据库。

在之前的 Bun 对比 Node 的基准测试中,我使用了 PostgreSQL 关系数据库。在这个测试中,我将其替换为 MongoDB 文档数据库。如果你对 Bun 与 PostgreSQL 的表现感兴趣,可以查看那个视频。

我使用 Prometheus 指标对两个应用程序都进行了检测,这样我们就可以测量每个函数调用的持续时间。在这个测试中,当应用程序收到一个 POST 请求时,它会生成 UUID 并将完整的对象存储在数据库中。你可以在视频描述中找到源代码的链接。我还使用 Prometheus 直方图(histogram)来测量向 MongoDB 插入数据所需的时间。

此外,根据我收到的反馈,我现在也测量 MongoDB 的 CPU 使用率以及其他标准指标。

在这个测试中,Go 的表现明显优于 Bun。客户端延迟和数据库插入延迟都几乎是 Bun 的一半。与 Bun 相比,Go 的 CPU 使用率也低得多。在大约每秒 7500 个请求时,Bun 开始性能下降并丢弃一些请求。Kubernetes 也开始对其进行节流,导致延迟增加。

让我们继续,找到 Go 的崩溃点。在大约每秒 24,000 个请求时,Go 也开始性能下降,CPU 使用率接近 100%。

如你所见,当测试涉及的不仅仅是像上一个测试那样返回静态响应时,Go 在真实世界场景中的表现要好得多。你肯定需要比静态响应更多的功能。根据我的经验和我运行的基准测试,Bun 在静态、综合基准测试中表现非常好,但是当需要执行实际工作(例如与数据库交互)时,Bun 失去了许多优势,甚至在这些情况下 Node.js 的表现都更好。所以我建议在选择 Bun(如果你的目标是提高性能)之前,先测试你的特定用例。

好的,让我展示整个测试期间的每个图表。

首先是每秒请求数图。

然后是客户端延迟。

数据库插入延迟。

MongoDB CPU 使用率。

应用程序 CPU 使用率。

内存使用率。

可用性图表。

(图略)

最后是 CPU 节流。

(图略)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2339596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

定制化 Docsify 文档框架实战分享

🌟 定制化 Docsify 文档框架实战分享 在构建前端文档平台时,我们希望拥有更友好的用户界面、便捷的搜索、清晰的目录导航以及实用的代码复制功能。借助 Docsify,我实现了以下几个方面的定制优化,分享给大家 🙌。 &…

鸿蒙ArkUI之布局实战,线性布局(Column,Row)、弹性布局(Flex)、层叠布局(Stack),详细用法

本文聚焦于ArkUI的布局实战,三种十分重要的布局,线性布局、弹性布局、层叠布局,在实际开发过程中这几种布局方法都十分常见,下面直接上手 线性布局 垂直布局(Column) 官方文档: Column-行列…

测试基础笔记第七天

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、cat命令二、ls -al命令三、>重定向符号四、>>追加重定向符号五、less/more命令六、grep命令七、|管道符八、clear命令九、head命令十、tail命令十一、…

[Windows] Adobe Camera Raw 17.2 win/Mac版本

[Windows] Adobe Camera Raw 链接:https://pan.xunlei.com/s/VOOIAXoyaZcKAkf_NdP-qw_6A1?pwdpd5k# Adobe Camera Raw,支持Photoshop,lightroom等Adobe系列软件,对相片无损格式进行编辑调色。 支持PS LR 2022 2023 2024 2025版…

开源模型应用落地-Podcastfy-从文本到声音的智能跃迁-Gradio(一)

一、前言 在当今信息呈现方式越来越多样化的背景下,如何将文字、图片甚至视频高效转化为可听的音频体验,已经成为内容创作者、教育者和研究者们共同关注的重要话题。Podcastfy是一款基于Python的开源工具,它专注于将多种形式的内容智能转换成…

Python 深度学习实战 第11章 自然语言处理(NLP)实例

Python 深度学习实战 第11章 自然语言处理(NLP)实例 内容概要 第11章深入探讨了自然语言处理(NLP)的深度学习应用,涵盖了从文本预处理到序列到序列学习的多种技术。本章通过IMDB电影评论情感分类和英西翻译任务,详细介绍了如何使…

将 DeepSeek 集成到 Spring Boot 项目实现通过 AI 对话方式操作后台数据

文章目录 项目简介本项目分两大模块 GiteeMCP 简介环境要求项目代码核心实现代码MCP 服务端MCP 客户端 DeepSeek APIDockersse 连接ws 连接(推荐)http 连接 vue2-chat-windowCherry Studio配置模型配置 MCP调用 MCP 项目简介 在本项目中,我们…

《前端面试题之 Vue 篇(第三集)》

目录 1、 nvm的常用命令①.Node.js 版本与 npm 版本的对应关系②Vue2 与 Vue3 项目的 Node.js 版本分界线③版本管理实践建议 2、Vue2 项目搭建(基于 vue-cli Webpack)① 环境准备② 安装 Vue CLI(脚手架)③.创建项目&#xff08…

嵌入式C语言位操作的几种常见用法

作为一名老单片机工程师,我承认,当年刚入行的时候,最怕的就是看那些密密麻麻的寄存器定义,以及那些让人眼花缭乱的位操作。 尤其是遇到那种“明明改了寄存器,硬件就是不听话”的情况,简直想把示波器砸了&am…

基于Djiango实现中药材数据分析与可视化系统

中药材数据分析与可视化系统 项目截图 登录 注册 首页 药材Top20 药材价格 产地占比 历史价格 新闻资讯 后台管理 一、项目概述 中药材数据分析与可视化系统是一个基于Django框架开发的专业Web应用,致力于对各类中药材数据进行全面、系统的采集、分析和可视化展示…

stm32(gpio的四种输出)

其实GPIO这个片上外设的功能: 用于控制IO引脚。 CPU就如同大脑,而这些片上外设就如同四肢一样的关系 如图 —————————————————————————————— OK类比了以上 其实GPIO是有 八种工作模式的 这八种工作模式 因为GPIO是面向IO…

Zookeeper 可观测性最佳实践

Zookeeper 介绍 ZooKeeper 是一个开源的分布式协调服务,用于管理和协调分布式系统中的节点。它提供了一种高效、可靠的方式来解决分布式系统中的常见问题,如数据同步、配置管理、命名服务和集群管理等。本文介绍通过 DataKit 采集 Zookeeper 指标&#…

微信小程序三种裁剪动画有效果图

效果图 .wxml <image class"img inset {{status?action1:}}" src"{{src}}" /> <image class"img circle {{status?action2:}}" src"{{src}}" /> <image class"img polygon {{status?action3:}}" src&quo…

C语言笔记(鹏哥)上课板书+课件汇总(结构体)-----数据结构常用

结构体 目录&#xff1a; 1、结构体类型声明 2、结构体变量的创建和初始化 3、结构体成员访问操作符 4、结构体内存对齐*****&#xff08;重要指数五颗星&#xff09; 5、结构体传参 6、结构体实现位段 一、结构体类型声明 其实在指针中我们已经讲解了一些结构体内容了&…

git清理--解决.git文件过大问题

背景&#xff1a;为什么.git比我仓库中的文件大很多 为什么我的git中只有一个1KB的README&#xff0c;但是.git却又1G多&#xff1f;当我想把这个git库push到gitee时&#xff0c;还会报错&#xff1a; 根据报错信息&#xff0c;可看出失败的原因是&#xff1a;有文件的大小超过…

Jetson Orin NX 部署YOLOv12笔记

步骤一.创建虚拟环境 conda create -n yolov12 python3.8.20 注意&#xff1a;YOLOv12/YOLOv11/YOLOv10/YOLOv9/YOLOv8/YOLOv7a/YOLOv5 环境通用 步骤二.激活虚拟环境 conda activate yolov12 #激活环境 步骤三.查询Jetpack出厂版本 Jetson系列平台各型号支持的最高Jetp…

微服务2--服务治理与服务调用

前言 &#xff1a;本文主要阐述微服务架构中的服务治理&#xff0c;以及Nacos环境搭建、服务注册、服务调用&#xff0c;负载均衡以及Feign实现服务调用。 服务治理 服务治理是微服务架构中最核心最基本的模块。用于实现各个微服务的自动化注册与发现。 服务注册&#xff1a;在…

C语言之高校学生信息快速查询系统的实现

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 C语言之高校学生信息快速查询系统的实现 目录 任务陈述与分析 问题陈述问题分析 数据结构设…

Spring Boot 项目中发布流式接口支持实时数据向客户端推送

1、pom依赖添加 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>2、事例代码 package com.pojo.prj.controller;import com.pojo.common.core.utils.String…

【网络篇】从零写UDP客户端/服务器:回显程序源码解析

大家好呀 我是浪前 今天讲解的是网络篇的第四章&#xff1a;从零写UDP客户端/服务器&#xff1a;回显程序源码解析 从零写UDP客户端/服务器&#xff1a;回显程序源码解析 UDP 协议特性​核心类介绍​ UDP的socket应该如何使用&#xff1a;1: DatagramSocket2: DatagramPacket回…