性能文章>记录两次多端排查问题的过程>

记录两次多端排查问题的过程原创

2年前
415124

我们组会负责后端的一些服务,因此出现问题时不仅仅是界面的样式兼容问题,还有很多其他的后台服务问题。

排查后面这类问题,需要具备些服务端的排查手段,否则就会难以定位问题所在。

一、聊天问题

公司有一个即时聊天的功能,在 6 月 2 日周五,上了一个自动推送个性文案的功能,大受好评,访问量迅速蹿升。

UV 一度增加了六七千,在高兴的同时,问题也接踵而至,例如匹配不到聊天对象、跳转页面时卡住白屏和聊天界面卡顿问题。

其实这些问题之前也存在,但因为用户量小,没有被大规模的曝光。

这次用户量上来后,在 3、4、5 号端午三天,客服不间断地收到投诉。由此可见,量大后,再小的问题也会被放大。

鉴于问题的表现都是在我们 Web 这一端,所以需要我们先进行排查。

排查的步骤分三步:首先需要确定问题是由哪一端触发的,其次确定问题影响范围和制定优先级,最后联合相关组一同给出解决方案。

在让其他端配合排查之前,需要先确保自己那块没有问题。

在将目前上报的所有问题分类后,发现大部分遇到的是第三个问题:聊天卡顿,这部分要安排更多的精力来解决。

1)匹配不到

当匹配不到时,就会像下图那样一直处于等待匹配中,用户不得不关闭界面。
 
匹配失败是因为账号被锁住了,由我们组负责优化。

image1.png

在匹配时会创建一个并发锁,正常情况是3秒后过期或在某个位置解锁,但出现异常后,没有成功解锁导致用户一直处于锁住状态。

// redis原子性控制并发
async incrLock(key, option) {
  const incrLock = await redis.aws.incr(key);
  if (incrLock && Number(incrLock) > 1) {
    return false;
  }
  const lockDuration = option && option.duration ? option.duration : 5;
  const momentstamp = moment().add(lockDuration, 's').valueOf();
  await redis.aws.pexpireat(key, momentstamp);
  return true;
}

为了保证锁能过期,将过期的配置提升至if语句之前。
image2.jpeg

2)跳转卡住

这个问题非常奇怪,遇到此问题的都是安卓用户(华为、VIVO 和小米),进度条卡在下图的位置就进行不下去了。

image3.png

查看客户端日志,发现其实已经请求了聊天页面(chat.html)。

06-05 12:08:12.730 1 INFO/AppForeground: WebViewActivity onCreate true
06-05 12:08:12.841 1 INFO/WebViewActivity: loadUrl https://security.xxx.me/safe_redirect?url=https%3A%2F%2Fs.xxx.me%2Fc%2F1Gf4Gf
06-05 12:08:12.867 1 INFO/AppForeground: WebViewActivity onStart
06-05 12:08:12.872 1 INFO/ChatServiceManager: startService true
06-05 12:08:12.873 1 INFO/AppForeground: WebViewActivity onResume
06-05 12:08:13.074 1 INFO/WebViewActivity: processUrl else true url:https://s.xxx.me/c/1Gf4Gf
06-05 12:08:13.394 1 INFO/AppForeground: MainActivity onStop
06-05 12:08:13.669 1 INFO/WebViewActivity: processUrl else true url:https://www.xxx.me/game/chat.html?entry=appchatpush
06-05 12:08:15.063 1 INFO/AppForeground: WebViewActivity onPause
06-05 12:08:16.064 1 INFO/AppForeground: WebViewActivity onStop

查看Nginx 服务器访问日志,发现的确在那个时刻收到了来自于客户端的请求。

url: "/game/chat.html?entry=appchatpush" not url: zh_cn and http_user_agent: MED-AL00

image4.png
但是在查找脚本的请求日志时(game/js/chat.719c3c70.js 和 game/js/chunk-vendors.11311460.js),并没有发现。

image5.jpeg
由此可推断,要么就是客户端没有发送请求,要么就是服务器当时没有响应,需要客户端帮忙排查。

3)聊天卡顿

这个问题主要是客户端排查,我们组配合打印关键信息(console.warn())。

image6.jpeg
后面我们对页面脚本也做了一次优化,实现组件区域化的渲染,避免整个大组件的渲染。

4)异常流量

在将相关组拉在一起开会时,运维反馈,在 6 月 4 日 23:42-23:43 之间有股异常流量,而 22:00-01:00 也是公司 APP 最为活跃的时间。

这股异常流量促使短链服务和长连接发生大量的 502/503/504 的报错。

查看 Nginx 日志(如下图所示),发现有个明显的凸起高峰,也正好是在那段时间发生的。
image7.jpeg

经查,在这段时间内,进入聊天页面的埋点只收到了 1 个。运维怀疑是 api 项目的一个回调接口影响了 api 的其他服务。

6 月 6 日晚上 20 点,将此接口服务迁出,单独作为一个服务(就是路由转发),当天晚上的错误从之前的 500 多降到了 60 多。

为了弄清楚长连接发生异常时,有哪些用户受到了影响,因此在 /socket 地址上还附带上了用户 ID。

image8.png

5)下一步动作

在 6 号开完会议后,就马上修复了我们这边的几个问题,以及运维的问题。

查询聊天匹配完成的曲线图,发生呈明显的上升趋势,匹配率增幅 23% 以上,这是一个让人振奋的消息。

客户端因为无法复现,所以需要添加埋点,例如增加键盘交互等事件的监听,还需要优化键盘弹出方案,这些都得发布新版本。

所以要下一个版本中解决卡顿的问题。

二、内存问题

我们组的静态资源都单独放在一台服务器中,静态资源就是图片、HTML、JavaScript 和 CSS 等文件。

运维和我反馈说,这些服务器的内存会一直涨,除非重启容器后,内存才会降下来。
image9.jpeg
  
我的第一反应是内存是不是泄漏了,服务器中有个聊天的页面,会不会是建立了大量的 websocket 连接,没有被释放掉。

但是转而一想,应该不是,因为这些文件会被传输到用户浏览器中,发起的连接也是存在于客户端,不会影响服务端的内存。

image10.jpeg
进入到服务器中,输入 ps aux 命令,查看正在运行的进程,发现有好多 worker process。

问运维,说这些都是 Nginx 的进程,后面就让他去优化,他改了个配置,内存增长的幅度是变小,不过依然会慢慢增长。

点赞收藏
咖啡机KFJ

https://www.cnblogs.com/strick

请先登录,查看2条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步
4
2