提升-Nodejs-应用性能的-5-个技巧

10次阅读

共计 7110 个字符,预计需要花费 18 分钟才能阅读完成。

Node.js 是全球领先的用 JavaScript——世界上最流行的编程语言创建服务器应用程序的工具。提供 web 服务器和应用服务器的功能,Node.js 被认为是各种以微服务为基础的开发和交付的关键工具。

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

Node.js 是单线程的,并且使用非阻塞 I / O,允许它扩展并支持数以万计的并行操作。它和 NGINX 共享这些架构特性,并解决 C10K 问题——支持超过 10000 个并发连接——NGINX 也可以解决并行操作问题。Node.js 以它的高性能和高开发效率享誉全球。

那么,哪里会出问题呢?

Node.js 有一些薄弱环节和漏洞,这些薄弱环节和漏洞会使得基于 Node 的系统容易出现性能不佳,甚至崩溃的现象。尤其是当基于 Node.js 的 web 应用程序碰到访问量高速增长的时候,问题就会出现得更加频繁。

此外,Node.js 是用于创建和运行产生核心可变网页内容逻辑的强大工具。但它在服务静态内容——例如图像和 JavaScript 文件——以及平衡多个服务器上的负载这些方面还没那么强大。

为了最有效地使用 Node.js,你需要缓存静态内容,代理和平衡多个应用程序服务器负载,并管理客户端、Node.js 和助手——如运行 Socket.IO 的服务器——之间的端口竞争。NGINX 可用于解决这些问题,从而使得它成为了一个 Node.js 性能优化的伟大工具。

使用这些技巧可以提高 Node.js 应用性能:

  1. 实现反向代理服务器
  2. 缓存静态文件
  3. 多服务器的负载均衡
  4. 代理 WebSocket 连接
  5. 实现 SSL / TLS 和 HTTP / 2

注:Node.js 应用性能的快速解决办法是修改你的 Node.js 配置,以充分利用现代多核服务器的优势。你也可以读一读另一篇关于如何让 Node.js 生成单独子进程的文章。

1. 实现反向代理服务器

我们在 NGINX.Inc 的时候,如果看到有应用程序服务器直接接触传入的访问流量,用于高性能网站核心的时候,总会不自觉地有点担忧。这包括许多基于 WordPress 的网站,也包括 Node.js 网站。

Node.js 专为可扩展性而设计,它比大多数应用服务器更易于扩展,它的 web 服务器端可以处理好大量的访问流量。但是 web 服务并不是 Node.js 存在的理由——Node.js 并不是因为这个目的而被构建的。

如果你有一个大流量网站,提高应用程序性能的第一步是在你的 Node.js 服务器前放一个反向代理服务器。这样可以保护 Node.js 服务器直接接触外部访问流量,还能让你灵活使用多个应用程序服务器,平衡负载服务器,缓存内容。

在现有的服务器设置前放 NGINX 作为一个反向代理服务器,是 NGINX 的核心用例,全世界各地已经有数以千万计的网站实施了。

使用 NGINX 作为 Node.js 的反向代理服务器还有一些特定的优势,其中包括:

  • 简化操作权限和端口分配
  • 更有效地服务于静态图像(见第二个小窍门)
  • 成功管理 Node.js 崩溃的情况
  • 减轻 DoS 攻击

注意:这些教程介绍了如何使用 NGINX 作为在 Ubuntu 14.04 或 CentOS 环境中的反向代理服务器,而且可以总览 NGINX 置于 node.js 之前的整体情况。

2. 缓存静态文件

随着基于 Node.js 的网站的使用量的增长,服务器的压力开始越来越大。这时候你要做这两件事情:

  1. 充分利用 Node.js 服务器。
  2. 使得添加应用程序服务器和负载均衡变得容易。

这其实是很容易做到的。一开始就实施 NGINX 作为反向代理服务器,就像第一点技巧中所描述的那样。这样就能轻易实现高速缓存、负载平衡(如果有多个 Node.js 服务器的话)等。

针对 Modulus,一个应用程序容器平台,有一篇非常有用的关于利用 NGINX 增压 Node.js 应用程序性能的文章。由于 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 位置块中,你可能不想要缓存某些内容。例如,你通常不会想要缓存博客平台的管理界面的。以下就是禁用 [或免除] 缓存 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 服务器上的静态文件可以显著减轻 Node.js 应用程序服务器的负载,让它能够达到更佳性能。

