Ver Fonte

Merge pull request #2364 from nginx-proxy/keepalive

feat: keepalive auto setting
Nicolas Duchon há 1 ano atrás
pai
commit
6f042854e1
4 ficheiros alterados com 39 adições e 9 exclusões
  1. 3 1
      docs/README.md
  2. 12 8
      nginx.tmpl
  3. 11 0
      test/test_keepalive.py
  4. 13 0
      test/test_keepalive.yml

+ 3 - 1
docs/README.md

@@ -520,7 +520,9 @@ services:
 > **Warning**
 > This feature is experimental.  The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version.  If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2194](https://github.com/nginx-proxy/nginx-proxy/discussions/2194).  Once we have collected enough feedback we will promote this feature to officially supported.
 
-To enable HTTP keep-alive between `nginx-proxy` and a backend server, set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container to the desired maximum number of idle connections. See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details.
+To enable HTTP keep-alive between `nginx-proxy` and backend server(s), set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container either to `auto` or to the desired maximum number of idle connections. The `auto` setting will dynamically set the maximum number of idle connections to twice the number of servers listed in the corresponding `upstream{}` block, [per nginx recommendation](https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#no-keepalives).
+
+See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details.
 
 ### Headers
 

+ 12 - 8
nginx.tmpl

@@ -249,7 +249,7 @@
     {{- if exists $override }}
     include {{ $override }};
     {{- else }}
-        {{- $keepalive := first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive")) }}
+        {{- $keepalive := coalesce (first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive"))) "disabled" }}
     location {{ .Path }} {
         {{- if eq .NetworkTag "internal" }}
         # Only allow traffic from internal clients
@@ -263,14 +263,14 @@
         root {{ trim .VhostRoot }};
         include fastcgi_params;
         fastcgi_pass {{ trim .Upstream }};
-            {{- if $keepalive }}
+            {{- if ne $keepalive "disabled" }}
         fastcgi_keep_conn on;
             {{- end }}
         {{- else if eq .Proto "grpc" }}
         grpc_pass {{ trim .Proto }}://{{ trim .Upstream }};
         {{- else }}
         proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}{{ trim .Dest }};
-        set $upstream_keepalive {{ if $keepalive }}true{{ else }}false{{ end }};
+        set $upstream_keepalive {{ if ne $keepalive "disabled" }}true{{ else }}false{{ end }};
         {{- end }}
 
         {{- if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }}
@@ -291,7 +291,7 @@
 
 {{- define "upstream" }}
 upstream {{ .Upstream }} {
-    {{- $server_found := false }}
+    {{- $servers := 0 }}
     {{- $loadbalance := first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.loadbalance")) }}
     {{- if $loadbalance }}
     # From the container's loadbalance label:
@@ -306,18 +306,22 @@ upstream {{ .Upstream }} {
         {{- template "container_port" $args }}
         {{- $port := $args.port }}
         {{- if $ip }}
-            {{- $server_found = true }}
+            {{- $servers = add1 $servers }}
     server {{ $ip }}:{{ $port }};
         {{- end }}
     {{- end }}
     {{- /* nginx-proxy/nginx-proxy#1105 */}}
-    {{- if not $server_found }}
+    {{- if lt $servers 1 }}
     # Fallback entry
     server 127.0.0.1 down;
     {{- end }}
-    {{- $keepalive := first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive")) }}
-    {{- if $keepalive }}
+    {{- $keepalive := coalesce (first (keys (groupByLabel .Containers "com.github.nginx-proxy.nginx-proxy.keepalive"))) "disabled" }}
+    {{- if and (ne $keepalive "disabled") (gt $servers 0) }}
+        {{- if eq $keepalive "auto" }}
+    keepalive {{ mul $servers 2 }};
+        {{- else }}
     keepalive {{ $keepalive }};
+        {{- end }}
     {{- end }}
 }
 {{- end }}

+ 11 - 0
test/test_keepalive.py

@@ -20,10 +20,21 @@ def test_keepalive_disabled_other_headers_ok(docker_compose, nginxproxy):
     assert re.search(fr'(?m)^(?i:X-Real-IP): ', r.text)
 
 def test_keepalive_enabled(docker_compose, nginxproxy):
+    conf = nginxproxy.get_conf().decode('ASCII')
+    assert re.search(r"keepalive 64\;", conf)
+
     r = nginxproxy.get("http://keepalive-enabled.nginx-proxy.test/headers")
     assert r.status_code == 200
     assert not re.search(fr'(?m)^(?i:Connection):', r.text)
 
+def test_keepalive_auto_enabled(docker_compose, nginxproxy):
+    conf = nginxproxy.get_conf().decode('ASCII')
+    assert re.search(r"keepalive 8\;", conf)
+
+    r = nginxproxy.get("http://keepalive-auto.nginx-proxy.test/headers")
+    assert r.status_code == 200
+    assert not re.search(fr'(?m)^(?i:Connection):', r.text)
+
 def test_keepalive_enabled_other_headers_ok(docker_compose, nginxproxy):
     """See the docstring for the disabled case above."""
     r = nginxproxy.get("http://keepalive-enabled.nginx-proxy.test/headers")

+ 13 - 0
test/test_keepalive.yml

@@ -18,6 +18,19 @@ services:
       VIRTUAL_HOST: keepalive-enabled.nginx-proxy.test
     labels:
       com.github.nginx-proxy.nginx-proxy.keepalive: "64"
+  
+  keepalive-auto:
+    image: web
+    deploy:
+      mode: replicated
+      replicas: 4
+    expose:
+      - "80"
+    environment:
+      WEB_PORTS: 80
+      VIRTUAL_HOST: keepalive-auto.nginx-proxy.test
+    labels:
+      com.github.nginx-proxy.nginx-proxy.keepalive: "auto"
 
   sut:
     image: nginxproxy/nginx-proxy:test