我有一个非常奇怪的问题,我无法解决。
多年来我一直在构建节点/快速应用程序,并且通常在家里运行开发服务器以进行快速调试/测试。我在前端使用 haproxy 实例,使其“像生产一样”并执行 ssl 部分。
无论如何,就在最近,所有服务器(不同的项目)都开始出现行为异常,并在启动后大约 5 分钟停止响应请求。这就是我有时在这台机器上运行的所有 3 或 4 个实例,但完全相同的 haproxy 实例在代码的生产版本的前端,并且没有任何问题,它仍然坚如磐石。而且,令人气愤的是,我写了一个非常基本的 Express 服务器示例,如果它的前端是同一个 haproxy,它也会锁定,但如果我切换端口,它会按预期永远运行良好!
总结一下:
1x haproxy 实例前端一堆具有相同规则集的 prod/dev 实例,全部使用 ssl。 2x 生产实例运行良好 4x 开发实例(和一个简单的测试程序)在 haproxy 后面大约 5 分钟后全部锁定 如果我在不同的端口上运行简单的测试程序(因此它只是本地网络),它就可以完美运行。
我还对 haproxy 进行了正常运行时间机器人活跃度检查,以监控实例。
所以这个例子:
const express = require('express')
const request = require('request');
const app = express()
const port = 1234
var counter = 0;
var received = 0;
process.on('warning', e => console.warn(e.stack));
const started = new Date();
if (process.pid) {
console.log('Starting as pid ' + process.pid);
}
app.get('/', (req, res) => {
res.send('Hello World!').end();
})
app.get('/livenessCheck', (req, res) => {
res.send('ok').end();
})
app.use((req, res, next) => {
console.log('unknown', { host: req.headers.host, url: req.url });
res.send('ok').end();
})
const server = app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
app.keepAliveTimeout = (5 * 1000) + 1000;
app.headersTimeout = (6 * 1000) + 2000;
setInterval(() => {
server.getConnections(function(error, count) {
console.log('connections', count);
});
//console.log('tick', new Date())
}, 500);
setInterval(() => {
console.log('request', new Date())
request('http://localhost:' + port, function (error, response, body) {
if (error) {
const ended = new Date();
console.error('request error:', ended, error); // Print the error if one occurred
counter = counter - 1;
if (counter < 0) {
console.error('started ', started); // Print the error if one occurred
const diff = Math.floor((ended - started) / 1000)
const min = Math.floor(diff / 60);
console.error('elapsed ', min, 'min ', diff - min*60, 'sec');
exit;
}
return;
}
received = received + 1;
console.log('request ', received, 'statusCode:', new Date(), response && response.statusCode); // Print the response status code if a response was received
//console.log('body:', body); // Print the HTML for the Google homepage.
});
}, 1000);
在非 haproxy 端口上完美运行并永远运行,但在 haproxy 后面的端口上仅运行约 5 分钟,通常每次都会收到 277 个请求响应,然后挂起并超时。
“exit()”函数只是为了测试而强制崩溃。
我尝试调整 haproxy 上的一些超时,但无济于事。并且每一个都不会影响生产实例,使其保持正常工作。
我在具有最新操作系统的 mac pro 2013 上运行这些开发版本。并尝试了各种版本的节点。
有什么想法或者如何进一步调试吗?
哦,它们都服务器 Web 套接字以及 http 请求。
这是我正在尝试的 haproxy 配置的一个示例(相关部分):
global
log 127.0.0.1 local2
...
nbproc 1
daemon
defaults
mode http
log global
option httplog
option dontlognull
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 4s
timeout server 5s
timeout http-keep-alive 4s
timeout check 4s
timeout tunnel 1h
maxconn 3000
frontend wwws
bind *:443 ssl crt /etc/haproxy/certs/ no-sslv3
option http-server-close
option forwardfor
reqadd X-Forwarded-Proto:\ https
reqadd X-Forwarded-Port:\ 443
http-request set-header X-Client-IP %[src]
# set HTTP Strict Transport Security (HTST) header
rspadd Strict-Transport-Security:\ max-age=15768000
acl host_working hdr_beg(host) -i working.
use_backend Working if host_working
default_backend BrokenOnMac
backend Working
balance roundrobin
server working_1 1.2.3.4:8456 check
backend BrokenOnMac
balance roundrobin
server broken_1 2.3.4.5:8456 check
因此,如果您访问 https://working.blahblah.blah 它会永远有效,但是 https://broken.blahblah.blah 的后端会锁定并在 5 分钟后停止响应(包括绕过直接的卷曲请求) haproxy)。
但是如果我在不同的端口上运行完全相同的代码,它会永远响应任何直接的curl请求。
正在运行的“生产”服务器位于 Centos 等各种操作系统上。我在我的 Mac Pro 上运行了测试。测试代码在 Mac 上运行,端口不是由 haproxy 前端的。同样的测试代码在Mac上前面有haproxy的情况下5分钟后就挂掉了
所以失败的精确配置是: Mac Pro + 任何 Node Express 应用程序 + 由 haproxy 前端。
如果我更改任何内容,例如在 Centos 上运行代码或确保没有 haproxy,那么代码可以完美运行。
鉴于它最近才停止工作,那么它是否是 OSX Monterey (12.6) 的最新补丁,当它从 haproxy 获取特定条件时,可能会以某种方式干扰应用程序套接字?看起来不太可能,但我能想到的最合乎逻辑的解释。
发现问题,忘了回答。抱歉耽搁了。
对于遇到类似情况的其他人来说,我的开发计算机上的 AV 代理已经启动并关闭了“恶意端口”。我没有时间进行根本原因分析,但修复了它。
🤦