首页 > 其他分享 >Go每日一库之157:tproxy (TCP连接代理与分析 )

Go每日一库之157:tproxy (TCP连接代理与分析 )

时间:2023-10-01 09:02:36浏览次数:45  
标签:tproxy 请求 157 gRPC TCP MySQL go 连接

你有同感吗?

当大家在开发服务端代码的时候,会不会经常有如下疑问?

  • 纳闷 MySQL 连接池到底有多少连接?
  • 每个连接的生命周期持续多久?
  • 连接异常断开的时候到底是服务端主动断的,还是客户端主动断的?
  • 当长时间没有请求的时候,底层库是否有 KeepAlive 请求?

复杂网络情况的处理从来都是后端开发的重点和难点之一,你是不是也为各种网络情况的调试而头顶发凉呢?

所以我写了 tproxy

当我在做后端开发的时候,经常会需要监控网络连接,分析请求内容。比如:

  • 分析 gRPC 连接何时连接、何时重连,并据此调整各种参数,比如:MaxConnectionIdle
  • 分析 MySQL 连接池,当前多少连接,连接的生命周期是什么策略
  • 也可以用来观察和分析任何 TCP 连接,看服务端主动断,还是客户端主动断等等

tproxy 的安装

$ GOPROXY=https://goproxy.cn/,direct go install github.com/kevwan/tproxy@latest

或者使用 docker 镜像:

$ docker run --rm -it -p <listen-port>:<listen-port> -p <remote-port>:<remote-port> kevinwan/tproxy:v1 tproxy -l 0.0.0.0 -p <listen-port> -r host.docker.internal:<remote-port>

arm64 系统:

$ docker run --rm -it -p <listen-port>:<listen-port> -p <remote-port>:<remote-port> kevinwan/tproxy:v1-arm64 tproxy -l 0.0.0.0 -p <listen-port> -r host.docker.internal:<remote-port>

tproxy 的用法

$ tproxy --helpUsage of tproxy:  -d duration            the delay to relay packets  -l string            Local address to listen on (default "localhost")  -p int            Local port to listen on  -q        Quiet mode, only prints connection open/close and stats, default false  -r string            Remote address (host:port) to connect  -t string            The type of protocol, currently support grpc

分析 gRPC 连接

tproxy -p 8088 -r localhost:8081 -t grpc -d 100ms
  • 侦听在 localhost 和 8088 端口
  • 重定向请求到 localhost:8081
  • 识别数据包格式为 gRPC
  • 数据包延迟100毫秒

img

其中我们可以看到 gRPC 的一个请求的初始化和来回,可以看到第一个请求其中的 stream id 为 1。

再比如 gRPC 有个 MaxConnectionIdle 参数,用来设置 idle 多久该连接会被关闭,我们可以直接观察到时间到了之后服务端会发送一个 http2 的 GoAway 包。

img

比如我把 MaxConnectioinIdle 设为 5 分钟,连接成功之后 5 分钟没有请求,连接就被自动关闭了,然后重新建了一个连接上来。

分析 MySQL 连接

我们来分析一下 MySQL 连接池设置对连接池的影响,比如我把参数设为:

maxIdleConns = 3maxOpenConns = 8maxLifetime  = time.Minute...conn.SetMaxIdleConns(maxIdleConns)conn.SetMaxOpenConns(maxOpenConns)conn.SetConnMaxLifetime(maxLifetime)

我们把 MaxIdleConns 和 MaxOpenConns 设为不同值,然后我们用 hey 来做个压测:

hey -c 10 -z 10s "http://localhost:8888/lookup?url=go-zero.dev"

我们做了并发为10QPS且持续10秒钟的压测,连接结果如下图:

img

我们可以看到:

  • 10秒钟内建立了2000+的连接
  • 过程中在不停的关闭已有连接,重开新的连接
  • 每次连接使用完放回去,可能超过 MaxIdleConns 了,然后这个连接就会被关闭
  • 接着来新请求去拿连接时,发现连接数小于 MaxOpenConns,但是没有可用请求了,所以就又新建了连接

这也就是我们经常会看到 MySQL 很多 TIME_WAIT 的原因。

然后我们把 MaxIdleConns 和 MaxOpenConns 设为相同值,然后再来做一次相同的压测:

img

我们可以看到:

  • 一直维持着8个连接不变
  • 压测完过了一分钟(ConnMaxLifetime),所有连接被关闭了

这里的 ConnMaxLifetime 一定要设置的小于 wait_timeout,可以通过如下方式查看 wait_timeout 值:

我建议设置小于5分钟的值,因为有些交换机会5分钟清理一下空闲连接,比如我们在做社交的时候,一般心跳包不会超过5分钟。具体原因可以看

https://github.com/zeromicro/go-zero/blob/master/core/stores/sqlx/sqlmanager.go#L65

