HTTP上传日志到数据中心出现SIGPIPE信号
在调试配置线上传日志到数据中心时,HTTP上传过程出现SIGPIPE信号,现记录一下过程。
一、现象
1、日志线采用HTTP方式将日志上传到数据中心,使用的HTTP库是libghttp。在查看日志的时候,发现HTTP总是出现上传失败的错误,如下图所示:
很奇怪的是上传成功和失败交替进行,且原因无法确定。
2、发现bin目录下RESTART.log不断刷日志,程序一直不断重启,使用GDB调试,发现总是出现SIGPIPE的信号!GDB提示“Broken pipe”。
3、规律是:程序首次启动,可以成功发送一次日志到数据中心,第二次发送的时候就出现SIGPIPE的信号!
二、问题的解决过程:
1、百度搜索SIGPIPE信号的解释:对一个对端已经关闭的socket调用两次write, 第二次将会生成SIGPIPE信号, 该信号默认结束进程。
2、总结一下目前程序的现状:
(1)使用GHTTP库,它自动管理TCP链接的建立和释放,调用这并不直接参与socket的创建、TCP链接的创建和释放;
(2)SOQ非结构化日志也使用HTTP上传方式,但从未出现这种情况,怀疑数据中心有问题,于是找对方进行讨论;数据中心一直咬定他们没问题,说其他厂家也一直用,但都没问题;而我们曾经换过一个数据中心的URL地址,上传没问题,只是换了不同的URL就会出问题,于是坚信是数据中心有问题,对方总是会关掉socket链接;
(3)与杨威、李佳、王凤梅进行讨论,得知数据中心采用的是短连接方式,得出结论是对端关闭了socket链接。数据中心未就此问题进行说明。
(4)思考如何解决这个问题。首先需要建立短连接,每次上传数据中心日志时都需要建立链接,而链接是由ghttp控制的,如何做到呢?肯定是使用方法的问题。
总结一下前面出现的规律,首次上传成功,第二次上传失败,程序重启,又上传成功,接着失败,重启.......观察代码的逻辑,第二次上传与第1次上传的区别就在于不再重新创建http上传句柄,使用第一次创建的句柄,改成每次重新创建句柄,经测试问题不再出现!
三、总结
1、ghttp库上传日志时,如果只创建一次句柄,每次都使用该句柄上传日志,则使用的是长链接模式,并不支持检测链接的状态。
2、SIGPIPE信号的含义是:对一个对端已经关闭的socket调用两次write;
- 1楼 刘庆云 2017-06-22 16:28:06 [回复]
- 改成每次重新创建句柄,这样系统的性能不会变的很挫吗?