5个提高性能的Node.JS应用Tips

Bryan Huges在twitter中写道:如果你没有在你的node服务前加一层nginx,那么你这么做可能是不正确的。

Node.js在用世界最著名的语言javascript去创建服务端应用的工具中处于领先地位。它同时提供了一个web服务器又和一个应用服务器的的功能。现在Node.js被当做开发和交付各类微服务的一个关键工具。

Node.js可以替代或增强Java或.NET用作后端应用程序的开发。

Node.js使用了单线程非阻塞IO,使其能够扩展并支持数万并发操作。Nginx也是使用这种架构去解决C10K(支持多于10000个并发连接)问题。Node.js以其高性能和开发人员的生产力而著称。

那哪里错了呢?

Node.js也有一些薄弱的环节和缺点,导致基于Node的系统容易表现的性能不好甚至崩溃。当问题频繁出现时,会引起基于Node的web应用程序流量大增。

此外,Node.js是一个强大的工具能用来创建和运行应用逻辑,为你的网页产生核心的变量。但是它不那么擅长服务静态内容(比如图片,javascript文件)、在多个服务器之间进行负载均衡。

为了最大化发挥Node.js的作用,你需要缓存静态内容,在多个应用服务器之间进行代理,进行负载均衡。还需要管理客户端、Node.js以及其他服务(比如一个运行Socket.IO的服务)之间的端口争用。Nginx可以被用来做这些,使之成为Node.js性能优化的一个很棒的工具。

使用这些tips提高Node.js应用的性能

  1. 部署一个反向代理服务器
  2. 缓存静态文件
  3. 在多个服务器之间进行负载均衡
  4. 代理WebSocket连接
  5. 实现SSL/TLS和HTTP/2

: 一种快速解决Node.js应用程序的性能的办法是修改你的Node.js的配置,以充分利用现代多核服务器的优势。看看这篇文章,以了解如何将Node.js的派生单独的子进程(在你的web服务器上子进程等于CPU的数量),每个进程都能充分利用一个CPU,给你的应用一个很大的性能提升

##1. 部署一个反向代理服务器

当我们看到应用服务器直接暴露在互联网上被当作高性能网站的核心传入流量,我们(Nginx Inc.)总是有点恐惧。比如包括许多基于WordPress的,还有Node.js的网站。

Node.js的扩展性在更大程度上比大多数应用服务器设计的更好,它的web服务器可以很好的处理大量的互联网流量。但是web服务不是Node.js构建的适合做的。

如果你有一个高流量的站点,提高应用性能的第一步是在你的Node.js服务前放一台代理服务器,这样可以防止你的Node.js服务直接暴露在互联网的流量中,并且在你使用多台应用服务器进行负载均衡时有很高的灵活性在,并且可以用内部链接去缓存内容。

Proxy Reverse

在现有的服务器前方搭建一台Nginx作为反向代理服务器,是nginx的一个核心用例,世界上已经有数以千万计的站点都这么用了。

这有一篇特别的高级的文章使用Nginx作为一个Node.js的反向代理服务器 包括:

  • 简化操作权限和端口分配
  • 更有效地服务于静态图像(见下一个tips)
  • 成功管理Node.js崩溃
  • 缓解Dos攻击

: 这些教程讲解如何使用NGINX作为在Ubuntu14.04或CentOS的环境反向代理服务器,而且对那些想把NGINX放到node.js前的人来说是很有用的概述。

##2. 缓存静态文件
随着一个基于Node.js的站点的成长,服务器开始显示的疲惫。这有亮点你希望做的:

  1. 最大化的使用Node.js服务器
  2. 尽可能简单的添加应用服务器,并且它们之间可以进行负载均衡

这实际上做起来很简单,就像上面第一个tips里面说的那样,部署一个Nginx作为反向代理,很简单就实现了缓存,负载均衡(当你有多台Node.js服务器的时候)等功能。

一个应用容器平台Modulus(用作系数压测)的网站有一篇文章压力测试nginx和Node.js应用的性能,作者的网站能够为平均每秒服务近900请求。使用NGINX作为反向代理服务器,提供静态内容,同一站点提供超过每秒1600请求 - 近2倍的性能提升。

如果再性能加倍你就要花费时间去采取额外的措施,以适应近一步的增长,比如审查(或者改进)一下你站点的设计,优化一下你的应用代码或者部署更多的应用服务器。

以下是配置代码,适用于Modulus上运行的网站

server {
      listen 80;
      server_name static-test-47242.onmodulus.net;

      root /mnt/app;
      index index.html index.htm;

      location /static/ {
           try_files $uri $uri/ =404;
      }

      location /api/ {
           proxy_pass http://node-test-45750.onmodulus.net;
      }
}

这篇详细的文章来自于NGINX公司的Patrick Nommensen,解释了他如何缓存他运行的Ghost开源博客平台Node.js应用程序的静态内容。虽然有些细节是Ghost特有的,你可以复用一些代码到很多其他的Node.js应用程序。

例如,在Nginx的location块中,你可能会想不缓存某些内容。你通常不会想要缓存博客平台的管理界面,例如。下面是禁用[或不缓存]Ghost管理界面的缓存配置代码:

location ~ ^/(?:ghost|signout) { 
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://ghost_upstream;
    add_header Cache-Control "no-cache, private, no-store,
    must-revalidate, max-stale=0, post-check=0, pre-check=0";
}

有关提供静态内容的一般信息,请参阅NGINX Plus管理指南。管理员指南包括实现更快的性能配置说明,尝试查找文件时相应成功或失败的多种选项,达到更快的性能的优化方法。

缓存静态文件的NGINX服务器显著从Node.js的应用程序服务器卸载一部分工作,使其达到更高的性能。

https://www.nginx.com/blog/5-performance-tips-for-node-js-applications/