tcp缓存引起的日志丢失

这篇具有很好参考价值的文章主要介绍了tcp缓存引起的日志丢失。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

logstash从数据源拉取日志,然后通过tcp插件发送到proxy进程中。在业务侧发现日志量明显少了,所以有了这一次的问题排查。

tcp缓存引起的日志丢失,计算机网络,go,logstash,tcp/ip,缓存,网络协议

问题排查定位

首先从logstash侧开始检查。我们先看logstash的日志,没有明显的报错信息。

然后再查看logstash管道的状态。可以很明显的看到,在output管道中,in远远大于out,也就是logstash拉取的日志已经到了output管道,但是无法输出出去,并且duration_in_millis时间很长,这个代表着发出去的速率很慢,这是什么原因呢?

curl -XGET 'localhost:9600/_node/stats/pipelines/azure_event_hubs?pretty'

{
    ...
"outputs" : [ {
        "id" : "99b12e190d297be5d6113d04cf10089a3dccbaef7eed0cc41515e8e5af5f4595",
        "name" : "tcp",
        "events" : {
        "in" : 341,
        "out" : 69,
        "duration_in_millis" : 519709
        }
    } 
}

要么是发送方的原因,要么是接收方的原因。我先从发送方进行排查,我在output管道中,除了tcp插件外,还添加了stdout插件,也就是日志来了除了会通过tcp发送外,还会打印在标准输出中。

output {

    tcp {
        ...
    }

    stdout {}

}

然后等待一段时间,然后再查看该管道的信息,stdout插件的in和out完全相等,但tcp插件in和out还是相差甚大,也就是output管道应该没问题。

我再假设proxy端有问题。日志是可以从logstash端发送到proxy端的,只是很慢,并且还有其他数据源也在往proxy端发送日志,也没有这个问题,所以我突然想到,该数据源的日志很大,会不会是这个原因导致的呢?

我从上面标准输出中抓了一条日志出来,134k大小,然后我手动的用nc命令将日志发送到proxy,因为日志很大,我是将日志写入到文件,然后再用管道的方式发送的

cat test.txt | nc 

通过查看proxy的日志发现,其根本没有收到该条日志。那么问题原因找到了,就是因为日志太大,导致日志发生了丢失。

代码排查

proxy服务的是golang写的,通过查看代码,这里使用了bufio.NewScanner来循环读取连接中的数据。

	scanner := bufio.NewScanner(conn)

	for scanner.Scan() {
		// 处理数据
		msg := scanner.Text()
        ...

查看NewScanner方法可以看到有一个maxTokenSize参数,然后用的默认值MaxScanTokenSize

func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        ScanLines,
		maxTokenSize: MaxScanTokenSize,
	}
}

再跳转,有一个初始化缓存大小startBufSize为4k和最大的缓存大小MaxScanTokenSize为64k。但是我们的日志大小为134k,已经大于最大大小了,所以无法接收到该日志,也就是因为这个原因导致了日志发生了丢失。

const (
	MaxScanTokenSize = 64 * 1024

	startBufSize = 4096
)

我们再看下Scan方法,有一段代码如下,如果拿到的数据的大小大于maxTokenSize,则会使用s.setErr(ErrTooLong)记录错误,然后返回false


func (s *Scanner) Scan() bool {

    ..
    const maxInt = int(^uint(0) >> 1)
    if len(s.buf) >= s.maxTokenSize || len(s.buf) > maxInt/2 {
        s.setErr(ErrTooLong)
        return false
    }
    newSize := len(s.buf) * 2
    if newSize == 0 {
        newSize = startBufSize
    }
    if newSize > s.maxTokenSize {
        newSize = s.maxTokenSize
    }
    newBuf := make([]byte, newSize)
    copy(newBuf, s.buf[s.start:s.end])
    ...

}

但是我们在业务代码中,并没有判断该错误,也就是如果Scan方法虽然返回了false,循环结束了,但是并没有任何错误信息。也就是无法发现该问题。

解决方法

  1. 将TCP的最大缓存大小修改为配置文件可配置的,这样如果日志很大,可以修改配置增大缓存上限。库中有提供Buffer方法来设置该上限。

  2. 在Scan发生错误时,打印错误日志,代码如下:


scanner := bufio.NewScanner(conn)

