首页 > 解决方案 > 通过 Unix 域套接字连接 Nginx 和 Varnish 6 不起作用

问题描述

我在同一台机器上的 Varnish 6 前面使用 Nginx 作为 SSL 端点。这在使用 TCP 端口时效果很好。由于 Varnish 6 支持监听 Unix 域套接字,我将配置更改为使用套接字:

重新启动 Nginx 和 Varnish,没有显示错误。套接字文件 /var/run/varnish.sock 被创建并且是世界可写的(我知道,我知道......我只是想让它运行)。Netstat 说 varnishd 正在监听 /var/run/varnish.sock。

但它不起作用,对 nginx 的任何 Web 请求都会返回“502 Bad Gateway”。

Nginx 错误日志显示“从上游读取响应标头时上游过早关闭连接”。

Varnishlog 为每个请求显示如下条目:

*   << Session  >> 65578
-   Begin          sess 0 PROXY
-   SessOpen       0.0.0.0 0 a0 0.0.0.0 0 1557937009.691636 21
-   SessClose      RX_JUNK 0.000
-   End

知道出了什么问题吗?

Varnish 是 varnish-6.0.3 修订版 7d1ded3aa033a018317dbafc61587026ea2ef8a3,Nginx 是 nginx/1.14.0 (Ubuntu),在 Ubuntu 18.04 Bionic 上运行

标签: nginxvarnishunix-socket

解决方案


您让 Varnish 使用 PROXY 协议进行侦听,但 NGINX 正在与常规 HTTP 协议通信。因此它失败了。

准确地说,-a /var/run/varnish.sock,PROXY,user=varnish,group=varnish,mode=666是指 Varnish 监听 UDS 套接字,接受 PROXY 协议。没有什么神奇的开关可以让它同时接受常规的 HTTP 和 PROXY 协议。

在一个完美的世界中,您将有一种方法让 NGINX 将代理协议转发(对话)到 Varnish。但是你不能proxy_passhttp {}上下文中做到这一点。您可以在 NGINX 流中执行proxy_pass+ proxy_protocol,但这通常不是您想要的,因为这会破坏 HTTP/2 并将其降级为旧协议。

请务必阅读UDS 堆栈概念。具体来说,它提到了为什么 NGINX 不是 UDS 设置中 TLS 终止的错误选择:

NGINX 无法通过 http 代理模块转发 PROXY 协议。这意味着 server { proxy_pass .... } TLS 终止到侦听 PROXY 协议的 Varnish 将不起作用。

nginx SSL 流 + Varnish 监听 PROXY 协议将不支持 HTTP/2,因为 nginx SSL 流不知道如何协商 ALPN proto。


推荐阅读