Golang Go语言中在 TLS 上比 Nginx 厉害这么多吗?

发布于 1周前 作者 songsunli 来自 Go语言

是我测试流程有问题吗?或者环境?

:2222的是 go 写的 https server 。代码很简单。都是标准库的。 根路径就返回个 index.html 内容是 404 not found

nginx 10 秒 1771 go 就 10 秒 6.9w

go 的 tlsconfig 如下

tlsCfg := &tls.Config{
    SessionTicketsDisabled: false,
    ClientSessionCache:     tls.NewLRUClientSessionCache(1000)
}

nginx ssl 配置部分如下

ssl_certificate   .pem;
ssl_certificate_key  .key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;

证书是 rsa2048

而且还有测试期间,nginx 部分就 cpu100% go 部分就 cpu50%上下。

服务器是阿里云的性能突发实例。


Golang Go语言中在 TLS 上比 Nginx 厉害这么多吗?

更多关于Golang Go语言中在 TLS 上比 Nginx 厉害这么多吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

50 回复

没有可比性

更多关于Golang Go语言中在 TLS 上比 Nginx 厉害这么多吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


一个反代,和一个语言比,有点意思

道理我都懂,但是问题出在哪呢? tls 版本? nginx 换成 1.3?

事出反常必有妖,go 开 cache nginx 不开是不是不公平

有的。cache 在全局配置中 ssl_session_cache builtin:1000 shared:SSL:10m;

都走的 http2 吗,Nginx 可能默认不是

是 http2 。都一样。都是 HTTP2

可能还有个原因,检查下 go 端是不是默认开启了 keep alive


我 go 还 httputil.reverseproxy 到 localhost:80 了(nginx)

还有一些 Nginx 的配置都会有影响,worker 数量,CPU aff ,multi acc 之类的,总得来的可比性不高

这是哪个开关。但是 nginx 也有 keepalive_timeout 65 啊

wrk 没用过 你可以用 ab 压测下对比下结果里的 Keep-Alive 数量

#7 记得 v2 的 h2+tls 教程, 写着 nginx 不支持 http2, 还特意换了 caddy

nginx 好几年前就支持 http2 了啊……

为什么没可比性,前者说到底是 C

#15
是的。但是这个结果在我这很诡异啊。

现在有一些公司其实不用 nginx ,用的硬件负载 F5

两者都是用同一个版本的 TLS 呢?

#14 重新翻了下, 教程说的是 nginx 不支持 h2 反代. 不过引用的 issue 是 18 年的了

另外,nginx 是多进程,go 是多线程,架构本身是不同的,进程比线程的切换开销大。

测试结果没问题,对比看估计是你的带宽满了

我做过相关的对比测试, 我只能说你 nginx 没配置对

这明显是你的配置有问题。
nginx avg latency 1.72s max 2s
你说这个数字正常吗?拿个 arm 的路由器跑 nginx 都跑不出这效果

看你这个 hostname ,你不会用的是 Windows 吧? nginx Windows 版官方明确说了 unsupported ,testing only 。

#21 nginx qps 175 的情况下,带宽 1.37MB/s ,golang qps 6892 的情况下,带宽 2MB/s ,可见 nginx 是不是磁盘 io 读取了 404.html 页面返回,而 go 只从代码里返回了 404 状态码

go 是正常水平 nginx 不可能这么低的吧

https://www.v2ex.com/t/776221#reply4
一楼我回的, 和你这里情况类似. 都是 go 块很多.

我测了下树莓派 3B 上的 nginx https: 49301 requests in 10.08s, 22.76MB read

你的结果里 Non-2xx or 3xx 响应有 639 个,请求没有正确处理吧,看下日志,是不是触发了什么防护

丢完整配置出来!

跟 老哥疑惑同一个地方,为啥你的 1771 次能返回这么多数据,你的 Nginx 是不是喜欢夹带私货……

记得 TLS1.3 本身的握手会比 TLS1.2 快很多。

抓包看的时候 TLS1.2 ,需要经历 Client Hello 和 Server Hello ,密钥和加密套件确认交换,没记错的话要 4 次之后开始传请求。

1.3 的话 Client Hello 和密钥一起发送,加密套件不再需要确认,两次之后就可以传请求。

我也在 wsl ubuntu 22.04 安装了 nginx 测了一下,测试过程也是 CPU 100%

基本可以破案了,就是 wsl ubuntu nginx 不行,也就能测试用用,跑起来甚至不如树莓派 3B 上的

Running 10s test @ https://ubuntu/
6 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 371.19ms 131.68ms 1.62s 80.99%
Req/Sec 430.44 205.48 2.34k 78.04%
16728 requests in 10.08s, 13.56MB read
Requests/sec: 1659.32
Transfer/sec: 1.35MB

