文档章节

RN 热更新Node服务cpu占用从80% 优化到20% 记录

hucheng9110
 hucheng9110
发布于 02/26 13:21
字数 1326
阅读 118
收藏 0

3 月,跳不动了?>>>

RN 热更新Node服务cpu占用从80% 优化到20% 记录

先看优化前后结果对比 优化前

优化前.png-64.7kB

优化后

优化后.png-53.7kB

先聊下背景,过年前半路接手团队的 RN的热更新的服务端开发,服务端采用的是 Express + Mysql,是拿 github 上一个开源服务改的 主要给React Native 项目提供热更,就是每次打开App,会发起一个请求,看当前App是否需要更新,目前已经用在 趣头条的 IOS端,集团萌推等一些项目上面,请求量还算比较大的,QPS 在 500 上下浮动, 之前这个项目经常报警,网关Kong 上面的日志显示40%504 状态码(网关连接超时,本质就是服务响应不过来),当时粗暴的处理了下,同事写了个脚本,cpu到到阀值就杀掉服务重启

报警1.png-129.2kB

过年来,添加了新的需求,然后我就发到线上了,三天2头的报警,还经常是大晚上,,给我气的要死,无法忍受了,决定好好整整,优化一把,下面是我整个流程的一个记录

kong错误码.png-229.6kB 上面这个图是 Kong 的监控,曲线最高的就是这个 RN 服务,因为这个服务请求主要是查询,是否要更新,不想动之前的业务代码情况下,想到的第一个点,就是上 Redis,二话不说 先整上,上完 Redis,通过观察 Kong 的曲线,发现 504 稍微下降了些,但是 cpu 并没有降下来,正在我摸着头发分析下一把咋整的的时候,Redis报警又来了! redis报警1.png-323.8kB

这次不是这台服务器,而是 Redis 报警了!,手忙脚乱的,回滚项目,看日志

redis报警2.png-83.9kB

从图上可以看到 用上 Redis 后,Redis 连接数飙升,快要到最大值了,Redis还丢弃了很多连接,头大头大了,以为上了 Redis 就是银弹,没想到新问题又来了,运维说要不加机器,要不 Redis 改成长连接,加机器是不可能的,思考一会,猜测是自己代码里是不是有些地方 redis 连接是不是没有关,检查代码,发现下面一段代码

return redisClient
      .getAsync(redisCacheKey)
      .then(data => {
        if (data) {
          try {
            log.info("get data from  cache");
            var obj = JSON.parse(data);
            // redisClient.quit() // 少了这行代码
            return obj;
          } catch (e) {
          // redisClient.quit() 少了这行代码
            log.error(`JSON.parse error:${data}`)
          }
        }
    }).then(....一堆代码)     

真想抽自己耳光,赶紧在 加上上面注释的2行代码,发布上线,Reids 曲线降下来了,一些,没有之前那么多了,但连接数还是不少

稍微平复下心情,盯着日志看,分析分析,思考下来,这个服务,app打开就会请求一次,虽然用 Redis 做了缓存,但有的版本实际是没有热更的需求的,但是都得经过去redis 查询下缓存,看有没有数据,而且这样的请求还非常多,就相当于 我要看今天有没有课,得走进教学楼,到教室里面,看看有没有人,然后确定有没有课,太浪费时间了,要是在教学楼前面有个告示,就知道今天上不上课,不就好了么,对应的,我在请求进来,在路由那做一层拦截不就好了,于是我就做了个内存缓存,创建了 size 最大为 200 的 map,请求进来,先看看 map 里面有没有,没有就直接返回,不耽搁时间,也不占用 cpu,在新发布版本的时候,clear 掉这个map 就好

const NOTFOUND_MAP = new Map();
const NOTIN_WHITELIST_MAP = new Map();
function clearNotFoundMap() {
  NOTFOUND_MAP.clear();
}
function setNotFoundMap(key) {
  if (NOTFOUND_MAP.size > 200) {
    NOTFOUND_MAP.delete(NOTFOUND_MAP.keys().next().value);
  }
  NOTFOUND_MAP.set(key, true);
}
function getNotFoundMap(key) {
  return NOTFOUND_MAP.get(key);
}
module.exports = {
  clearNotFoundMap,
  getNotFoundMap,
  setNotFoundMap,
  clearNotWhiteListdMap
};