本次给大家推荐一个免费的学习群,里面概括移动应用网站开发,css,html,webpack,vue node angular 以及面试资源等。获取资料????????????
对 web 开发技术感兴趣的同学,欢迎加入 Q 群:????????????582735936 ????????????,不管你是小白还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。
最后,祝大家早日学有所成,拿到满意 offer,快速升职加薪,走上人生巅峰。

3. 实现 Node.js 负载平衡

Node.js 应用高性能的真正关键运行多个应用程序服务器和平衡负载。

Node.js 负载平衡可能特别棘手,因为 Node.js 允许运行在 web 浏览器上的 JavaScript 代码和运行在 Node.js 应用服务器上的 JavaScript 代码做高水平的交互,同时使用 JSON 对象作为数据交换的介质。这意味着,一个给定的客户会话会持续运行在特定的应用程序服务器上,并且会话持久性用多个应用程序服务器天然地难以实现。

Internet 和 web 的主要优点之一就是高度无国界,其中包括通过任意服务器访问请求文件来满足客户端请求。Node.js 颠覆了无国界,并且在有状态的环境中——同一服务器始终如一地响应来自任意特定客户端的请求——效果最好。

通过 NGINX Plus,而非开源 NGINX 软件,可以最好地满足这个需求。NGINX 的两个版本颇为相似,但一个主要区别就是它们对负载平衡算法的支持不同。

NGINX 支持无状态的负载均衡方法:

  • 循环。新的请求会去往列表中的下一个服务器。
  • 最少的连接。新的请求会去到活跃连接最少的服务器。
  • IP Hash。新的请求会去往哈希分配客户端 IP 地址的服务器。

只是这些方法中的一种,IP Hash,可靠地发送指定客户端请求到同一服务器,有利于 Node.js 应用程序。然而,IP Hash 很容易导致某台服务器收到的请求数量不成比例,在牺牲其他服务器的代价下,正如这一篇博客中描述的负载均衡技术那样。此方法支持的有状态是以牺牲潜在不理想的跨服务器资源的请求分配为代价的。

不同于 NGINX,NGINX Plus 支持会话持久性。在使用会话持久性的时候,同一服务器还能可靠地接收来自指定客户端的所有请求。Node.js 的优势——在客户端和服务器之间有状态的通信,以及 NGINX Plus 的优势——高级负载均衡能力,都达到最大化。

所以,你可以使用 NGINX 或 NGINX Plus 来支持多个 Node.js 服务器的负载均衡。只有 NGINX 才有可能让你最大化地实现负载均衡性能和友好的 Node.js 有状态性。内置于 NGINX 的应用健康检查以及监控功能也很有用。

NGINX Plus 还支持会话维持,因此允许应用程序服务器在它采取停止服务的请求之后,还能优雅地完成当前会话。

4. 代理 WebSocket 连接

HTTP,在所有版本里,是专为“pull”通信——来自于服务器的客户端请求文件设计的。WebSocket 是一个允许“push”和“push/pull”通信的工具,即服务器可以主动发送客户端没有请求的文件。

WebSocket 协议可以更容易地支持客户端和服务器之间更坚固的相互作用,同时减少传输的数据量并最小化等待时间。当需要时,可以实现全双工传输连接,也就是说根据需要客户和服务器都可以发起并接收请求。

WebSocket 协议具有强大的 JavaScript 接口,因此非常适合作为应用服务器的 Node.js——而且,对于事务量不多的 web 应用程序,也可以作为 web 服务器。当事务量增加,那么在客户端和 Node.js web 服务器之间,多个应用服务器之间使用 NGINX 或 NGINX Plus 插入 NGINX 就有必要了。

Node.js 通常与 Socket.IO 联合使用,Socket.IO 是一个 WebSocket API,它在 Node.js 应用程序中很受欢迎。这可能会导致 port 80(对于 HTTP)或 port 443(对于 HTTPS)变得相当拥挤,而解决方法就是代理 Socket.IO 服务器。你可以使用 NGINX 作为代理服务器中,就像前面说的那样,并且还获得其他的功能,例如静态文件缓存,负载均衡等。

以下就是作为 server.js node 应用程序文件监听 port 5000 的代码。它担当了代理服务器(而不是 web 服务器)的角色,并路由请求到正确的端口:

var io = require('socket.io').listen(5000);
io.sockets.on('connection', function (socket) {socket.on('set nickname', function (name) {socket.set('nickname', name, function () {socket.emit('ready');
    });
  });
  socket.on('msg', function () {socket.get('nickname', function (err, name) {console.log('Chat message by', name);
    });
  });
});

var socket = io(); // 这是你的初始化代码。

