用gin做了一些api接口,经常运行中挂掉,处于访问无响应的状态,只能重启解决。用netstat -ano查看端口状态,处于CLOSE_WAIT。用wireshark监测确实可以看到有访问进来,但是gin没有相应。这些api有些是访问数据库返回结果的,有些是访问其它外部接口再返回结果的。单独每个api都用postman测试过几千次,并无逻辑问题。但就是运行中偶发变成无响应状态,无响应状态时数据库无死锁(排除数据库问题)。起初我猜测是不是访问其它外部接口超时所致,后来访问外部接口加入了超时5秒的限制,无效。后来猜测是gin自身未设置超时,于是改成如下启动参数
&http.Server{ Addr: address, Handler: router, ReadTimeout: 10 time.Second, WriteTimeout: 10 time.Second, MaxHeaderBytes: 1 << 20, }
仍然无效。请问在api中访问其它外部接口有什么需要注意的地方?是否会引起gin自身无响应?如何能让gin在api请求失败后超时不影响其它访问?
求指教,新手拜谢
下面是对外访问接口时候,使用的get,post方法,加了5秒超时
有疑问加站长微信联系(非本文作者)

贴代码看看
recovery中间件加上没有
代码已贴图,请看有问题吗
用router := gin.Default() 创建的,好像是自动开启recovery中间件吧
你说加了5秒超时,是怎么加的,不会是设置 ReadTimeout 吧。这不是访问外部接口的超时。
对外部访问的get,post方法代码已贴,您看写的有问题吗
日志呢,没报错吗。是你监听的 8080 端口状态是 CLOSE_WAIT?
日志里没有报错。就仿佛gin假死了完全没有收到请求一样。但用wireshark能看到请求确实到端口了,用netstat 命令看端口状态确实是CLOSE_WAIT
难道是我的gin版本太老有什么隐藏bug?我的gin是v1.4.0-dev
另外还有个怀疑,是不是遇到了拒绝服务攻击?
端口状态应该是listen, 你接收下 s.listenAndServer() 的err 看看。
11楼 @don178 这是其中一次TCP状态,监听的端口6692是listen没错。但就是不响应了
首先应该不是拒绝服务攻击,因为从图中看是客户端可以顺利建立连接,并且是主动断开连接。 一般还是怀疑服务端超时,我在 handler 中 sleep 一段时间就可以复现你描述的情况
赞同
可以考虑在 gin 根路由挂个日志看看,是不是收到了请求
13楼 @symphony09 谢谢指点。这是我数据库连接参数,请问有没有问题。最初我设的是SqlDB.SetMaxIdleConns(50),SqlDB.SetMaxOpenConns(100)。曾经怀疑连接池不够用,分别放大了10倍,但没有解决问题,服务挂掉的时候查非活跃连接数量并不多,不到10个。还有一点我百思不得其解,服务挂掉的时候,一些并不访问数据库的api(只是简单返回时间或者字符串的功能),也失去了响应。
谢谢指点。gin日志已挂,挂日志代码如下。当服务挂掉的时候,日志就停止输出了。但从wireshark里能看到请求已经访问到本机端口卡在那里。
确实奇怪,有用 pprof 分析过吗
有加载pprof,但还不太会看这个东西
建议还是升级下gin版本到最新。 gin的http是用的协成,基本是不会出现无法响应的问题
我现在用的是 gin是v1.4.0-dev,不确认是不是我这个gin版本的问题,请问有谁用过这个版本吗。有下载最新版尝试升级过,但最新版里面的一些引用文件,怎么都go get不到,真是喝凉水都塞牙
不知道如何了,我也遇到类似问题。我用gin弄了个服务,目前在测试阶段,就我一个人用。 如果长时间没访问,然后再次访问时,第一次会502,再次访问就好了。 再长时间搁置不访问,再次访问时,依然会复现。 我感觉是 ReadTimeout 和 WriteTimeout 导致的