【问题标题】:varnish + nginx low throughput and hight response timevarnish + nginx 低吞吐量和高响应时间
【发布时间】:2022-01-04 02:57:05
【问题描述】:

我们有以下基于 openshift 的设置

nginx => varnish (2 pods) => web api nodejs

我通过 jmetr 在 60 秒内对一个 url 发出了 1000 个请求。 此 url 应由 varnish 缓存并快速处理所有请求,但结果如下:

所有请求都有来自响应标头的X-Cache: HIT_1,这意味着它们是由清漆处理的,

看起来有一些队列或其他东西……目前还不太明白

清漆配置:

vcl 4.0;

import std;
import bodyaccess;

backend freshproxy {
   .host = "fresh-proxy";
   .port = "3000";
}

sub vcl_recv {
  set req.backend_hint = freshproxy;
    if (req.method == "XCGFULLBAN") {
        ban("req.http.host ~ .*");
        return (synth(200, "Full cache cleared"));
    }

  if (req.method == "GET" && ! req.url ~ "varnish_no_cache") {
    if (req.url ~ "^/api/v1/tours/favorite" || req.url ~ "^/api/v1/products/favorite") {
        return (pass);
    }

    if (
      req.url ~ "^/api/v1/products" ||
      req.url ~ "^/api/v1/tours" ||
      req.url ~ "^/api/v1/farmers" ||
      req.url ~ "^/api/v1/stories" ||
      req.url ~ "^/api/v1/recipes" ||
      req.url ~ "^/api/v1/categories/farmers" ||
      req.url ~ "^/api/v1/categories/tours" ||
      req.url ~ "^/api/v1/categories/recipes"
    ) {
      return (hash);
    }
  }

  return (pass);
}

sub vcl_backend_response {
    # We first set TTLs for most of the content we need to cache
    set beresp.ttl = 30m;
    set beresp.grace = 30m;
}

sub vcl_hash {
    # To cache POST and PUT requests
    if (req.http.X-Body-Len) {
    bodyaccess.hash_req_body();
    } else {
    hash_data("");
    }
}

sub vcl_backend_fetch {
    if (bereq.http.X-Body-Len) {
    set bereq.method = "POST";
    }
}

sub vcl_deliver {
    if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT_1";
    set resp.http.X-Cache-Hits = obj.hits;
    } else {
    set resp.http.X-Cache = "MISS_1";
    }
    set resp.http.X-Cache-Expires = resp.http.Expires;
    unset resp.http.X-Varnish;
    unset resp.http.Via;
    unset resp.http.Age;
    unset resp.http.X-Purge-URL;
    unset resp.http.X-Purge-Host;
    # Remove ban-lurker friendly custom headers when delivering to client.
    unset resp.http.X-Url;
    unset resp.http.X-Host;
    # Comment these for easier Drupal cache tag debugging in development.
    unset resp.http.X-Cache-Tags;
    unset resp.http.X-Cache-Contexts;
    unset resp.http.X-Powered-By;
}

nginx 配置:

server {
        listen 80;
        server_name api.my-app.ru;

        include well-known.conf;

        location /robots.txt { return 200 "User-agent: *\nDisallow: /\n"; }

        location / {
                    return 301 https://$host$request_uri;
        }
}

server {
        listen 443 ssl http2;
        server_name api.my-app.ru;

#        auth_basic "Restricted";
#        auth_basic_user_file /etc/nginx/htpasswd;

        ssl_certificate /etc/nginx/certs/my-app.ru/my-app.ru.crt;
        ssl_certificate_key /etc/nginx/certs/my-app.ru/my-app.ru.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers On;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
        add_header Strict-Transport-Security max-age=15768000;
        ssl_stapling on;

        include gzip.conf;
        include location_deny.conf;
        fastcgi_param                   HTTPS on;
        # To allow POST on static pages
        error_page  405     =200 $uri;
        include well-known.conf;

        access_log  /var/log/nginx/api.my-app.ru_access.log  main;
        error_log  /var/log/nginx/api.my-app.ru_error.log;        


        location /robots.txt { return 200 "User-agent: *\nDisallow: /\n"; }

        location / {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_buffering off;
                proxy_pass http://openshift-prod;
                proxy_set_header Host $host;
                proxy_set_header realip $remote_addr;
                proxy_set_header X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-Proto https;
                proxy_set_header X-Forwarded-Port 443;
                proxy_set_header Ssl-Offloaded "https";
                proxy_set_header HTTPS "on";
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_read_timeout 1200;
                proxy_send_timeout 1200;
                proxy_connect_timeout 1200;

                ### SET GEOIP Variables ###
                proxy_set_header country $geoip_city_country_code;
                proxy_set_header region $geoip_region;
                proxy_set_header city $geoip_city;
                proxy_set_header postal $geoip_postal_code;

                proxy_set_header  X-City     $city;
                proxy_set_header  X-Country  $country;
                proxy_set_header  X-Region   $region;

                rewrite ^/pwa.html$ / permanent;
        }

        location /api {
                auth_basic off;
                proxy_buffering off;
                proxy_pass http://openshift-prod;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_read_timeout 1200;
                proxy_send_timeout 1200;
                proxy_connect_timeout 1200;
        }

        location /img {
                auth_basic off;
                proxy_buffering off;
                proxy_pass http://openshift-prod;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_read_timeout 1200;
                proxy_send_timeout 1200;
                proxy_connect_timeout 1200;
        }
}

