Javascript 优化Express+Swig HTML呈现时间

Javascript 优化Express+Swig HTML呈现时间,javascript,node.js,express,nginx,swig-template,Javascript,Node.js,Express,Nginx,Swig Template,我面临着一个关键问题 我的应用程序架构描述如下: nginx->webappexpress/nodejs->api-jetty/java->mysql API应用程序经过了很好的优化,因此这里不需要提及它的性能~200毫秒/秒,100毫秒/秒 我的web应用程序: 在做概要文件日志时,我注意到Swig模板引擎的HTML呈现时间阻塞了太长的I/O,所以它显著增加了其他挂起请求的等待时间 对于呈现1MB文本/html响应,Swig模板需要约250ms 以下是我的压力测试结果: $ node stre

我面临着一个关键问题

我的应用程序架构描述如下:

nginx->webappexpress/nodejs->api-jetty/java->mysql

API应用程序经过了很好的优化,因此这里不需要提及它的性能~200毫秒/秒,100毫秒/秒

我的web应用程序:

在做概要文件日志时,我注意到Swig模板引擎的HTML呈现时间阻塞了太长的I/O,所以它显著增加了其他挂起请求的等待时间

对于呈现1MB文本/html响应,Swig模板需要约250ms

以下是我的压力测试结果:

$ node stress.js 20
Receive response [0] - 200 - 431.682654ms
Receive response [1] - 200 - 419.248099ms
Receive response [2] - 200 - 670.558033ms
Receive response [4] - 200 - 920.763105ms
Receive response [3] - 200 - 986.20115ms
Receive response [7] - 200 - 1521.330763ms
Receive response [5] - 200 - 1622.569327ms
Receive response [9] - 200 - 1424.500137ms
Receive response [13] - 200 - 1643.676996ms
Receive response [14] - 200 - 1595.958319ms
Receive response [10] - 200 - 1798.043086ms
Receive response [15] - 200 - 1551.028243ms
Receive response [8] - 200 - 1944.247382ms
Receive response [6] - 200 - 2044.866157ms
Receive response [11] - 200 - 2162.960215ms
Receive response [17] - 200 - 1941.155794ms
Receive response [16] - 200 - 1992.213563ms
Receive response [12] - 200 - 2315.330372ms
Receive response [18] - 200 - 2571.841722ms
Receive response [19] - 200 - 2523.899486ms
AVG: 1604.10ms
如您所见,请求越晚,等待时间越长

当我返回响应代码而不是呈现HTML时,通过修改一些代码:

function render(req, res, next, model) {
    return res.status(200).end(); // add this line
    res.render('list', model);
}
压力测试输出更改为:

$ node stress.js 20
Receive response [0] - 200 - 147.738725ms
Receive response [1] - 200 - 204.656645ms
Receive response [2] - 200 - 176.583635ms
Receive response [3] - 200 - 218.785931ms
Receive response [4] - 200 - 194.479036ms
Receive response [6] - 200 - 191.531871ms
Receive response [5] - 200 - 265.371646ms
Receive response [7] - 200 - 294.373466ms
Receive response [8] - 200 - 262.097708ms
Receive response [10] - 200 - 282.183757ms
Receive response [11] - 200 - 249.842496ms
Receive response [9] - 200 - 371.228602ms
Receive response [14] - 200 - 236.945983ms
Receive response [13] - 200 - 304.847457ms
Receive response [12] - 200 - 377.766879ms
Receive response [15] - 200 - 332.011981ms
Receive response [16] - 200 - 306.347012ms
Receive response [17] - 200 - 284.942474ms
Receive response [19] - 200 - 249.047099ms
Receive response [18] - 200 - 315.11977ms
AVG: 263.30ms
我以前尝试过一些解决方案,但没有一个能够缩短响应时间:

在我的服务器中使用2个worker 使用 启动4个节点进程

$ PORT=3000 forever start app.js
$ PORT=3001 forever start app.js
$ PORT=3002 forever start app.js
$ PORT=3003 forever start app.js
nginx.conf

upstream webapp {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
}

server {
    listen 80;

    location / {
        proxy_pass http://webapp;
    }

    [...]
}
我认为上述所有解决方案都会提供多个进程/线程,在执行繁重的任务(如HTML渲染)时不会相互阻塞,但结果与我的预期不同:等待时间没有减少。尽管日志显示请求实际上由多个进程/线程提供服务

我有没有遗漏任何要点


或者,您能给我展示另一种减少等待时间的解决方案吗?

创建集群不会减少响应时间,但它允许您并行运行响应,而不会阻塞IO。当然,为了正确地使用集群,您需要为主机设置自己的逻辑,以便有效地控制工作进程。添加一个没有正确逻辑的集群永远不会给您带来任何真正的好处。为了使这项工作正常进行,您的主机需要处理所有传入的请求,并将它们分发给工作人员进行处理。然后工作人员将结果发送回主控台,由主控台处理其余部分。

我认为您应该检查以下几点:

->避免使用模板缓存阻塞IO

->将模板拆分为多个部分并使用按需加载


->收集数据的时间只涉及一次?

这里真正的答案是缓存

每次重读时都要重新呈现页面吗?我不认为模板数据每分钟都在变化,如果有的话

解决方案可以是编写两个充当三明治的中间件,渲染的路由应该具有如下结构:

要求 从缓存中间件获取 数据库 swig模板 放入缓存中间件 响应中间件 put-in-cache应该写入一个非常快速的缓存数据库REDIS非常适合这样的情况:编译后的模板在1分钟内过期,并使用url或其他更聪明的机制(如用户ID请求)或标头对其进行索引


get-from-cache将在每个HTTP请求上查询REDIS的索引查询,如果它找到已编译的模板,它应该只是res.send-away

没有简单的答案来优化渲染时间。这个问题太宽泛了。您真正想要做的是防止脚本阻塞IO,您可以通过创建集群并使用主节点将处理负载分配给工作节点来做到这一点。主机的IO永远不会被阻塞,并且可以同时处理多个请求。问题是,尽管我创建了集群/线程,但性能并没有得到改善
$ PORT=3000 forever start app.js
$ PORT=3001 forever start app.js
$ PORT=3002 forever start app.js
$ PORT=3003 forever start app.js
upstream webapp {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
}

server {
    listen 80;

    location / {
        proxy_pass http://webapp;
    }

    [...]
}