改完上线,然后先看了 下 Redis 曲线

redis报警.png-368.5kB 断崖式下跌,效果明显

再看下 cpu 占用

优化后.png-53.7kB

效果也挺好,从 平均 80% 降到 20%,效果也非常明显,从这以后,到目前位置也没有报警大半夜来骚扰了,睡个安稳觉

基本上就完成了本次优化思路,总结下来就是不要急,遇到问题先回滚代码,仔细分析日志,业务流程,一定是能找到问题点

插一句,最开始 运维给我讲 Kong 报的 4xx|5xx 问题非常多,当时没有看监控曲线,我以为报是 都是500,就想到是代码问题,然后检查代码里面做全局的错误 捕获,但是日志显示没有 500 错误,但是 node 是异步的,异步的错误, expres 这种框架如果自己不处理,是捕获不到的,接下来我会写一篇,Node.js 里面怎么样 友好的设计一个全局的异常处理,就像 Java那样,在最外层捕获异常,漂亮的很

如果你喜欢也可以关注我的 公众号 「chromedev」

© 著作权归作者所有

hucheng9110
粉丝 2
博文 4
码字总数 3703
作品 0
普陀
私信 提问
加载中

评论(0)

ReactNative快速入门笔记

ReactNative的文档地址有多个,如果你英文够好,就去研读官方的文档吧, 如果读原文比较吃力,中文官网也是不错的选择。 下面是我个人记录的一些笔记,仅供初学者入门参考 预科 入门React N...

木羽zwwill
2017/09/19
0
0
移动动态化方案在蜂鸟的架构演进(含React Native与Weex对比)

当下,移动动态化已经成为各大公司都回避不了的问题,产品的快速迭代对技术提出了更高的要求,而移动端的动态化方案也是层出不穷:Hypid、结构化 Native View、React Native、Weex,什么样的...

雪夜凋零
2017/08/18
0
0
React Native 在卖菜公司的落地之路

摘要 本次分享介绍了RN应用从开发到上线以及最后维护的整个过程,其中涉及到了组件化、热更新、打包、线上监控等方方面面。 Why RN 之所以要选择RN,一方面是因为效率问题,另一方面则是历史...

2018/06/26
0
0
揭露QPS增高后的秘密

这种方式降低了系统的请求量,但是降低了系统的QPS吗?这种做法系统更安全了还是更危险了? 首先来介绍一下基本概念。 1 .性能的关键指标 系统吞吐量(Throughput) 吞吐量指单位时间内系统处理的...

linuxprobe
2016/09/16
41
0
React Native VS Flutter评测

React Native VS Flutter评测 编辑于 11:34

纪洪波
2018/06/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Flutter 强大的MediaQuery控件

注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 MediaQuery 通常情况下,不会直接将MediaQuery当作一个控件,而是使用MediaQuery.of获取当...

老孟程序员
15分钟前
12
0
【实战】2.如何写周报

如何写周报 一、周报的目的 以一个时间节点为准,同时做到向上汇报和向下汇报。向上汇报要做到整体项目的概况,让上级领导知道当前项目的整体状态。向下汇报要做到我们当前做了什么,紧接着的...

卖小女孩的小火柴
23分钟前
18
0
美颜重磅技术之GPUImage源码分析

说到基于GPU的图像处理和实时滤镜,大家肯定会想到鼎鼎大名的GPUImage,这个项目确实为后续开发提供了很多方便,基本的图像处理工具一应俱全。但是学习借鉴GPUImage的项目结构,可以为我们提...

码农突围
29分钟前
7
0
mapbox

Mapbox是一个可以跨行业使用的开发平台,我们可以利用它对地图进行创建和定制,以解决地图、数据和空间分析等问题。 Leaflet 轻量 WebGIS 前端类库 Leaflet 是一个为建设移动设备友好的互动地...

东东笔记
35分钟前
32
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部