“search1”是AWS弹性搜索服务 . 它有一个访问策略,只允许来自所选IP地址的流量 . 我的理解是AWS在VPC面前将其实现为ELB,我无法访问 .
"esproxy"是AWS EC2实例,用作search1的代理 . 在esproxy上, nginx
配置为要求(https)基本身份验证,并且任何具有该身份验证的内容都会被代理到search1 .
有用 . 一段时间,几小时或一天 . 然后每个请求开始给出"504 Gateway Time-out"错误 . nginx
仍然立即响应以发出401 auth所需的错误,但是使用auth需要两分钟才能恢复超时 . 当发生这种情况并重新启动 nginx
时,这两方似乎都没有太多负载 . 实际上,通过代理的流量并不重,每天点击几千次 .
试图理解这个问题,我尝试使用 openssl
,如 telnet
:
openssl s_client -connect search1:443
[many ssl headers including certs shown rapidly]
GET / HTTP/1.1
Host: search1
HTTP/1.1 408 REQUEST_TIMEOUT
Content-Length:0
Connection: Close
这个408超时需要大约一分钟才能回到我身边 . Aha ,我想, this particular server is having issuses. 然后我尝试了另一台主机的 openssl
测试 . 同样的延迟 .
然后我想我自己, hey, curl works to test https, too, now that I know the ssl layer is snappy. 好吧, curl
访问工作,即使 nginx
和 openssl
同时从esproxy超时 .
所以我想, maybe something about the headers? curl has different headers than I'm typing into openssl.
我修改了一个低级别的http / https工具,让我轻松发送特定的 Headers . 我发现它似乎没有缺少或额外的 Headers ,但行结尾 . nginx
(和 apache
)不关心你是否使用DOS样式的行结尾(对HTTP规范正确)或Unix样式(不正确) . search1实例(弹性搜索本身或ELB)显然非常关心 .
在不了解 nginx
的情况下,我有以下几个问题:
-
我的代理超时源是否是一堆现有的连接遇到了错误的请求行结尾?
-
我该怎么说?
-
可能不是因为超时不同(一到两分钟) .
-
默认情况下
nginx
代理请求的行结尾是否正确? -
如果没有,可以强迫吗?
-
AND if the line endings is a red herring ,我怎么能得到
nginx
来帮助我解决这个问题?我在日志中看到的只是"upstream timed out (110: Connection timed out) while reading response header from upstream",这并没有提高我对该问题的理解 .
我在调试中发现了这个问题:nginx close upstream connection after request我已经修复了 nginx
conf以使用1.1代理,如前所述 . 相关配置:
upstream search1 {
server search1-abcdefghijklmnopqrstuvwxyz.us-east-1.es.amazonaws.com:443;
# number of connections to keep alive, not time
keepalive 64;
}
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host "search1-abcdefghijklmnopqrstuvwxyz.us-east-1.es.amazonaws.com"
# must supress auth header from being forwarded
proxy_set_header Authorization "";
# allow keep-alives on proxied connections
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass https://search1;
}