写在前面
记录一次502错误,这个错误在测试服务器没有发生过,只有到了prod环境才发生,先说明一下咱们的系统有单独的一个用户平台系统,用户登陆成功后,会将用户信息加密放到redirect_url中,而后重定向到子平台。子平台经过参数跟本身的key,再作解密,获取数据。前端
错误情况
服务上线之后,有些用户登陆就报了502错误,表现的症状是nginx
- 随机发生,可是有的人继续访问502的连接,就能够登陆上,一样,有些人访问502的连接,也一直报502。
- 发生错误跟用户浏览器绑定程度很高,好比一个浏览器发生过502,再发生的几率会很高,可是换一个浏览器,一样的帐号就有很大的几率能登陆。
- 有时清理缓存后就行了,过一阵子又出了问题。
- 使用无痕浏览器的话,症状缓解了不少,可是没有彻底解决。
- 由于程序是django写的,登陆过admin后台的人,出现问题的几率会增长。
- 手机号注册的用户基本能登陆,可是微信扫码注册的用户不少不能登陆。
错误排查
- 先查找日志,从Kibana中查找的错误是nginx报错:
*1063309261 upstream prematurely closed connection while reading response header from upstream
,根据这个现象,第一时间查的是nginx的问题,猜想是否是keep alive时间太短,致使读数据没读完被强制关闭了连接。
- 排查uwsgi的日志,其实当时先入为主,由于uwsgi的log中没有明确的报错信息,以为会是nginx那边的问题,虽然502对应着网关错误,通常是uwsgi的问题,但先入为主的思想致使对已经能提示错误缘由的日志没有过度关注。好比这条日志:
[pid: 50|app: 0|req: 2236/12394] 172.16.59.0 () {52 vars in 4089 bytes} [Thu Nov 14 08:55:34 2019] GET /login/?next=/text&data=9f3649e655416055e02f2a17ae558d75c
解决方案
- 由于跟nginx有关,并且微信登陆出现502错误的几率会增大,当时考虑的是找微信登陆跟手机号登陆的差别,发现微信登陆是扫码以后,用户平台HttpResponseRedirect到子平台的。而手机号是将地址作成redirect_url参数返回给前端,前端访问redirect_url的地址。考虑到这层因素,可是HttpResponseRedirect的302会不会对nginx有影响致使了nginx报错,因此第一个方案就将微信扫码的信息加密后重定向到一个地址中,将地址放到GET请求的redirect_url参数中,前端读取该参数,而后再跳转,从而达到两次登陆一致。
- 上述方法使用了以后,缓解了不少502,可是仍是有不少502错误,这个问题没有彻底解决,考虑仍是其余引发的问题。次日,产品的微信又登陆不了了,并且手机号注册也登陆不了,让她不要清理缓存,在接着登陆几回,找错误日志。这一次目标主要放在了uwsgi上,看到了一些请求日志。
[pid: 50|app: 0|req: 2236/12394] 172.16.59.0 () {52 vars in 4089 bytes} [Thu Nov 14 08:55:34 2019] GET /login/?next=/text&data=9f3649e655416055e02f2a17ae558d75c
,结合以前upstream没读完就被关闭,怀疑是uwsgi主动关闭的,就考虑是否是某些缓存满了,而后去找uwsgi相关参数,发现有一个参数为buffer-size,这个参数默认值为4k,当时以前的uwsgi说4089 bytes,猜想应该是这个问题,因此将该值扩大到8k,重启以后,原来登陆不了的问题就解决了。
复盘
- 复盘想一下以前的症状,由于目前咱们是用的authtoken的验证方式,登陆admin后台会在cookies多了session,加大了header,致使错误发生率提升。清理cookies,会减小header,因此发生错误几率会下降,无痕浏览器没有百度统计的cookies,也会减小header的大小,产品常常多个帐号切换,会致使cookies的数据增多。
- 查找bug仍是不要先入为主,按照经验,应为uwsgi没有明显的报错,才致使了排查重点到了nginx和代码层面。
- 这个bug在测试服务器没有发生过,主要缘由是测试服务器当时没介入微信注册,致使都使用手机号注册,因此在取用户数据的时候,oauth的表中就没有数据,减小了用户信息加密的长度,致使没有发生这类错误。
优化
- 后期仍是要增长监控的维度,打算增长uwsgi管理服务。
- 从新去研究下uwsgi的配置,排查可能将来可能致使问题。
- 将用户数据拉去更改,用户数据只加密用户表的PK,子平台获取信息以后,经过Pk去平台再拉去用户的全部信息。这样会减小url中的参数长度,使URL变的可控,不会随用户数据增长而变多。