Skip to content

记一次node开发中的“诡异”bug

LYF edited this page Jun 22, 2017 · 6 revisions

一、 2017-06-16 发现是app内的url但是却渲染出了share页的问题

经过分析,正文页下方的sku(g_ab变量)会出现一个风牛马不相及的sku的bug和这个也是同一个问题

以移动正文页为例(即m=show)我们原来的调用流程是这样的:

  render
   .setPageType(pageType)
   .setDebug(debug)
   .setId(id)
   .rende()
   .then(doc => writeDoc(doc))

二、若node中的request是多线程的:

这种调用流程会出现问题,假设说,有两个同时进来的的request

第一个request请求的是show模板,第二个request请求的是share模板

第一个request走上述流程,走到setPageType这一步,把pageType设置为了show

此时,线程切换到另一个request,然后这个request,走到setPageType这一步,把pageType设置为了share

但是第二个线程还没有继续往下执行,CPU就切换到了第一个requst上,此时由于render对象只有一个,

pageType就为share,第一个request就会渲染成share页,本来它是请求的show的。

正文页关联的sku是一个不相干的sku的bug也是类似,

CPU切片导致id乱了,所以拿到的sku就不对

要时刻牢记:如果有多线程争用的话,用一个对象来serve所有的线程,但是每个线程设置属性,那么就会出问题,

某个线程会用到其他线程设置的属性!

三、若node中的request不是多线程的,即单线程 + 异步队列的:

第一个request执行到了rende,此时pageType为show

第二个request执行到了rende,此时pageType为share

由于rende是异步的,如果第一个rende执行的快,则第一个rende的回调在异步队列中是排在第二个rende的回调之前的

所以第一个rende执行回调时,此时pageType为share

所以不管是requst是多线程的还是单线程的,都会出问题

四、解决办法

  1. 每个request都new一个render对象为其serve,这个解决办法的问题会导致内存占用过多,若内存占用多了,GC压力会变大 进而导致CPU占用也高;

  2. 不设置render的属性,而是把这些数据作为rende的参数。目前采用的是这种方法。

Clone this wiki locally