使用 fasthttp 时要注意的两个点

我们做的是聚合支付系统,使用的是fasthttp 作为http server, http client 也是使用fasthttp

1. 第一个问题出现的场景是我们使用fasthttp client 请求微信支付时报了这个err ErrConnectionClosed

the server closed connection before returning the first response byte Make sure the server returns 'Connection: close' response header before closing the connection
image.png

由于是线上问题 情况紧急,查了一些资料后觉得使用fasthttp client 估计有坑,零时换成 go 原生 http client ,果然解决了问题。

那么问题来了,怎么会出现这中情况呢,这个错误的字面意思是 链接被对端关闭了,说到这里 就有一个要 注意了,fasthttp 默认使用的是 http1.1 golang 里面 默认是 keep-live 保持长链接的,但是对方关闭了链接我们 发包时 报的错误 应该是reset 呀,怎么是这么个玩意儿,只能抓包看看 啰, 结果发现 我们一个请求过去正常回包后,8秒过后 又收到一个FIN 包,此时就怀疑微信的 keep-live 时间了 ,那么 我就打印了一下 回包的head ,果然 keep-live 时间就是8s ,也就是说 8s 后微信 关闭了链接,不巧 我们的fasthttp 空闲等待时间是 15s 。还是没弄明白,按道理对端关闭了 ,client 端 应该是有感知的, 而且换成了 golang 原生 http client 就解决了问题,说明原生的client 是 有感知的,只能看代码了,结果发现了有意思的


image.png

从截图可以看出来,这个fasthttp client write 和 read是 同步的
如果第一个请求 之后 8s 之内不再请求 ,那么我们是不会再进行read 操作的,那么就无法感知 已经 被server 端关闭了。此时问题又来了, 8s 后请求 对端已经发了 FIN 我们再次write 应该是 Connection reset by peer 错误吧,其实不对 ,这里就涉及 tcp 的 四次挥手了, server 发了FIN 包 只能说明 server 不再 write 了 ,但是 server 是可以再read 的 ,也就是说 client 是可以再 wirte 的,刚好错误就是在第二次 请求 的read 操作时报出的。这里证明了错误的产生原因。

但是有 一个疑问 没解决,为什么用 原生 http client 没问题, 进一步来分析下,看代码


image.png

可以看到两个 协程 在 loop write read,所以对 server 端 FIN 是 及时响应的,也就是client 及时也关闭了链接。
问题找到了如何解决呢,两个方法:

  1. 简单粗暴,直接 设置 head 请求头 keep-live close ,变成短链接,但是这个有损性能。
  2. 既然 微信 keep-live 是 8s 那么 只要 设置 IdleConnTimeout 小于 8s 就行了 比如 7s , 这样就可以先于 微信 关闭连接了,不会让新的请求 使用 对端 发了 FIN 的链接 。

第二个问题 fasthttp 优雅关闭关不掉

我们使用了 fasthttp 作为 http server . 为了保证 业务完整性,做了一个 优雅关闭功能 ,其实优雅关闭思路很简单:
收到 signal QUIT 后 首先close 调 监听 端口, 然后等所有的链接上的业务处理完毕后 退出程序 就OK 了 , 那么如果 保证 所有链接处理完毕呢, 计数器!!! 新建一个链接时 +1 关闭一个链接时 -1 , 具体实现 其实就是实现 net.Listener 的 accept 和 close 接口 ,例如:


image.png

实现思路 是这样的 按道理 就OK 了,其实不是的,我是这么测试的:用一个 golang client for 循环 每隔5秒 发一个 请求, 然后在server 端 发送kill signal QUIT 结果发现程序一直没有退出, 怎么回事呢 ,除非 链接数 一直没有 减到 0 ,后来打印日志发现 确实没有,但是没道理啊, 一个请求处理了应该 close 呀, 此时 又想起了 http1.1 默认 keep-live 我每隔5秒 发一个请求,而设置的 server 最大空闲等待时间为15分钟, 也就是虽然 listener 关闭了 不会再有新的链接进来,但是 正在跑的这个链接永远不会主动关闭,因为每隔五秒 就有一个请求
怎么解决呢 ? 想到一个方法,就是设置一个标志判断是否程序 被关闭,当收到了signal QUIT 之后 就把正在处理的 链接的 resonse head 设置 connection close ,如何设置呢, 因为 我们我们处理的请求 都是在 一个 fasthttp.RequestHandler
,可以包装一下 这个 函数 例如:


image.png

这样我们每个请求完毕之后,检测到stop 标志后 必定处理会关闭链接。
貌似 解决了,其实还有点漏洞,就是这个stop 标志的检测 是代码要运行到这里,如果设置了stop 标志代码,但此时这条链接上的没有请求过来怎么办(j假如我是10分钟发一个请求),那么只能等待 IdleConnTimeout 超时的时候关闭链接了,但是 我们关闭一个程序的时候 不希望等待那么久,可以看看 这段代码:


image.png

listener 有一个maxWaitTime,就是程序无论有没有包在处理,到了这个时间程序 一定要退出,比如这个时间设置为 3秒,当然这个问题 也是有漏洞的万一 我们一个请求 处理耗时 不止3s 呢,岂不是不能完整处理这个请求, 当然我们业务一般一个请求一秒就处理完了。 不过这个问题确实存在,目前我还没想到一个好的办法彻底解决这个问题,如果你们有想法可以告诉我一下。

总结一下,这些主要是关于fasthttp 使用时要注意的问题,http协议 get post 虽然简单,但是要用好 还是要好好研究下, tcp 协议也要好好理解下,三次握手,四次挥手 还是有很多值得深究的,也很有意思。今天太冷就不多写了,写的有问题之处,还望多多指点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335