V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dzdh
V2EX  ›  Go 编程语言

在 TLS 上 Go 比 Nginx 厉害这么多吗?

  •  
  •   dzdh · 2022-09-01 15:49:50 +08:00 · 6816 次点击
    这是一个创建于 815 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    :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%上下。

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

    第 1 条附言  ·  2022-09-01 18:31:38 +08:00
    服务器是 [阿里云] 的性能突发实例 8c8g
    第 2 条附言  ·  2022-09-01 18:35:47 +08:00

    完整配置

    nginx
    http {
    user  www www;
    worker_processes  auto;
    worker_cpu_affinity auto;
    
    error_log  /usr/local/nginx/logs/error.log error;
    pid        /usr/local/nginx/logs/nginx.pid;
    
    #Specifies the value for maximum file descriptors that can be opened by this process. 
    worker_rlimit_nofile 65535;
    
    events
    {
      use epoll;
      worker_connections 65535;
    }
    
            server_names_hash_max_size 1024;
            server_names_hash_bucket_size 2048;
            client_header_buffer_size 32k;
            large_client_header_buffers 4 32k;
            client_max_body_size 50m;
    
            sendfile on;
            tcp_nopush     on;
    
            keepalive_timeout 65;
    
            tcp_nodelay on;
    
            fastcgi_connect_timeout 15;
            fastcgi_send_timeout 15;
            fastcgi_read_timeout 15;
            fastcgi_buffer_size 64k;
            fastcgi_buffers 4 64k;
            fastcgi_busy_buffers_size 128k;
            fastcgi_temp_file_write_size 128k;
    
            ssl_session_cache ssl_session_cache builtin:1000 shared:SSL:10m;
    
            server {
                listen 443 ssl http2;
                server_name xxx;
                root xxx;
                index index.html index.php;
                ssl_certificate   xxx.pem;
                ssl_certificate_key  xxx.key;
                ssl_session_timeout 5m;
                ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
                ssl_prefer_server_ciphers on;
            }
    
    
    }
    
    第 3 条附言  ·  2022-09-02 13:26:18 +08:00

    阿里云的cdn节点。ip也都是就近的。不知道跟是不是要回源有关系。

    49 条回复    2022-09-03 11:51:43 +08:00
    dem0ns
        1
    dem0ns  
       2022-09-01 15:55:43 +08:00
    没有可比性
    xuelu520
        2
    xuelu520  
       2022-09-01 15:56:41 +08:00   ❤️ 1
    一个反代,和一个语言比,有点意思
    dzdh
        3
    dzdh  
    OP
       2022-09-01 15:56:43 +08:00
    @dem0ns 道理我都懂,但是问题出在哪呢? tls 版本? nginx 换成 1.3?
    rekulas
        4
    rekulas  
       2022-09-01 15:57:04 +08:00   ❤️ 1
    事出反常必有妖,go 开 cache nginx 不开是不是不公平
    dzdh
        5
    dzdh  
    OP
       2022-09-01 15:58:23 +08:00
    @rekulas 有的。cache 在全局配置中 ssl_session_cache builtin:1000 shared:SSL:10m;
    seers
        6
    seers  
       2022-09-01 16:01:31 +08:00 via Android
    都走的 http2 吗,Nginx 可能默认不是
    dzdh
        7
    dzdh  
    OP
       2022-09-01 16:02:01 +08:00
    @seers 是 http2 。都一样。都是 HTTP2
    rekulas
        8
    rekulas  
       2022-09-01 16:03:02 +08:00
    可能还有个原因,检查下 go 端是不是默认开启了 keep alive
    dzdh
        9
    dzdh  
    OP
       2022-09-01 16:03:57 +08:00
    @seers
    我 go 还 httputil.reverseproxy 到 localhost:80 了(nginx)
    seers
        10
    seers  
       2022-09-01 16:04:14 +08:00 via Android
    还有一些 Nginx 的配置都会有影响,worker 数量,CPU aff ,multi acc 之类的,总得来的可比性不高
    dzdh
        11
    dzdh  
    OP
       2022-09-01 16:04:30 +08:00
    @rekulas 这是哪个开关。但是 nginx 也有 keepalive_timeout 65 啊
    rekulas
        12
    rekulas  
       2022-09-01 16:07:35 +08:00
    @dzdh wrk 没用过 你可以用 ab 压测下对比下结果里的 Keep-Alive 数量
    DAPTX4869
        13
    DAPTX4869  
       2022-09-01 16:08:50 +08:00
    @dzdh #7 记得 v2 的 h2+tls 教程, 写着 nginx 不支持 http2, 还特意换了 caddy
    chendy
        14
    chendy  
       2022-09-01 16:10:46 +08:00
    @DAPTX4869 nginx 好几年前就支持 http2 了啊……
    justanetizen
        15
    justanetizen  
       2022-09-01 16:11:38 +08:00
    @xuelu520 为什么没可比性,前者说到底是 C
    dzdh
        16
    dzdh  
    OP
       2022-09-01 16:12:49 +08:00
    @justanetizen #15
    是的。但是这个结果在我这很诡异啊。
    justanetizen
        17
    justanetizen  
       2022-09-01 16:13:07 +08:00
    现在有一些公司其实不用 nginx ,用的硬件负载 F5
    justanetizen
        18
    justanetizen  
       2022-09-01 16:15:17 +08:00
    @dzdh 两者都是用同一个版本的 TLS 呢?
    DAPTX4869
        19
    DAPTX4869  
       2022-09-01 16:17:34 +08:00
    @chendy #14 重新翻了下, 教程说的是 nginx 不支持 h2 反代. 不过引用的 issue 是 18 年的了
    justanetizen
        20
    justanetizen  
       2022-09-01 16:19:15 +08:00
    另外,nginx 是多进程,go 是多线程,架构本身是不同的,进程比线程的切换开销大。
    liuxu
        21
    liuxu  
       2022-09-01 16:21:25 +08:00
    测试结果没问题,对比看估计是你的带宽满了
    ShuA1
        22
    ShuA1  
       2022-09-01 16:22:23 +08:00
    我做过相关的对比测试, 我只能说你 nginx 没配置对
    ryd994
        23
    ryd994  
       2022-09-01 16:22:48 +08:00 via Android
    这明显是你的配置有问题。
    nginx avg latency 1.72s max 2s
    你说这个数字正常吗?拿个 arm 的路由器跑 nginx 都跑不出这效果

    看你这个 hostname ,你不会用的是 Windows 吧? nginx Windows 版官方明确说了 unsupported ,testing only 。
    liuxu
        24
    liuxu  
       2022-09-01 16:23:32 +08:00
    @liuxu #21 nginx qps 175 的情况下,带宽 1.37MB/s ,golang qps 6892 的情况下,带宽 2MB/s ,可见 nginx 是不是磁盘 io 读取了 404.html 页面返回,而 go 只从代码里返回了 404 状态码
    xdeng
        25
    xdeng  
       2022-09-01 16:30:15 +08:00
    go 是正常水平 nginx 不可能这么低的吧
    onikage
        26
    onikage  
       2022-09-01 16:36:22 +08:00
    https://www.v2ex.com/t/776221#reply4
    一楼我回的, 和你这里情况类似. 都是 go 块很多.
    eason1874
        27
    eason1874  
       2022-09-01 16:41:31 +08:00
    我测了下树莓派 3B 上的 nginx https: 49301 requests in 10.08s, 22.76MB read

    你的结果里 Non-2xx or 3xx 响应有 639 个,请求没有正确处理吧,看下日志,是不是触发了什么防护
    uiosun
        28
    uiosun  
       2022-09-01 16:44:10 +08:00
    丢完整配置出来!

    跟 @liuxu 老哥疑惑同一个地方,为啥你的 1771 次能返回这么多数据,你的 Nginx 是不是喜欢夹带私货……
    cyrbuzz
        29
    cyrbuzz  
       2022-09-01 17:00:52 +08:00
    记得 TLS1.3 本身的握手会比 TLS1.2 快很多。

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

    1.3 的话 Client Hello 和密钥一起发送,加密套件不再需要确认,两次之后就可以传请求。
    eason1874
        30
    eason1874  
       2022-09-01 17:20:34 +08:00
    我也在 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
    villivateur
        31
    villivateur  
       2022-09-01 17:25:37 +08:00
    你的 Nginx 是不是开启了某些自动保护?放 DDoS 那种
    pastor
        32
    pastor  
       2022-09-01 18:37:48 +08:00
    遇到这种现象一定要相信是自己的问题而不是 go 真的牛逼到可以吊打 c/cpp/rust
    picone
        33
    picone  
       2022-09-01 18:39:14 +08:00
    @justanetizen nginx 是进程绑核的,才用 reactor 模型,并不是你说的多个进程在不同核中飘来飘去。
    picone
        34
    picone  
       2022-09-01 18:41:15 +08:00
    BFE (一个用 Go 重写 nginx 的项目),压测比 nginx 差了一倍,事出反常必有妖。或者可以 nginx 开 debug 看看每个阶段的耗时?
    dzdh
        35
    dzdh  
    OP
       2022-09-01 19:17:12 +08:00
    @picone nginx 的 debug 在哪里开
    justanetizen
        36
    justanetizen  
       2022-09-01 19:28:21 +08:00
    @picone 绑核和调度有关系么?
    justanetizen
        37
    justanetizen  
       2022-09-01 19:29:05 +08:00
    还一个原因,有可能是阿里云的机器在 80 端口有包过滤、防火墙之类的
    justanetizen
        38
    justanetizen  
       2022-09-01 19:31:53 +08:00
    说错了,443 端口,建议 OP 将两个程序 bind 到同一个端口压测
    ngv2
        39
    ngv2  
       2022-09-01 19:37:59 +08:00
    在 nginx 的 server 里面的最后加上这个,reload ,再测下看看
    location = / {
    return 200 "404 not found";
    }
    access_log off;
    adoal
        40
    adoal  
       2022-09-01 20:06:38 +08:00 via iPhone
    建议先在自己本地机测试。云服务器或多或少有些保护措施。
    picone
        41
    picone  
       2022-09-01 20:18:50 +08:00
    wdlth
        42
    wdlth  
       2022-09-02 00:21:29 +08:00
    估计你的 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
    ngv2
        43
    ngv2  
       2022-09-02 00:39:06 +08:00   ❤️ 1
    散了吧,楼主的测试根本不准

    配置: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
    dingyaguang117
        44
    dingyaguang117  
       2022-09-02 00:47:15 +08:00 via iPhone
    Qps 相差 40 倍,带宽却几乎差不多。顺着这个往下查就行了
    ngv2
        45
    ngv2  
       2022-09-02 01:11:03 +08:00
    我树莓派 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
    smallthing
        46
    smallthing  
       2022-09-02 03:54:01 +08:00
    我也是 wsl2 结果完全不一样。怕的你的 wsl 的 hostname 访问到 ipv6 或者别的什么去了。可能大部分时间都在这上面,用 ip 地址试试看呗?
    JohnBull
        47
    JohnBull  
       2022-09-02 11:30:15 +08:00 via Android   ❤️ 2
    造句:用一句话把三个不相干的东西连起来并让别人无言以对
    Senorsen
        48
    Senorsen  
       2022-09-02 13:03:12 +08:00
    这个 ip 为啥遮住了,用的不是 localhost 吗?如果不是的话,走了网络栈出去的话,显然没有控制好变量吧?
    ngv2
        49
    ngv2  
       2022-09-03 11:51:43 +08:00
    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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2729 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:04 · PVG 18:04 · LAX 02:04 · JFK 05:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.