有关完整的介绍,包括 NGINX 配置,请参阅此博客文章。有关这一类更深入的 web 应用程序潜在架构和基础设施问题,请参阅此博客文章。

5. 实现 SSL / TLS 和 HTTP / 2

越来越多的网站使用 SSL / TLS 来保护网站上所有用户的交互。你可以决定是否以及何时做出这个举动,但如果你选择了这么做,那么 NGINX 有两种方式来支持这个转变:

  1. 你可以在 NGINX 里终止 SSL / TLS 连接到客户端,如果你设置了 NGINX 作为反向代理的话。Node.js 服务器使用 Nginx 反向代理服务器来来回回地发送和接收未加密的请求和内容。
  2. 早期迹象表明,使用 HTTP / 2——新的 HTTP 协议的新版本——可以在很大程度上或完全抵消使用 SSL / TLS 强加的性能损失。NGINX 支持 HTTP / 2,你可以终止 HTTP / 2 和 SSL,而在 Node.js 应用服务器中无需做任何改变。

在你采取这些实现步骤的时候,你还需要更新在 Node.js 配置文件中的 URL,建立和完善在 NGINX 配置中的安全连接,必要时还可以使用 SPDY 或 HTTP / 2。添加 HTTP / 2 支持意味着浏览器版本使用新的协议支持 HTTP / 2 与应用程序进行通信:老版本的浏览器使用 HTTP / 1.x。

下面的配置代码适用于使用 SPDY 的 Ghost 博客。它包括一些高级功能,如 OCSP stapling。使用 NGINX 用于 SSL 终端,包括 OCSP stapling 选项,看这里。对于同一主题的概述,看这里。

你需要做的轻微改动就是配置 Node.js 应用程序,从 SPDY 升级到 HTTP / 2,时间可以是现在,也可以是 2016 年初 SPDY 支持消失的时候。

server {
   server_name domain.com;
   listen 443 ssl spdy;
   spdy_headers_comp 6;
   spdy_keepalive_timeout 300;
   keepalive_timeout 300;
   ssl_certificate_key /etc/nginx/ssl/domain.key;
   ssl_certificate /etc/nginx/ssl/domain.crt;
   ssl_session_cache shared:SSL:10m;  
   ssl_session_timeout 24h;           
   ssl_buffer_size 1400;              
   ssl_stapling on;
   ssl_stapling_verify on;
   ssl_trusted_certificate /etc/nginx/ssl/trust.crt;
   resolver 8.8.8.8 8.8.4.4 valid=300s;
   add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';
   add_header X-Cache $upstream_cache_status;
   location / {
        proxy_cache STATIC;
        proxy_cache_valid 200 30m;
        proxy_cache_valid 404 1m;
        proxy_pass http://ghost_upstream;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_ignore_headers Set-Cookie;
        proxy_hide_header Set-Cookie;
        proxy_hide_header X-powered-by;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Host $http_host;
        expires 10m;
    }
    location /content/images {
        alias /path/to/ghost/content/images;
        access_log off;
        expires max;
    }
    location /assets {
        alias /path/to/ghost/themes/uno-master/assets;
        access_log off;
        expires max;
    }
    location /public {
        alias /path/to/ghost/built/public;
        access_log off;
        expires max;
    }
    location /ghost/scripts {
        alias /path/to/ghost/core/built/scripts;
        access_log off;
        expires max;
    }
    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";
        proxy_set_header X-Forwarded-Proto https;
    }
}

结论

本文介绍了一些最重要的可以在 Node.js 应用程序布置的性能改进。它着重于添加到应用程序的 NGINX 以及 Node.js——通过使用 NGINX 作为反向代理服务器,缓存静态文件,负载均衡,代理 WebSocket 连接,并终止 SSL / TLS 和 HTTP / 2 协议。

NGINX 和 Node.js 的结合,被广泛认为是一种创建新的微服务型应用程序或增加灵活性和性能到现有的基于 SOA 的使用 Java 或 Microsoft .NET 应用的方法。这篇文章可以帮助你优化 Node.js 应用程序,让 Node.js 和 NGINX 的伙伴关系为你所用。

本次给大家推荐一个免费的学习群,里面概括移动应用网站开发,css,html,webpack,vue node angular 以及面试资源等。获取资料????????????
对 web 开发技术感兴趣的同学,欢迎加入 Q 群:????????????582735936 ????????????,不管你是小白还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。
最后,祝大家早日学有所成,拿到满意 offer,快速升职加薪,走上人生巅峰。

正文完
 0