被 http2 坑了一把,nginx 1.9.15/1.10.0 + http2 + post + safari 有严重 bug

2016-08-20 08:11:06 +08:00
 fancy20
惭愧在公司官网上了 http2 ,有一部分注册 post 请求发送时返回错误 0x0 ,后来通过错误回调的统计发现大部分是 safari(好像还有 edge)出现这个问题, safari 能稳定复现, chrome 不能复现,关闭 http2 后 safari 不能复现。

具体就是,打开 http2 站点页面,等待几分钟不动(或看下面连接里说可以断网再连接上),接下来在页面上的操作,比如我们的注册是 ajax 的 post 请求会返回 0x0 错误,看 safari 的调试页面网络请求都没发。贴两个连接:

https://openradar.appspot.com/26406397
http://stackoverflow.com/questions/37309940/nginx-http-2-http-post-safari-error

猜测是 safari 的 http2 socket 超过 idle 后,即使有新请求也不会重新连接,直接报连接错误。。

这次给我的教训就是生产环境还是不要玩这类太新的东西了。。

@qgy18
20605 次点击
所在节点    站长
27 条回复
fancy20
2016-08-20 08:13:22 +08:00
问题就是导致用户打开我们官网,上来就直接注册没问题。但他看了一会儿官网介绍,再注册就提示错误了。。看了从 5 月份上了 http2 后就有这类错误发生,但一直没察觉,看统计大约有 100 多次。。
bigzhu
2016-08-20 08:49:41 +08:00
我有类似问题,主要是图片加载上,图太多的时候,不再会等着慢慢加载,似乎迅速 timeout ,后面的直接提示错误(忘记错误码了),显示加载失败。
MrMario
2016-08-20 09:49:08 +08:00
具体哪个 Safari 版本?
ivmm
2016-08-20 10:06:22 +08:00
不新了吧, Nginx 支持 h2 都已经有个一年了。
FrankFang128
2016-08-20 10:27:59 +08:00
什么是 0x0 错误
fancy20
2016-08-20 10:34:27 +08:00
@MrMario 公司两个用 mac 的同事自带的 Safari 都可复现,版本应该比较新,具体我之后看看

@FrankFang128 提示大意是无法连接服务器,错误码 0x0
qgy18
2016-08-20 11:06:37 +08:00
@fancy20
是有这个问题,我之前也遇到了,还研究了一下,我争取本周末写一个文章详细介绍下这个问题。
这个是 nginx 的锅,应该跟 http/2 关系不大。

https://trac.nginx.org/nginx/ticket/959#comment:18
https://blog.crashed.org/fixing-nginx-bugs-with-nghttp2/
qgy18
2016-08-20 11:22:39 +08:00
要避免这个问题,要么升级到 nginx 1.11.0+(第二位奇数表示是 nginx 的主线版本,偶数是稳定版本);要么使用 nghttp2 等其它软件做为 http/2 接入层。

两者风险都挺大的,建议楼主先在生产环境关闭 http/2 。
ThreeBody
2016-08-20 11:23:44 +08:00
我之前用 lnmp.org 的一键安装包安装的 nginx ,用 httpt2 后,如果目录后面没有 /就会出现 504 gateway time out ,我一直以为是我自己配置错了,最试了一下用 ssl ,所有问题都消失了
后来干脆不用 http2 了
kn007
2016-08-20 11:25:39 +08:00
一直用新版,没有啥问题
rrfeng
2016-08-20 12:18:43 +08:00
这个我遇到过。

我们的现象是 iOS 客户端在发起 POST 请求的时候很大概率会直接失败。

就是 http2 在建立连接的时候一个预发送数据的窗口问题,很难说是谁的错…… nginx 并没有违反协议,但是和 http client 采取了不同的策略。

所以 1.11 加了一个新的配置项。
LazyZhu
2016-08-20 12:27:11 +08:00
哎呀,可在 1.10.x 打补丁啊
qgy18
2016-08-20 12:38:34 +08:00
@rrfeng

To avoid unnecessary latency, clients are permitted to send additional frames to the server immediately after sending the client connection preface, without waiting to receive the server connection preface.

客户端可以在建立连接的时候发送其它帧(也应该包括 DATA 帧),但是 Nginx 这时候的 initial window 是 0 ,所以回了一个 REFUSED_STREAM ,这时候部分浏览器直接报错而不是重试。

格式感觉这还是 Nginx 的锅。


@LazyZhu

Nginx 已经明确表示,这个补丁不会移植到 1.10.x 。他们认为: 1.10.x 是稳定版,而 HTTP/2 本来就属于「不稳定」的功能,要用 HTTP/2 就上主线版。

We don't backport features to the stable branch (that's what we call stable, no enhancements). It receives only critical bug fixes. If you use such new, very complicated and actively developing protocol as HTTP/2 then it's naturally that you have to stay with the mainline branch.
anjunecha
2016-08-20 12:38:56 +08:00
之前遇到过,后来索性在服务器上就去掉了 http2
just1
2016-08-20 12:57:44 +08:00
一直在用 1.9.7 ,会有这个问题嘛
rrfeng
2016-08-20 13:10:28 +08:00
@just1 1.9.7 没有
rrfeng
2016-08-20 13:10:49 +08:00
1.10 就不能用了
或者自己打 patch
反正 1.11 也发布了
fancy20
2016-08-20 13:48:30 +08:00
@qgy18 已经关了,当时觉得稳定版应该没太大问题了就开了,否则也不会去掉 spdy 啊

太难了…甚至想去掉 https 降到 http 了,改 https 导致了一大堆问题,已经因此荣登公司“持续最久”,“引发问题最多” bug 榜榜首。之前在某度的时候,搜索改 https 有个 http 引用的问题找到我,一堆人催着赶紧解决,本来就很忙还催的要命,当时很生气,现在总算明白了…
rrfeng
2016-08-20 13:50:59 +08:00
@fancy20
这个 bug 确实隐蔽性很高,而且我们不知道为什么只有 iOS 的库有问题,而且当且仅当是 WiFi 的时候。
可能是移动网络无法 upgrade 到 http/2 ?
fancy20
2016-08-20 14:02:16 +08:00
@qgy18 ssl 太难了…我们有个模块是用户申请注册后给用户发邮件的,用的 javamail 和腾讯企业邮箱,上个月突然有一天同事说最近 3 天都没人注册啊(邮件会抄送他邮件组),然后发现是邮件都没发出去,在服务器上打了一堆 java 网络日志都是握手失败,但我 mac 同样代码就没问题。。最后发现服务器用的 jdk 是 1.8.51 ,我 mac 是 1.8.45 ,腾讯改了 ssl 配置,他新的 cipher 在 1.8.51 被 Oracle 改为不安全已废弃的,各种参数显式指定使用都不行,换了 1.8.45 的 sdk 解决。。腾讯为啥要改呢, Oracle 为啥要改呢。。。太难了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/300566

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX