linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Limux发行版SuSE >

NodeJS VS Tomcat搭建高并发静态文件服务器

时间:2016-11-01  来源:未知  作者:linuxsir首页

测试动机

NodeJS因为它的非阻塞I/O和优秀的高并发性能受到越来越多的关注,而且NodeJS的服务器相对于Nginx其搭建非常简单,仅需很少的步骤和设置就可以搭建一个高性能的文件服务器。之前我有一台Tomcat服务器兼做文件下载的功能,后来我在上面部署了一个NodeJS来提供静态文件的下载,然后经过压力测试发现NodeJS在静态文件的服务能力上强于Tomcat很多,主要体现在支持的并发连接数多,处理单个请求快。下面介绍一下我部署NodeJS静态资源文件服务器的过程和压测结果。

这里以Ubuntu系统为例介绍NodeJS服务器的搭建过程

首先需要安装node服务和npm工具,Ubuntu安装命令如下:

$sudo apt install nodejs-legacy
$sudo apt install npm

如果网速还可以,那么安装这两个东西的时间也就在一分钟以内。

然后我们需要为我们的nodejs应用创建一个目录,比如文件夹的名字叫myapp

$ mkdir myapp
$ cd myapp

然后通过 npm init 命令为你的应用创建一个 package.json 文件,作用是初始化Express这个nodeJS框架的

$ npm init

 

敲回车以后需要输入一些东西,全部用默认的就可以,一路回车敲下去

 


输入“yes”后,会在myapp目录下生成一个.json文件,如上图,然后我们安装express框架并将其保存到依赖列表中

$ npm install express --save

然后我们需要创建一个index.js作为nodeJS服务器的入口文件


 

在index.js中,输入如下内容

 

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});
app.use(express.static('public'));

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});


其中

 

app.use(express.static('public'));

 

表示将静态资源文件所在的目录作为参数传递给 express.static 中间件以提供静态资源文件的访问。例如,假设在 /public 目录放置了图片、CSS 和 JavaScript 文件,就可以通过这个配置将public底下的文件映射到url上面


然后我在images目录放了一个图片文件,名字叫pic1.jpg

然后我启动nodeJS服务器,用下面的命令

 

$ node index.js

 

执行这段指令的时候会在控制台打出刚才我在index.js中配置的console函数,控制台输出Example app listening at http://:::3000,表示NodeJS服务器已经成功启动并监听3000端口.

注意:如果此时点击ctrl+c会终止掉nodeJS的服务进程,包括SSH工具

然后通过浏览器访问http://localhost:3000 可以看到浏览器输出一句Hello World!,说明NodeJS服务器运转正常


然后访问我们部署好的静态文件pic1.png只需要访问http://localhost:3000/images/pic1.jpg就可以看到浏览器下载到的图片了,这里要注意public文件夹映射到了3000端口的根目录,也就是说不必在url中输入/public。


下面我们来对比一下tomcat静态文件下载和nodeJS静态文件下载的并发性能,测试工具是apache的ab,测试目标是一个20m左右的apk文件,首先看一下tomcat的表现

 

测试环境:

  • 网络环境:本地回环
  • 测试客户端:本机
  • 被测试服务器:本机
  • 服务器系统:Ubuntu 14.04
  • 服务器配置:Intel(R) Core i7(TM) CPU 3.40GHz 2 CPUS
  • 内存:8GB
  • NodeJS版本: v0.4.12

 

我在服务器上同时部署了80端口的tomcat和3000端口的nodeJS,tomcat的文件目录为webapp/项目目录/release/,tomcat所有设置除了端口以外均采用默认设置,使用两个20MB左右的apk压缩包做测试目标,测试命令分别为:

ab -n1000 -c100 192.168.1.81/release/test.apk

ab -n1000 -c100 192.168.1.81:3000/test.apk

让我们来观察一下控制台输出:

alex@alex-ThinkPad-T430:~$ ab -n1000 -c100 192.168.1.81/release/test.apk
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/


Benchmarking 192.168.1.81 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests




Server Software:        Apache-Coyote/1.1
Server Hostname:        192.168.1.81
Server Port:            80


Document Path:          /release/test.apk
Document Length:        20300487 bytes


Concurrency Level:      100
Time taken for tests:   6.486 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      20300772000 bytes
HTML transferred:       20300487000 bytes
Requests per second:    154.17 [#/sec] (mean)
Time per request:       648.617 [ms] (mean)
Time per request:       6.486 [ms] (mean, across all concurrent requests)
Transfer rate:          3056498.14 [Kbytes/sec] received


Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.8      0       6
Processing:    43  638 333.7    519    2088
Waiting:        0    5  15.8      1      93
Total:         43  639 333.9    520    2091
WARNING: The median and mean for the initial connection time are not within a normal deviation
        These results are probably not that reliable.


Percentage of the requests served within a certain time (ms)
  50%    520
  66%    672
  75%    843
  80%    883
  90%   1085
  95%   1334
  98%   1528
  99%   1781
 100%   2091 (longest request)

我们可以看到1000个请求的总用时是6.486秒,下面再看看nodeJS的表现,nodeJS文件目录为项目目录/public/

同上面测试tomcat一样,测试同一个20m的apk文件,index.js的代码如下:

 

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.use(express.static('public'));

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;
  console.log('Example app listening at http://%s:%s', host, port);
});



 

alex@alex-ThinkPad-T430:~$ ab -n1000 -c100 192.168.1.81:3000/test.apk
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/


Benchmarking 192.168.1.81 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests




Server Software:        
Server Hostname:        192.168.1.81
Server Port:            3000


Document Path:          /test.apk
Document Length:        20300487 bytes


Concurrency Level:      100
Time taken for tests:   18.002 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      20300799000 bytes
HTML transferred:       20300487000 bytes
Requests per second:    55.55 [#/sec] (mean)
Time per request:       1800.207 [ms] (mean)
Time per request:       18.002 [ms] (mean, across all concurrent requests)
Transfer rate:          1101261.94 [Kbytes/sec] received


Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       3
Processing:  1685 1798  43.1   1799    1876
Waiting:       32   53  11.1     52      87
Total:       1685 1798  43.0   1801    1876


Percentage of the requests served within a certain time (ms)
  50%   1801
  66%   1829
  75%   1837
  80%   1840
  90%   1849
  95%   1856
  98%   1862
  99%   1871
 100%   1876 (longest request)

 

NodeJS总耗时为18.002秒,比tomcat的速度慢3倍左右。

从这里可以看出,对于一个不需要执行任何动态代码的静态文件下载,tomcat服务器在默认配置下要比nodeJS在默认配置下高3倍性能。

但是要注意这是使用服务器自己测试服务器自己,所有的流量均走本地回环网卡,也就是说排除了网速对于服务器处理性能的影响,我也是过在局域网内使用另一台linux服务器进行测试,不过由于测试文件是个20m的apk,几乎99.999%的时间都用于网络传输(使用ab能让局域网网速跑满,实测的时候一直保持在11.3MB/s)所以Tomcat和NodeJS的性能差别并不明显。

那么既然nodeJS在文件的并发访问请求方面相对于tomcat并无优势,那么我们为什么还要使用nodeJS来做静态资源服务器呢?

有一个优势是nodeJS提供了方便的url重定向功能,比如我们有好几个文件夹下的静态文件都想通过192.168.1.81:3000/static/xxx.jpg  这样来获取,也就是不加上具体资源文件夹的名字如/css,/js这样,那么通过nodeJS只需几行代码就可以搞定:

 

app.use('/static', express.static('css'));
app.use('/static', express.static('js'));
app.use('/static', express.static('imgs'));

这样就轻松的把所有类型的静态文件都影射到了192.168.1.81:3000/static/这个url下

 

另外,NodeJS在做静态资源文件服务器的时候,还可以监听资源文件夹的文件增删改事件,然后以这些事件做为触发器做一些其他的操作,这个功能使用Tomcat很难完成,例如有人用新增jpg图片文件的事件触发制作了webp压缩图片文件,对于nodeJS只需几行代码就搞定了,我把上面测试的代码稍加改动如下就可以实现监听某个文件夹动作的功能,使用fs模块和chokidar模块分别做测试:

 

var express = require('express');
var chokidar = require('chokidar');//文件监听,需要使用npm安装新模块
var fs = require('fs');//fs文件监听
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.use(express.static('/opt/apache-tomcat-8.0.36/webapps/AndroidOnlinePackage/release'));
app.use(express.static('public'));

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);

	
	// 监控文件夹
	var watcher = chokidar.watch("public", {
	    persistent: true // 保持监听状态
	});

	// 监听增加,修改,删除文件的事件
	watcher.on('all', (event, path) => {
	    switch (event) {
		case 'add':
			console.log('添加文件'+path)
		case 'change':
		    console.log('改变文件'+path)
		    break;
		case 'unlink':
		    console.log('删除文件'+path);
		    break;
		default:
		    break;
	    }
	});

	fs.watch('public', function (event, filename) {//fs的文件监听虽然系统集成该模块,但是使用的时候感觉并不是很准
	  console.log('event is: ' + event);
	  if (filename) {
	    console.log('filename provided: ' + filename);
	  } else {
	    console.log('filename not provided');
	  }
	});
});


其中,如果使用chokidar模块进行监听需要使用npm安装该模块

