V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dzdh

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

  •  
  •   dzdh · Sep 1, 2022 · 7406 views
    This topic created in 1337 days ago, the information mentioned may be changed or developed.

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

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

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

    Supplement 1  ·  Sep 1, 2022
    服务器是 [阿里云] 的性能突发实例 8c8g
    Supplement 2  ·  Sep 1, 2022

    完整配置

    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;
            }
    
    
    }
    
    Supplement 3  ·  Sep 2, 2022

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

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

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

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

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

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

    1.3 的话 Client Hello 和密钥一起发送,加密套件不再需要确认,两次之后就可以传请求。
    eason1874
        30
    eason1874  
       Sep 1, 2022
    我也在 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  
       Sep 1, 2022
    你的 Nginx 是不是开启了某些自动保护?放 DDoS 那种
    pastor
        32
    pastor  
       Sep 1, 2022
    遇到这种现象一定要相信是自己的问题而不是 go 真的牛逼到可以吊打 c/cpp/rust
    picone
        33
    picone  
       Sep 1, 2022
    @justanetizen nginx 是进程绑核的,才用 reactor 模型,并不是你说的多个进程在不同核中飘来飘去。
    picone
        34
    picone  
       Sep 1, 2022
    BFE (一个用 Go 重写 nginx 的项目),压测比 nginx 差了一倍,事出反常必有妖。或者可以 nginx 开 debug 看看每个阶段的耗时?
    dzdh
        35
    dzdh  
    OP
       Sep 1, 2022
    @picone nginx 的 debug 在哪里开
    justanetizen
        36
    justanetizen  
       Sep 1, 2022
    @picone 绑核和调度有关系么?
    justanetizen
        37
    justanetizen  
       Sep 1, 2022
    还一个原因,有可能是阿里云的机器在 80 端口有包过滤、防火墙之类的
    justanetizen
        38
    justanetizen  
       Sep 1, 2022
    说错了,443 端口,建议 OP 将两个程序 bind 到同一个端口压测
    ngv2
        39
    ngv2  
       Sep 1, 2022
    在 nginx 的 server 里面的最后加上这个,reload ,再测下看看
    location = / {
    return 200 "404 not found";
    }
    access_log off;
    adoal
        40
    adoal  
       Sep 1, 2022 via iPhone
    建议先在自己本地机测试。云服务器或多或少有些保护措施。
    wdlth
        42
    wdlth  
       Sep 2, 2022
    估计你的 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  
       Sep 2, 2022   ❤️ 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  
       Sep 2, 2022 via iPhone
    Qps 相差 40 倍,带宽却几乎差不多。顺着这个往下查就行了
    ngv2
        45
    ngv2  
       Sep 2, 2022
    我树莓派 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  
       Sep 2, 2022
    我也是 wsl2 结果完全不一样。怕的你的 wsl 的 hostname 访问到 ipv6 或者别的什么去了。可能大部分时间都在这上面,用 ip 地址试试看呗?
    JohnBull
        47
    JohnBull  
       Sep 2, 2022 via Android   ❤️ 2
    造句:用一句话把三个不相干的东西连起来并让别人无言以对
    Senorsen
        48
    Senorsen  
       Sep 2, 2022
    这个 ip 为啥遮住了,用的不是 localhost 吗?如果不是的话,走了网络栈出去的话,显然没有控制好变量吧?
    ngv2
        49
    ngv2  
       Sep 3, 2022
    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
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   927 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 162ms · UTC 19:13 · PVG 03:13 · LAX 12:13 · JFK 15:13
    ♥ Do have faith in what you're doing.