Running 10s test @ https://raspberry/
6 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 125.46ms 68.90ms 767.34ms 72.52%
Req/Sec 1.06k 411.05 2.34k 74.57%
50618 requests in 10.09s, 23.36MB read
Requests/sec: 5016.59
Transfer/sec: 2.32MB

你的 Nginx 是不是开启了某些自动保护?放 DDoS 那种

遇到这种现象一定要相信是自己的问题而不是 go 真的牛逼到可以吊打 c/cpp/rust

nginx 是进程绑核的,才用 reactor 模型,并不是你说的多个进程在不同核中飘来飘去。

BFE (一个用 Go 重写 nginx 的项目),压测比 nginx 差了一倍,事出反常必有妖。或者可以 nginx 开 debug 看看每个阶段的耗时?

nginx 的 debug 在哪里开

绑核和调度有关系么?

还一个原因,有可能是阿里云的机器在 80 端口有包过滤、防火墙之类的

说错了,443 端口,建议 OP 将两个程序 bind 到同一个端口压测

在 nginx 的 server 里面的最后加上这个,reload ,再测下看看
location = / {
return 200 “404 not found”;
}
access_log off;

建议先在自己本地机测试。云服务器或多或少有些保护措施。

估计你的 nginx 用的 OpenSSL 没编译好。

Running 10s test @ https://localhost:443/
6 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 139.92ms 104.60ms 999.46ms 93.38%
Req/Sec 1.15k 529.66 6.22k 81.98%
61417 requests in 10.10s, 51.31MB read
Requests/sec: 6079.15
Transfer/sec: 5.08MB

双核轻量云,nginx 1.20 boringssl

散了吧,楼主的测试根本不准

配置:Oracle A1 ARM64 4C24G

curl https://test.example.com/ -s -D-

HTTP/2 200
server: nginx/1.23.1
date: Thu, 01 Sep 2022 16:37:53 GMT
content-type: text/plain; charset=utf-8
content-length: 13

测试命令:wrk -c1000 -d10 -t6 https://test.example.com/

Running 10s test @ https://test.example.com/
6 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 11.86ms 42.40ms 1.76s 99.55%
Req/Sec 15.35k 4.33k 43.39k 74.52%
737772 requests in 10.07s, 157.57MB read
Requests/sec: 73232.29
Transfer/sec: 15.64MB

Qps 相差 40 倍,带宽却几乎差不多。顺着这个往下查就行了

我树莓派 4B 都能跑 11 K/s

Running 10s test @ test.example.com
6 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 44.72ms 78.06ms 814.26ms 95.19%
Req/Sec 2.47k 1.32k 7.09k 66.45%
116597 requests in 10.10s, 24.90MB read
Requests/sec: 11544.61
Transfer/sec: 2.47MB

我也是 wsl2 结果完全不一样。怕的你的 wsl 的 hostname 访问到 ipv6 或者别的什么去了。可能大部分时间都在这上面,用 ip 地址试试看呗?

造句:用一句话把三个不相干的东西连起来并让别人无言以对

这个 ip 为啥遮住了,用的不是 localhost 吗?如果不是的话,走了网络栈出去的话,显然没有控制好变量吧?

Vultr - Optimized Cloud Compute - CPU Optimized
8 vCPUs 16 GB Memory

测试结果为 14 万 /秒


$ wrk -c1000 -d10 -t8 https://test.example.com/

Running 10s test @ https://test.example.com/
8 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 9.27ms 10.67ms 108.29ms 85.90%
Req/Sec 18.49k 7.28k 47.43k 77.99%
1444385 requests in 10.09s, 242.37MB read
Requests/sec: 143170.65
Transfer/sec: 24.02MB

关于Go语言(Golang)在TLS方面与Nginx的比较,可以从以下几个方面进行专业分析:

  1. TLS支持:Go语言从1.12版本开始提供对TLS 1.3的可选支持,并随后逐渐成为默认选项。Nginx也支持TLS,但配置和优化可能相对复杂。Go语言的标准库对TLS和证书相关操作提供了良好支持,简化了HTTPS服务器的设置。
  2. 性能:Go语言以其高并发性和高效性著称,在处理大量并发TLS连接时可能表现出色。Nginx同样是一个高性能的Web服务器,但在某些特定场景下,Go语言可能因其灵活性和低资源消耗而更具优势。
  3. 配置和灵活性:Go语言允许通过代码直接配置TLS参数,提供了更高的灵活性。Nginx的配置虽然强大,但需要通过配置文件进行,相对不够灵活。
  4. 集成与应用:Go语言可以方便地调用其他语言编写的程序,实现与其他语言的接口交互,这在进行复杂系统集成时可能是一个优势。Nginx虽然也有丰富的模块和插件生态,但在某些特定应用场景下可能不如Go语言灵活。

综上所述,Go语言在TLS方面确实表现出了一定的优势,但并不意味着它在所有场景下都比Nginx更强大。选择哪种技术取决于具体的应用场景和需求。

回到顶部