我们在一台服务器上运行 Logstash,该服务器正在将日志推送到 Elasticsearch 集群。在 Logstash 日志中,我们看到它与 Elasticsearch 服务器失去连接,并出现连接重置错误。我们在所有服务器上的所有 logstash 和 elasticsearch 实例之间都看到了这种情况。在此示例中,我们看到 logstash3 (192.168.1.133) 与 elasticsearch4 (192.168.1.88) 失去连接
[2018-08-21T20:21:21,414][WARN ][logstash.outputs.elasticsearch] Marking url as dead. Last error: [LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError] Elasticsearch Unreachable: [http://elasticsearch4:9200/][Manticore::SocketException] Connection reset {:url=>http://elasticsearch4:9200/, :error_message=>"Elasticsearch Unreachable: [http://elasticsearch4:9200/][Manticore::SocketException] Connection reset", :error_class=>"LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError"}
查看系统日志,我们可以看到 UFW 在几秒钟前阻止了一个数据包:
Aug 21 20:21:03 logstash3 kernel: [1760565.386970] [UFW BLOCK] IN=enp0s31f6 OUT= MAC=90:1b:0e:cc:50:95:30:b6:4f:d8:05:51:08:00 SRC=192.168.1.88 DST=192.168.1.133 LEN=40 TOS=0x0 PREC=0x00 TTL=57 ID=442 DF PROTO=TCP SPT=9200 DPT=59338 WINDOW=0 RES=0x00 RST URGP=0
我们在 ufw 中制定了一条规则,允许这些服务器之间的所有连接。最初我们只允许特定端口,但我将其开放到所有端口,以防出现问题。允许连接的规则是:
logstash3:~$ sudo ufw status | grep '\.88'
Anywhere ALLOW 192.168.1.88
如果我们重新启动 logstash,这些断开的连接会暂时消失(约 1 小时),但随后会开始重复出现。
因为我们看到这种情况在一段时间后开始发生,所以我倾向于认为这是队列在某处填满。连接并没有完全停止,我们只是偶尔开始丢失数据包。我认为这可能与连接跟踪有关,但我们没有看到任何与此相关的日志。我们conntrack_max
之前已经增加了,因为我们已经将其视为一个问题,但在这种情况下它没有帮助。
elasticsearch4:~$ cat /proc/sys/net/nf_conntrack_max
262144
未发现任何通用数据包丢失的证据:
logstash3:~$ ifconfig
enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.133 netmask 255.255.255.255 broadcast 0.0.0.0
inet6 2a01:4f8:121:53b7::2 prefixlen 64 scopeid 0x0<global>
inet6 fe80::921b:eff:fecc:5095 prefixlen 64 scopeid 0x20<link>
ether 90:1b:0e:cc:50:95 txqueuelen 1000 (Ethernet)
RX packets 7746452399 bytes 8566845158411 (8.5 TB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5792178105 bytes 5164493104253 (5.1 TB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 16 memory 0xef000000-ef020000
根据 @Lenniey 的建议,我尝试禁用 UFW,看看是否仍然在 logstash 日志中看到错误。我在许多服务器上禁用了 ufw,发现在Connection reset
禁用 ufw 的服务器之间,我们仍然在日志中收到消息,因此看来 syslog 中的 ufw 条目可能是一种症状,而不是原因。
sudo tcpdump -i enp0s31f6 -s 65535 -w logstash.pcap 'port 9200'
当我们看到错误时,我制作了一个数据包捕获( )
[2018-08-23T07:20:11,108][WARN ][logstash.outputs.elasticsearch] Marking url as dead. Last error: [LogStash::Outputs::ElasticSearch::
HttpClient::Pool::HostUnreachableError] Elasticsearch 无法访问:[http://elasticsearch3:9200/][Manticore::Socket 异常] 连接重置 {:url=>http://elasticsearch3:9200/, :error_message=>“Elasticsearch 无法访问:[http://elasticsearch3:9200/][Manticore::SocketException] 连接重置", :error_class=>“LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError”}
在数据包捕获中我可以看到 elasticsearch 响应 400 错误:
HTTP/1.0 400 Bad Request
content-type: application/json; charset=UTF-8
content-length: 203
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "text is empty (possibly HTTP/0.9)"
}
],
"type": "illegal_argument_exception",
"reason": "text is empty (possibly HTTP/0.9)"
},
"status": 400
}
然后我看到 5 个 TCP RST 数据包从 elasticsearch 发送到 logstash。最后一个 RST 数据包位于07:20:11.107663
,与 logstash 错误发生的时间 相符07:20:11,108
。
我发现数据包捕获有点令人困惑。我已将数据包捕获过滤到相关 logstash 和 ES 服务器的 IP,以及我们看到 400 和 RST 的端口,但在 400 之前似乎有一个_bulk
正在进行的请求,然后在请求期间在请求中间出现 414 响应_bulk
,然后_bulk
请求继续,然后我们得到 400:
Logstash -> ES
POST /_bulk HTTP/1.1
Connection: Keep-Alive
Content-Type: application/json
Content-Length: 167481062
Host: elasticsearch3.channelgrabber.com:9200
User-Agent: Manticore 0.6.1
Accept-Encoding: gzip,deflate
{ ... data ... }
ES -> Logstash
HTTP/1.1 413 Request Entity Too Large
content-length: 0
Logstash -> ES
{ ... data continues ... }
ES -> Logstash
HTTP/1.0 400 Bad Request
content-type: application/json; charset=UTF-8
content-length: 203
{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"text is empty (possibly HTTP/0.9)"}],"type":"illegal_argument_exception","reason":"text is empty (possibly HTTP/0.9)"},"status":400}
对于我还应该关注什么,还有什么建议吗?