Redian新闻
>
线上服务挂了 3 分钟

线上服务挂了 3 分钟

科技

你好,我是yes。

在一个风和日丽的下午,刚打算饮茶,线上就开始报警了,一看情况网关报 500 了。。

网关(用的是Spring Cloud Gateway)挂了可还行,这可是对外的们,门没了岂不是所有请求都进不来了!

说好的动态调度扩缩容负载均衡呢??怎么没支棱起来?

及时处理

话不多说,直接重启。

然后看起来好了,重启大法!yyds!

问题排查

感觉有点突然,最近网关并没有发版,上一个版本还是在 4 月份,挂的有点莫名其妙。

不过这两天在执行一个动态迁移服务,有大量的请求,预估两天的请求量有 300 w,我一开始以为是被这个打挂了。

但是有关的接口我都加了限流,且请求一直是匀速的,也已经正常处理一天一夜了,服务的各项指标也没任何异常,咋就突然这样了呢?

仔细看了看,网关的服务没挂,但是请求都返回了 500。

上去一查日志:

我擦,这是什么玩意?

看起来是要创建临时目录,然后失败了,因为空间不足,但是实际上我看磁盘空间还很多,这时候我已经有点感觉了。

可以看到是 Spring 的 SynchronossPartHttpMessageReader 类触发的这个报错,网关代码确实有用到 HttpMessageReader 相关的解析。

然后进行一波源码分析:

点进源码粗略了看了下,每个请求的解析都会创建一个临时目录,往里跟了几步看了看,这个临时目录的作用是到时候用来给解析 Multipart 存储临时文件用的。

但最近的请求也都跟 Multipart 没关系了,咱也不懂为啥要这样先预创建。

看到这反正问题已经定位到了:因为网关要用到 HttpMessageReader 相关的解析,而这个解析实现类,每次都会预创建一个临时目录,用来到时候给 Multipart 用(即使实际没这玩意),因此每个经过网关的请求,都会在网关本地服务器上创建一个临时目录

而由于这两天请求非常多,创建了很多目录,把操作系统的文件 inode 占满了,使得后续的所有请求在执行到创建临时目录的方法时就报错了,因此所有请求都返回了 500。

inode

这边先介绍下 inode。

在类Unix文件系统中,文件的元数据存储的地方叫 inode,也就是文件元数据和文件的数据是分开存储的。

所谓的元数据指的是:文件的大小、创建时间、修改时间、权限等等,它也会占用磁盘空间。

因此操作系统分配给 inode 存储空间也是有限的,超过了限制就申请不了

所以有时候磁盘空间够的,但是文件还是无法创建,一种可能就是 inode 满了。

对了,对 Linux 这类系统而言,目录也是文件,一样的。

tmp

tmp 目录其实是有讲究的,临时目录。

理论上这个目录默认操作系统会有个叫 tmpwatch 的玩意去清理长时间无用的文件,一般会定时去清理。

而且重启系统的话,这里面的文件也会被清空。

至此,产生问题的原因应该非常清晰了。那如何解决?

解决

  1. 利用 tmpwatch 勤快点去清理,比如近几个小时没用的就直接干了。
  2. 不用 HttpMessageReader
  3. 定时重启
  4. 修改源码
  5. 看看后续版本

第一点不太好,因为有几率误删有用的文件。第二点理论上用了  Spring 体系,这玩意好像不太好避免,先暂定。第三点,太骚了,还是算了。第四点,改起来不难,但是后面升级版本啥的不太方便

先试试第五点。

然后我就去 spring-cloud github 搜一搜,果然有 issue。

点进去一看,关联到另一个 issue,一看巧了,一模一样的错:

然后他圈了好几个老哥,有个叫 poutsma 老哥回答了他的问题:

我简单翻译下:这样的实现是为了解决一个安全问题,为了不创建一个固定的临时目录,如果使用固定目录会带来严重的安全隐患,然后也不能在退出后删除,因为这样会删除所有上传的文件。

简单来说:不是bug

而且目录本身占用的磁盘空间可以忽略不计,只有当大量上传的文件存储在那里时,目录才会开始占用空间。

通常,操作系统会在一段时间后清理临时文件。

咳咳,老哥看起来说的没毛病,但是它这个实现确实没有考虑到大量的目录会撑爆 inode 的情况!

然后有个叫 RekaDowney 的老哥也在下面说到:

不论请求的 content-type 是不是 multipart/form-data 都会创建临时目录(这跟我前面说的一样,我这几天的几百万请求压根不是 multipart 相关的)。

然后 poutsma 老哥觉得没啥毛病:

你不用 multipart 创建这个目录也没影响,这目录里面又不会有文件,一个目录才占几 bytes,洒洒水啦。