其中 go-sql-driver 的 issue 257 里有一段也在说 ConnMaxLifetime,如下:

14400 sec is too long. One minutes is enough for most use cases.

Even if you configure entire your DC (OS, switch, router, etc...), TCP connection may be lost from various reasons. (bug in router firmware, unstable power voltage, electric nose, etc...)

所以如果你不知道 MySQL 连接池参数怎么设置,可以参考 go-zero 的设置。

另外,ConnMaxIdleTime 对上述压测结果没有影响,其实你也不需要设置它。

项目地址

tproxy: https://github.com/kevwan/tproxy

标签:tproxy,请求,157,gRPC,TCP,MySQL,go,连接
From: https://www.cnblogs.com/arena/p/17738573.html

相关文章

  • 《看了受制了》第三十天,9道题,合计157道
    2023年9月29日Awcing244迷一样的牛题目大意有n头牛,身高是1~n给出了n头牛,每头牛前面有多少个比它高的牛求它们的身高是多少?题目理解将题目转化成,倒着去枚举,在现在的序列中,二分去找第k+1小的值,每次输出一个身高,把身高弹出。代码实现constintN=1e5+10;intn,......
  • CF1575I Illusions of the Desert
    prologue还是太菜了,这个154行的树剖20min才敲完。analysis首先,处理这个给到我们的这个式子。\[\max(\mida_u+a_v\mid,\mida_u-a_v\mid)\]我们可以分类讨论:\(a>0,b>0\):显然\(a+b>a-b\),所以上式等于$a+b\Rightarrow\mida\mid+......
  • tcp协议基础
    前言:买的书到了,特此来学习一下。内容参考《web漏洞解析与攻防实战》-----1tcp协议之前有两篇基础的博客较为浅显的介绍了一下http协议,在http协议发挥作用之前,我们注意到会先建立tcp连接,那tcp连接要如何建立呢?这就需要tcp协议了。tcp协议是一种面向连接的,可靠的,基于字节流,双......
  • TCP/IP连接数的最大值取决于操作系统、硬件和应用程序等多个因素
    TCP/IP连接数的最大值取决于操作系统、硬件和应用程序等多个因素。下面是一些常见操作系统中TCP/IP连接数的默认值和最大值:Windows10/WindowsServer2019:默认值为16384,最大值为16777216Windows8/WindowsServer2012:默认值为16384,最大值为16777216Windows7/WindowsServer......
  • 【闲暇一写】基于TCP协议写的FTP管理工具
    这是一个FTP(文件传输协议)管理工具,能够支持文件上传下载以及操作服务端的文件。该工具由客户端和服务端组成。客户端与服务端通过Socket连接实现通信,客户端发送命令,服务端解析并执行相应的操作。部分代码已省略,下面是服务端和客户端代码的详细解释。GitHub:https://github.com/......
  • TCP/IP
    TCP/IP是因特网的通信协议。TCP/IP通信协议是对计算机必须遵守的规则的描述,只有遵守这些规则,计算机之间才能进行通信。计算机通信协议(ComputerCommunicationProtocol)计算机通信协议是对那些计算机必须遵守以便彼此通信的的规则的描述。什么是TCP/IP?TCP/IP是供已连接因特网的......
  • tcpdump 抓包命令的使用
     ##抓取192.168.6.6的tcpdump -i 网卡  host 192.168.6.6  ##抓取目的端口为22的网络数据tcpdump -i 网卡  dst port 22##抓取udp协议的tcpdump -i网卡 udp 过滤协议 ##抓包存取tcpdump -i eth0 host 192.168.66.6 andport......
  • Linux下的网络抓包tcpdump
    tcpdump[-AdDefIJKlLnNOpqRStuUvxX][-Bbuffer_size][-ccount][-Cfile_size][-Grotate_seconds][-Ffile][-iinterface][-jtstamp_type][-mmodule][-Msecret][-Q|-Pin|out|inout][-rfile][-ssnaplen][-Ttype][-wfile......
  • Luogu9157「GLR-R4」夏至
    抢到最优解了,UOJ校验码上80pts过不去。/kk这里是官方题解的简化。首先考虑\(n=1\)怎么做,相当于对\(m\le10^{10}\)筛出\(f\)的前缀和。由于\(f(p)=p\),直接构造函数\(g(n)=n\)然后PN筛\(O(\sqrtm)\)求即可。然后考虑\(n>1\),由于\(n\)比较小,考虑对每一个\(i......
  • 5157
    https://www.acwing.com/problem/content/5157/利用贡献思想入门的一道题,对于看起来复杂的问题,我们去考虑每一个元素在每一轮中的贡献,如果这道题不理解了可以去看视频讲解,里面说的非常明晰。在本题实现过程中需要找到找到数组中的最大数,并且统计有几个同时最大的数,我的实现非常......