压力大导致你的Logstash重发消息吗?

今天突然发现自己的ELKF传递给ES的数据都是重复的发,日志中明明只记录了一条但是ES中却有三条,很是疑惑。

  1. 首先怀疑filebeat,是不是filebeat重复发送导致logstash传递给ES的数据是重复的
    查看filebeat的日志是正常的,但是会出现断开连接,然后retry的日志,所以一开始我很怀疑是不是这里发送的重复消息给了logstash。于是我关闭了其他传递给logstash的filebeat(因为不关闭日志太多了,根本看不清哪个是我想测试的内容)。再次测试。发现我通output输出到终端的确是三条记录。

  2. 这个时候我很怀疑是不是filebeat的问题,因为的确看到了三条输出。但是3个数字很奇怪,因为我正好logstash有三个配置文件,所以在我看不出来filebeat究竟问题在哪的时候,我觉得先改下logstash的配置试一下。之前是直接启动读取的一个目录,目录下三个配置文件,这次先单独使用一个配置尝试一下,发现现在正常了。

  3. 这时候怀疑是不是Logstash的问题,然后百度查看,有的网友反馈说如果logstash的压力比较大的话,配置不够,的确可能会出现这个问题,他们说的都是400/s,虽然我的这个也是线上服务,但是目前只是属于半线上状态,很多日志都还没写到ES里面,也没有这么大的消息量,按道理应该是不会出现这个问题的.

  4. 如果不是压力的问题(因为我把之前其他服务的filebeat的服务都启动起来依旧没有问题)的话,那跟之前变化的地方就只有读取的配置文件这次是一个,之前是三个,分析了一下配置文件,发现没有问题(从单个文件的角度来看)。

  5. 然后我看一下logstash的日志文件(logstash-plain.log)发现里面有如下日志

[2021-07-06T20:14:20,608][ERROR][logstash.javapipeline    ][main][8cfd5614b6a882179cc50ba58a07b1e575992388c7f98d4af2c47bd657e40cd5] A plugin had an unrecoverable error. Will restart this plugin.
  Pipeline_id:main
  Plugin: <LogStash::Inputs::Beats port=>5044, id=>"8cfd5614b6a882179cc50ba58a07b1e575992388c7f98d4af2c47bd657e40cd5", enable_metric=>true, codec=><LogStash::Codecs::Plain id=>"plain_d28ef72f-5c31-4dd3-8a69-e55dfbfa602c", enable_metric=>true, charset=>"UTF-8">, host=>"0.0.0.0", ssl=>false, add_hostname=>false, ssl_verify_mode=>"none", ssl_peer_metadata=>false, include_codec_tag=>true, ssl_handshake_timeout=>10000, tls_min_version=>1, tls_max_version=>1.2, cipher_suites=>["TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"], client_inactivity_timeout=>60, executor_threads=>4>
  Error: Address already in use
  Exception: Java::JavaNet::BindException
  Stack: sun.nio.ch.Net.bind0(Native Method)
sun.nio.ch.Net.bind(sun/nio/ch/Net.java:455)
sun.nio.ch.Net.bind(sun/nio/ch/Net.java:447)
sun.nio.ch.ServerSocketChannelImpl.bind(sun/nio/ch/ServerSocketChannelImpl.java:227)
io.netty.channel.socket.nio.NioServerSocketChannel.doBind(io/netty/channel/socket/nio/NioServerSocketChannel.java:134)
io.netty.channel.AbstractChannel$AbstractUnsafe.bind(io/netty/channel/AbstractChannel.java:550)
io.netty.channel.DefaultChannelPipeline$HeadContext.bind(io/netty/channel/DefaultChannelPipeline.java:1334)
io.netty.channel.AbstractChannelHandlerContext.invokeBind(io/netty/channel/AbstractChannelHandlerContext.java:506)
io.netty.channel.AbstractChannelHandlerContext.bind(io/netty/channel/AbstractChannelHandlerContext.java:491)
io.netty.channel.DefaultChannelPipeline.bind(io/netty/channel/DefaultChannelPipeline.java:973)
io.netty.channel.AbstractChannel.bind(io/netty/channel/AbstractChannel.java:248)
io.netty.bootstrap.AbstractBootstrap$2.run(io/netty/bootstrap/AbstractBootstrap.java:356)
io.netty.util.concurrent.AbstractEventExecutor.safeExecute(io/netty/util/concurrent/AbstractEventExecutor.java:164)
io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(io/netty/util/concurrent/SingleThreadEventExecutor.java:472)
io.netty.channel.nio.NioEventLoop.run(io/netty/channel/nio/NioEventLoop.java:500)
io.netty.util.concurrent.SingleThreadEventExecutor$4.run(io/netty/util/concurrent/SingleThreadEventExecutor.java:989)
io.netty.util.internal.ThreadExecutorMap$2.run(io/netty/util/internal/ThreadExecutorMap.java:74)
io.netty.util.concurrent.FastThreadLocalRunnable.run(io/netty/util/concurrent/FastThreadLocalRunnable.java:30)
java.lang.Thread.run(java/lang/Thread.java:829)

从日志中可以很明显的看到 Error: Address already in use,然后百度查看,竟然说是端口冲突了,我这台服务器上也有没有其他服务,按道理说也不存在说端口冲突。
疑惑不解就百度,然后看到别人直接把5044端口的程序给结束了,那可能是他的端口的确被别的进程给占用了,但是我的情况明显不是这样。

然后我想着方便测试,我就指定的配置文件去启动的logstash,发现竟然问题都没人,记录也不重复记录了,logstash的报错也没了。
然后抱着试一试的心态,把三个配置文件中的input和output都放到了一个文件中,再次重启测试,果然全都好了。果然是一次很傻逼的问题,但是对于我这种新手东看一点西看一点,这样的问题的确浪费了我很多时间,记录一下,给我同样的小白避坑。

说明:
想让filbeat重新上传所有的日志

$ find / -name registry
/var/lib/filebeat/registry

找到目录之后,先停止filebeat,然后删除,最后启动filebeat

$ systemctl stop filebeat
$ rm -rf /var/lib/filebeat/registry
$ systemctl start filebeat
原文地址:https://www.cnblogs.com/xll970105/p/14980441.html