额,把我洒哭了(3分钟线上服务不可用这是P几事故?)

不过后面马上 poutsma 老哥意识到这样好像也不好,因此他回复到:

对,他稍微妥协了下:我改我改,目录只在解析 multipart 数据的才会创建。

一天后 RekaDowney 老哥已经等不及了,他说:我已经算不清到底创建了多少个目录了,至少有 200 多w,然后我修改了源码,就调整了几行,只有在解析 multipart 的时候才创建,并且老哥还说要不要他提个 pr 贡献一波代码!

这位 RekaDowney 老哥的执行力还是强啊,自己动手丰衣足食,毕竟鬼知道这修复啥时候能发版。

好了,吃瓜暂时吃到这,最终我跟踪看到这个玩意是在 5.2.16 版本修复:

具体的替换方式是不无脑创建了,就创建一个随机的目录,然后保存这个引用,这样即使有很多 multipart 的请求,也不会创建很多目录了,整挺好:

然后我翻阅了一下 5.2.16 那个版本的 release,咳咳:

上面写着这玩意是 feat,不是 bug。

你们觉得呢?

程序员的倔强之,这不是bug:)

最终我的解决方案是:升级了 gateway 的版本到 5.2.16。

插播我的个人小广告,最近在写一个专栏,有兴趣的可以看看,适合初学者:

- 我的消息队列专栏

然后我有个摸鱼闲聊群,想入群的加我微信:yes_oba,备注摸鱼,拉你入群。

我是yes,从一点点我亿点点,我们下篇见~


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
无中介费|随时入住|近红线地铁站步行5分钟/MIT步行15分钟/哈佛步行13分钟高级公寓两室一厅两卫4250微信、支付宝服务升级,国际银行卡可在华线上支付9.1住|接本科生|近伯克利步行1分钟/NEU步行11分钟/BU步行15分钟studio 2650,包供暖和热水降价|无中介费|9.1入住|近红线地铁站步行5分钟/MIT步行15分钟/哈佛步行13分钟高级公寓两室一厅1.5卫3900校招提前批挂了,会影响秋招吗?学员OFFER | 面试挂了,Meta HR居然主动打电话加面!为了你走遍草原 第八章《东风第一枝 - 谷雨》开挂了!有了它,你家厨房永远不会脏太好了!微信、支付宝服务升级! 国际银行卡可回国可绑定线上支付!一位北大才子的"润"之路左右逢源!印度要开挂了吗?9.1入住|半中介费|近伯克利步行5分钟/NEU步行13分钟/BU步行10分钟studio月租2350+,包水暖开挂了!奥莱月末疯狂大促,真是开挂了!安德UA玛,Burberry,CK史前疯折开打国产防晒开挂了!防水防汗防晒还养肤!上脸变成水光肌!请把它焊在脸上寄了,线上服务挂了 3 分钟!《薔薇處處開》半中介费|八九月入住|近红线地铁站步行5分钟/MIT步行15分钟/哈佛步行13分钟高级公寓两室一厅两卫4250+9.1住|接本科生|室内洗烘|近伯克利步行1分钟/NEU步行11分钟/BU步行15分钟两室一厅两卫5000,包供暖和热水adidas这是开挂了么??又好看又直接5折的!智秀同款$80收!吃饭事小,出局事大:在高人眼中,你已经一丝不挂了​找室友合租|无中介费|9.1入住|近红线地铁站步行5分钟/MIT步行15分钟/哈佛步行13分钟高级公寓两室一厅两卫3800一丝不挂了…点一下详情系统挂了,CPU100%面试经历 | 面试挂了,Meta HR居然主动打电话加面!罗兰岗华人在超市停车场下车仅三分钟 遭雌雄大盗偷车!LA动物服务中心提供免费收养服务!【提示】上海发布“15分钟就业服务圈”社区就业服务站点建设指引,加强重点群体就业帮扶9.1住|接本科生|近伯克利步行1分钟/NEU步行11分钟/BU步行15分钟studio 2500+,包供暖和热水调研直播火了!基金公司借线上平台试水“顾”服务《花信风之谷雨》摆烂后,我的事业反而开挂了!秋招资讯 | 如何避免“面试挂了才知道考什么了”的情况发生?9.1入住|近红线地铁站步行5分钟/MIT步行15分钟/哈佛步行13分钟高级公寓两室一厅两卫4500以财税SaaS+线上经营体系服务企业,「融易算」获数千万元B+轮融资|36氪首发9.1入住|接本科生 |近伯克利步行1分钟/NEU步行11分钟/BU步行15分钟1B1B 2800,包供暖和热水
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。