for scanner.Scan() {
    // 处理数据
    msg := scanner.Text()
    ...

if err := scanner.Err(); err != nil {
    log.Errorf("扫描输入时发生错误:%s", err)
}

总结

  1. 要提高自己的排查的手段,熟悉组件提供的排查机制,让你事半功倍。
  2. 每一个提供的参数都至关重要,所以我们都需要有一定的理解,可以减少BUG的发生

欢迎关注,互相学习,共同进步~

我的个人博客
公众号:编程黑洞文章来源地址https://www.toymoban.com/news/detail-820379.html

到了这里,关于tcp缓存引起的日志丢失的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机网络-TCP协议

    TCP被称为面向连接的,因为在应用程序开始互传数据之前,TCP会先建立一个连接,该连接的建立涉及到 三次“握手 ”。 TCP的连接不是一条真实存在的电路,而是一条逻辑链接 ,其共同状态仅保留在两个通信端系统的TCP程序中。 TCP连接也是点对点的,即TCP连接只能存在于一

    2024年02月08日
    浏览(40)
  • 【计算机网络】TCP协议详解

    目录 1. TCP协议头部格式 2. TCP协议原理  2.1 可靠传输机制 2.1.1 确认应答机制 2.1.2 超时重传机制 2.1.3 连接管理机制(三次握手,四次挥手) 2.1.4 流量控制 2.1.5 拥塞控制  2.2 效率机制  2.2.1 滑动窗口  2.2.2 延迟应答  2.2.3 捎带应答  3. 粘包问题  4. TCP的异常情况  5. TCP协议特

    2024年01月18日
    浏览(34)
  • 05.计算机网络——TCP协议

    TCP协议——TCP全称为 “ 传输控制协议 (Transmission Control Protocol)”,对数据的传输进行一个详细的控制。 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去; 32位序号/32位确认号: 用来支持确认应答和按序到达 4位TCP报头长度: 表示该TCP报头有多少个4字节大小; 6位标志位

    2024年02月16日
    浏览(36)
  • 【计算机网络篇】TCP协议

    ✅作者简介:大家好,我是小杨 📃个人主页:「小杨」的csdn博客 🐳希望大家多多支持🥰一起进步呀! TCP(Transmission Control Protocol)是一种在计算机网络中广泛使用的传输层协议,用于在网络上可靠地传输数据。 TCP 提供了可靠的、面向连接的通信,并负责数据的划分、排

    2024年02月11日
    浏览(33)
  • 【计算机网络笔记】Web缓存/代理服务器技术

    什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)——时延带宽积、丢包率、吞吐量/率 计算机网络体系结构概念 OSI参考模型

    2024年02月08日
    浏览(35)
  • 【计算机网络】UDP/TCP协议

    我们先来看一张图; 在研究UDP前我们先来回答两个问题: 有效载荷如何与报头分离? 如何将有效载荷交付? 第一个问题由于在报头里面有16位UDP长度(表示的是有效载荷+报头长度),而报头长度8字节是固定的,所以分离时我们只需要用整个报文的大小减去固定的8字节报头数据即

    2024年02月08日
    浏览(51)
  • 计算机网络:传输层(TCP详解)

    TCP报文段结构、可靠数据传输、TCP连接管理(三次握手、四次挥手)、拥塞控制。 点对点: —个发送方,一个接收方 可靠的、按顺序的字节流: 没有报文边界 管道化(流水线): TCP拥塞控制和流量控制设置窗口大小 发送和接收缓存 全双工数据: 在同一连接中数据流双向

    2024年02月04日
    浏览(39)
  • 【计算机网络】UDP/TCP 协议

    端口号(Port)标识了一个主机上进行通信的不同的应用程序。在 TCP/IP 协议中, 用 “源IP”, “源端口号”, “目的IP”, “目的端口号”, “协议号” 这样一个五元组来标识一个通信(可以通过netstat -n查看)。 0 - 1023: 知名端口号,HTTP, FTP, SSH 等这些广为使用的应用层协议,它们的

    2024年03月14日
    浏览(47)
  • 【计算机网络-传输层】TCP 协议

    端到端通信 :提供应用进程间的端到端通信(逻辑通信)。因此传输层又称为端到端协议。 差错检测 :对首部和数据部分进行检测。 两种协议 :面向连接的 TCP、无连接的 UDP。 复用和分用 : 概念 解释 传输层 TCP 复用 发送方的部分应用进程的报文在传输层使用 TCP 协议进

    2023年04月13日
    浏览(37)
  • 【计算机网络】TCP|IP协议

    目录 前言 什么是TCP/IP协议? TCP/IP协议的层次结构 TCP/IP协议的工作原理 TCP/IP协议的重要性 结语   TCP/IP协议是当今互联网世界中最重要的网络协议之一,它是网络通信的基石,为数据在网络中的传输提供了可靠性和有效性。本文将深入探讨TCP/IP协议的重要性、基本原理以及其

    2024年02月03日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包