【问题讨论】:

    标签: nginx varnish varnish-vcl


    【解决方案1】:

    通过varnishlog,我们可以检查单个请求、它们在有限状态机中的内部行为及其时间。

    您始终可以运行以下命令:

    sudo varnishlog -g request
    

    这会吐出非常冗长的内容。这一切都很有用,但在实时系统上可能会不堪重负。

    这就是为什么我建议使用以下命令:

    sudo varnishlog -c -g request -i requrl -i vcl_call -i vcl_return -i timestamp
    

    此命令仅列出以下字段:

    • 请求 URL (requrl)
    • 有限状态机的各种状态 (vcl_call)
    • 转换到下一个 FSM 状态 (vcl_return)
    • 交易流程中各个点的时间戳 (timestamp)

    这是缓存未命中的一些输出:

    *   << Request  >> 13290606
    -   Timestamp      Start: 1637911747.472568 0.000000 0.000000
    -   Timestamp      Req: 1637911747.472568 0.000000 0.000000
    -   ReqURL         /
    -   VCL_call       RECV
    -   VCL_return     hash
    -   VCL_call       HASH
    -   VCL_return     lookup
    -   VCL_call       MISS
    -   VCL_return     fetch
    -   Timestamp      Fetch: 1637911747.582202 0.109634 0.109634
    -   VCL_call       DELIVER
    -   VCL_return     deliver
    -   Timestamp      Process: 1637911747.582226 0.109658 0.000023
    -   Timestamp      Resp: 1637911747.582427 0.109859 0.000201
    

    此日志事务针对主页 (/),导致缓存未命中。总交易时间(Timestamp Resp 表示为 0.109859 秒。

    之所以花费这么多时间是因为后端提取(由Timestamp Fetch 表示)花费了0.109634 秒。

    这是缓存命中

    的输出
    *   << Request  >> 13290626
    -   Timestamp      Start: 1637911786.334841 0.000000 0.000000
    -   Timestamp      Req: 1637911786.334841 0.000000 0.000000
    -   ReqURL         /
    -   VCL_call       RECV
    -   VCL_return     hash
    -   VCL_call       HASH
    -   VCL_return     lookup
    -   VCL_call       HIT
    -   VCL_return     deliver
    -   VCL_call       DELIVER
    -   VCL_return     deliver
    -   Timestamp      Process: 1637911786.334933 0.000091 0.000091
    -   Timestamp      Resp: 1637911786.334954 0.000113 0.000022
    

    如您所见,没有获取,因为对象存储在缓存中。 Timestamp Resp 标记告诉使用 Varnish 中的总响应时间是 0.000113 秒。

    一旦您确定了哪些端点速度较慢,我们可以在日志事务中包含更多信息以找出速度较慢的原因。

    这是一个varnishlog 命令,用于过滤特定 URL(在本例中为 /):

    varnishlog -g request -q "ReqUrl eq '/'"
    

    如果您发现某个特定交易太慢,请将完整交易添加到您的问题中,我会帮助您找出原因。

    【讨论】:

    • 我知道清漆的响应取决于后端获取时间,但我做了 1k 完全相同的请求,正如我在后端日志上看到的那样 - 我的背部只收到了 3 个请求,reamings 请求由清漆处理我不明白共振时间范围从300到5000ms的原因
    • @Ilya 收集一些日志事务,将它们粘贴到您的问题中,我们将一起解决。请确保添加完整的交易,因为我们需要的不仅仅是 Timestamp 字段来弄清楚发生了什么。请将您的 varnishd 运行时参数添加到问题中,以便我们知道您是如何配置 Varnish 的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    相关资源
    最近更新 更多