首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Go每日一库之157:tproxy (TCP连接代理与分析 )

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

作者头像
luckpunk
发布于 2023-10-02 00:18:16
发布于 2023-10-02 00:18:16
67900
代码可运行
举报
运行总次数:0
代码可运行

你有同感吗?

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

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

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

所以我写了 tproxy

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

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

tproxy 的安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ GOPROXY=https://goproxy.cn/,direct go install github.com/kevwan/tproxy@latest

或者使用 docker 镜像:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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 系统:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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 的用法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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 连接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 连接池设置对连接池的影响,比如我把参数设为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
maxIdleConns = 3maxOpenConns = 8maxLifetime  = time.Minute...conn.SetMaxIdleConns(maxIdleConns)conn.SetMaxOpenConns(maxOpenConns)conn.SetConnMaxLifetime(maxLifetime)

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Gorm-数据库连接池管理
Gorm是一个支持多种数据库的ORM框架,因此它在数据库连接池管理方面也提供了一些功能。在Gorm中,连接池是自动管理的,它根据应用程序的需求动态地增加或减少连接数,从而提高数据库访问的效率。
堕落飞鸟
2023/04/24
5.3K0
Gorm-数据库连接池管理示例
在这个示例中,我们创建了一个数据库连接池,然后使用Gorm进行了一些简单的数据库操作。首先,我们创建了一个名为User的结构体,并调用了AutoMigrate方法来创建数据库表。然后,我们插入了两条数据,并使用Find方法查询了所有的数据。
堕落飞鸟
2023/04/24
8450
go-zero 中使用 gorm gen
由于go-zero自带的sqlx太难用, 实在无法忍受写这么多的魔法字符串, 所以这边在go-zero中引入gorm
seth-shi
2023/12/18
1.1K0
gRPC 网关,针对 HTTP 2.0 长连接性能优化,提升吞吐量
简单看下即可,由于含有定制化业务背景,架构图看不懂也没关系,后面我会对里面的核心技术点单独剖析讲解
微观技术
2021/07/05
4.3K0
线上问题分析系列:数据库连接池内存泄漏问题的分析和解决方案
上周五晚上主营出现部分设备掉线,经过查看日志发现是由于缓存系统出现长时间gc导致的。这里的gc日志的特点是:
捡田螺的小男孩
2020/05/17
2.7K0
nginx使用长连接代理grpc流量
Nginx在1.13.10版本支持了对grpc流量的反向代理,恰好业务有需求,要在sidecar容器中代理grpc流量。因此参考指引文档进行了配置。但是并未如预期般顺利运行,按照示例配置后,nginx与后端的grpc服务并非长连接,导致了一系列问题,在此做个记录,也给有需要的读者做一个参考,对具体过程不感兴趣的可直接跳到最后查看完整配置。
我有一只萌妹子
2022/10/09
4K3
gRPC 客户端调用服务端需要连接池吗?
在微服务开发中,gRPC 的应用绝对少不了,一般情况下,内部微服务交互,通常是使用 RPC 进行通信,如果是外部通信的话,会提供 https 接口文档
阿兵云原生
2023/09/01
1K0
gRPC 客户端调用服务端需要连接池吗?
Java生态中性能最强数据库连接池HikariCP
字节码精简:优化代码,直到编译后的字节码最少,这样,CPU缓存可以加载更多的程序代码; 优化代理和拦截器:减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一; 自定义数组类型(FastStatementList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描; 自定义集合类型(ConcurrentBag):提高并发读写的效率;
JavaEdge
2020/05/27
1.2K0
Java生态中性能最强数据库连接池HikariCP
Go数据库连接池设置不合理导致大量TIME_WAIT连接占满端口问题排查与解决
最近公司内部准备尝试使用下腾讯的TDSQL,因此组内同学写了一段很简单的查询TDSQL的go web程序,使用ab对其进行一个简单压测以获取TDSQL的性能表现,go代码如下:
Orlion
2024/09/02
3070
Go数据库连接池设置不合理导致大量TIME_WAIT连接占满端口问题排查与解决
为什么我们更喜欢 gRPC 进行微服务开发?
想象一下,有一天你的服务崩溃或突然关闭,以及后果:资源泄漏、交易不完整和整个微服务生态系统的混乱。这个问题的解决方案是什么?
Michel_Rolle
2024/01/18
3.2K0
PGbouncer-轻量级PG连接池管理工具
导言:曾经听说过一句话,用 PostgreSQL 而不用连接池,绝对是坑爹的做法…… 哪怕是像 pgbouncer 这样的“轻量级”连接池,有和没有的区别都不是一般的大。
腾讯云数据库 TencentDB
2021/09/07
2.8K0
HikariPool 连接池问题
问题描述: 腾讯云上 centos7 安装的 mysql 5.7.27,SpringBoot 使用 Hikaricp 连接池连接 MySQL。
全栈程序员站长
2022/09/10
4.3K2
HikariPool 连接池问题
工作中你会使用到 grpcurl 吗?
导入咱们的 tenant.proto 文件后,可以看到咱们服务端提供的如下两个接口:
阿兵云原生
2023/09/12
4450
工作中你会使用到 grpcurl 吗?
再有谁说不熟悉夜莺( Nightingale )监控系统,就把这个给他扔过去!
夜莺监控( Nightingale )是一款国产、开源云原生监控分析系统,采用 All-In-One 的设计,集数据采集、可视化、监控告警、数据分析于一体。于 2020 年 3 月 20 日,在 github 上发布 v1 版本,已累计迭代 60 多个版本。从 v5 版本开始与 Prometheus、VictoriaMetrics、Grafana、Telegraf、Datadog 等生态紧密协同集成,提供开箱即用的企业级监控分析和告警能力,已有众多企业选择将 Prometheus + AlertManager + Grafana 的组合方案升级为使用夜莺监控。
民工哥
2023/11/16
19K0
再有谁说不熟悉夜莺( Nightingale )监控系统,就把这个给他扔过去!
gRPC: 如何添加 API Prometheus 监控拦截器/中间件?
本文将介绍如何在 gRPC 微服务中添加 API Prometheus(普罗米修斯)拦截器/中间件。也就是可以在 Grafana 里做的 API 监控。
尹东勋
2021/10/15
1.8K0
gRPC: 如何添加 API Prometheus 监控拦截器/中间件?
用 Docker 在一台宿主机启动多个 etcd 节点
在学习和开发基于 etcd 的服务和功能时,需要自己在本地部署一套 etcd 集群。
amc
2021/02/22
2.3K0
用 Docker 在一台宿主机启动多个 etcd 节点
Chisel:一款基于HTTP的快速稳定TCPUDP隧道工具
关于Chisel Chisel是一个快速稳定的TCP/UDP隧道工具,该工具基于HTTP实现其功能,并通过SSH保证通信安全。Chisel是一个可执行文件,其中包含了客户端和服务器端,该工具基于Go(golang)语言开发,因此具备较好的跨平台特性。 Chisel主要可以用于绕过防火墙,但也可以用于向网络中提供安全终端节点。 工具的运行机制如下图所示: 功能介绍 易于使用; 高性能; 使用SSH协议对通信连接进行加密(通过crypto/SSH); 连接经过身份验证; 通过用户配置文件进行身份验证的客户端;
FB客服
2023/04/26
1.6K0
Chisel:一款基于HTTP的快速稳定TCPUDP隧道工具
(译)Istio:503、UC 和 TCP
最近 AutoTrader 在调试一个有些复杂的问题,这一过程得到了 Istio 团队的很多帮助。这个问题现在已经基本得到了解决,这一过程中采取的一些措施可能对其他用户有所启发,因此有了本文。
崔秀龙
2019/07/24
3.5K0
有赞TCP网络编程最佳实践
本文是根据有赞中间件团队多年的TCP网络编程实践经验总结而来,目的是为了避免应用因各种网络异常而出现各种非预期行为,从而造成非预期的影响,影响系统稳定性与可靠性。
用户1278550
2021/06/16
1K0
有赞TCP网络编程最佳实践
go web开发 (gin&gorm) 之DB配置及DAO的基本使用
  在正式进入主题前,先说说框架的现状,个人用的是gin-gonic框架,这是个在校大学生写的基于go语言的高性能web框架,在此之前我对比过beego 、 iris 、gin-gonic这几个在维护频度和依赖支持以及star热度方面,个人选择了gin-gonic这个框架 ,同时也在github上选用了一套比较前卫的成型的框架代码,东西十分的好,但是个人觉得框架集成的mysql实在是看不下去(主要是性能低了+ 稳定性不够好+升级麻烦),遂就将数据库换成postgresql,配置完成就开始测试Dao,需要说的是其中gorm是位台湾胸弟写的ORM框架,于是开始~
上帝
2018/12/19
3.2K0
推荐阅读
相关推荐
Gorm-数据库连接池管理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档