npm install chokidar

注意在该js文件启动的时候,chokidar会将所有之前存在的文件都认为是‘添加文件’,出发js命令,所以要格外小心。

另外chokidar.watch函数还可以轻松的添加过滤器等设置,用法比fs要简单实用。 

下面关于Node.js的内容你可能也喜欢

在 Ubuntu 14.04/15.04 上安装配置 Node.js v4.0.0  http://www.linuxidc.com/Linux/2015-10/123951.htm

如何在CentOS 7安装Node.js http://www.linuxidc.com/Linux/2015-02/113554.htm

Ubuntu 14.04下搭建Node.js开发环境  http://www.linuxidc.com/Linux/2014-12/110983.htm

Ubunru 12.04 下Node.js开发环境的安装配置 http://www.linuxidc.com/Linux/2014-05/101418.htm

Node.Js入门[PDF+相关代码] http://www.linuxidc.com/Linux/2013-06/85462.htm

Node.js开发指南 高清PDF中文版 +源码 http://www.linuxidc.com/Linux/2014-09/106494.htm

Node.js入门开发指南中文版 http://www.linuxidc.com/Linux/2012-11/73363.htm

Ubuntu 编译安装Node.js http://www.linuxidc.com/Linux/2013-10/91321.htm

Node.js 的详细介绍:请点这里
Node.js 的下载地址:请点这里

友情链接
  • Mozilla发布Firefox 67.0.4,修复沙箱逃逸漏洞
  • 蚂蚁金服正式成为CNCF云原生计算基金会黄金会员
  • Firefox 68将采用Microsoft BITS安装更新
  • OpenSSH增加对存储在RAM中的私钥的保护
  • 谷歌想实现自己的curl,为什么?
  • Raspberry Pi 4发布:更快的CPU、更大的内存
  • Firefox的UA将移除CPU架构信息
  • Ubuntu放弃支持32位应用程序实属乌龙,Steam会否重回Ubuntu怀抱
  • Qt 5.13稳定版发布:引入glTF 2.0、改进Wayland以及支持Lottie动
  • 红帽企业Linux 7现已内置Redis 5最新版
  • Slack进入微软内部禁用服务清单,GitHub也在其列?
  • 安全的全新编程语言V发布首个可用版本
  • Windows Terminal已上架,快尝鲜
  • 阿里巴巴微服务开源生态报告No.1
  • 面世两年,Google地球将支持所有基于Chromium的浏览器
  • 推进企业容器化持续创新,Rancher ECIC千人盛典完美收官
  • CentOS 8.0最新构建状态公布,或于数周后发布
  • Debian移植RISC
  • 微软拆分操作系统的计划初现雏形
  • Oracle发布基于VS Code的开发者工具,轻松使用Oracle数据库
  • Ubuntu 19.10停止支持32位的x86架构
  • 微软为Windows Terminal推出全新logo
  • 联想ThinkPad P系列笔记本预装Ubuntu系统
  • 微软发布适用于Win7/8的Microsoft Edge预览版
  • 启智平台发布联邦学习开源数据协作项目OpenI纵横
  • 经过六个多月的延迟,微软终于推出Hyper
  • ZFS On Linux 0.8.1 发布,Python可移植性工作
  • DragonFly BSD 5.6.0 发布,HAMMER2状态良好
  • Linux Kernel 5.2
  • CentOS 8.0 看起来还需要几周的时间
  • 百度网盘Linux版正式发布
  • PCIe 6.0宣布:带宽翻倍 狂飙至256GB/s
  • PHP 7.4 Alpha 发布,FFI扩展,预加载Opcache以获得更好的性能
  • Canonical将在未来的Ubuntu版本中放弃对32位架构的支持
  • Scala 2.13 发布,改进的编译器性能
  • 微软的GitHub收购了Pull Panda,并且使所有订阅完全免费
  • Windows Subsystem for Linux 2 (WSL 2)现在适用于Windows 10用
  • Debian 10 “Buster”的RISC
  • MariaDB宣布发布MariaDB Enterprise Server 10.4
  • DXVK 1.2.2 发布,带来微小的CPU开销优化
  • DragonFlyBSD 5.6 RC1 发布,VM优化,默认为HAMMER2
  • PrimeNG 8.0.0 发布,支持Angular 8,FocusTrap等
  • GIMP 2.10.12 发布,一些有用的改进
  • 清华大学Anaconda 镜像服务即将恢复
  • Debian GNU/Linux 10 “Buster” 操作系统将于2019年7月6日发布
  • 时时彩论坛
  • 五星体育斯诺克
  • 北单比分直播
  • 河北11选5走势图
  • 福建体彩36选7开奖结果
  • 九龙图库下载