>提供一些静态文件(HTML / CSS /图像资源等)
>查询数据库(仅选择并插入,不更新或删除)
但是,我遇到了一些性能问题,我试图找出问题所在.为了隔离问题,我创建了一个最小的NodeJS应用程序,它运行对MysqL的查询,并以JSON的形式返回50行数据.以下是我的代码:
var express = require('express'); var compression = require('compression'); var MysqL = require('MysqL'); var db = MysqL.createPool({ host: <host>,user: <user>,password: <password>,database: <database>,debug: false }); var app = express(); app.use(compression()); app.get('/data',function(req,res) { var sql = 'SELECT column_1,column_2 FROM table'; db.query(sql,function (error,rows,fields) { if (error) throw error; res.json(rows); }); }); app.listen(3000,function () { console.log("Running on port 3000."); });
通过使用ApacheBench在并发级别为1的1000个请求(为了不影响单线程节点应用程序),结果如下:
Concurrency Level: 1 Time taken for tests: 10.377 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 3057000 bytes HTML transferred: 2829000 bytes Requests per second: 96.37 [#/sec] (mean) Time per request: 10.377 [ms] (mean) Time per request: 10.377 [ms] (mean,across all concurrent requests) Transfer rate: 287.69 [Kbytes/sec] received
<?PHP $hostname = <host>; $username = <user>; $password = <password>; $database = <database>; try { $db_handler = new PDO('MysqL:host=' . $hostname . ';dbname=' . $database,$username,$password); } catch (PDOException $e) { throw new Exception('[ERROR] Unable to connect to the database.'); } $sql = 'SELECT column_1,column_2 FROM table'; $statement = $db_handler->prepare($sql,array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); $statement->execute(); $rows = array(); while ($row = $statement->fetch(PDO::FETCH_ASSOC)){ $rows[] = $row; } print json_encode($rows); $db_handler = null; ?>
而ApacheBench的结果:
Concurrency Level: 1 Time taken for tests: 6.726 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 3023000 bytes HTML transferred: 2829000 bytes Requests per second: 148.68 [#/sec] (mean) Time per request: 6.726 [ms] (mean) Time per request: 6.726 [ms] (mean,across all concurrent requests) Transfer rate: 438.92 [Kbytes/sec] received
从上述结果可以看出,PHP比NodeJS快得多.如果触发更复杂的查询(差异可能是20次,如20ms对400ms),或者并发级别增加,则差异更大.
我已经尝试添加最多4名工作人员(我正在运行Raspberry Pi 2的服务器,它有4个核心)到Node应用程序,看看它是否有帮助,不幸的是它仍然不接近PHP的结果.你能告诉我可能做错了什么吗?或者NodeJS只是不是我想要实现的好选择?
[EDITED]
非常感谢您的意见.似乎大多数人怀疑这个问题是由NodeJS MysqL驱动造成的.我也做了一些更多的测试,以确定是否如此,我不小心发现一些非常有趣的东西.
通过在另一台PC(Core 2 Duo E7200)上运行相同的Node应用程序,但是在Raspberry Pi上连接到同一个MysqL,结果其实是相当不错的:
Concurrency Level: 1 Time taken for tests: 2.705 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 3057000 bytes HTML transferred: 2829000 bytes Requests per second: 369.71 [#/sec] (mean) Time per request: 2.705 [ms] (mean) Time per request: 2.705 [ms] (mean,across all concurrent requests) Transfer rate: 1103.72 [Kbytes/sec] received
作为比较,我还在该PC上运行Apache服务器,连接到Raspberry Pi上的同一个MysqL,结果如下:
Concurrency Level: 1 Time taken for tests: 6.297 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 3034000 bytes HTML transferred: 2829000 bytes Requests per second: 158.80 [#/sec] (mean) Time per request: 6.297 [ms] (mean) Time per request: 6.297 [ms] (mean,across all concurrent requests) Transfer rate: 470.50 [Kbytes/sec] received
作为总结,下面是我到目前为止的结果.只有Web服务器部分是不同的,而数据库总是MysqL在Raspberry Pi上:
Server Time Taken Node (Pi) 10.337s PHP (Pi) 6.726s Node (PC) 2.705s PHP (PC) 6.297s
PHP的结果似乎在两个服务器上或多或少相同,而NodeJS的结果变化很大.基于上面的结果,在我看来,NodeJS对cpu性能更敏感,或者说另一个字是cpu密集型? (我正在使用的NodeJS版本是v6.9.4,只是FYI)
By using ApacheBench to fire 1000 requests at a concurrency level of 1 (in order not to disadvantage the single-threaded Node app)
通过将并发限制为1,您实际上是消除了节点最大的优势,即异步IO.即使node.js是单线程的,它将在等待db.query调用时处理其他请求.
因为节点没有为此使用系统线程,而是自己的轻量级调度程序,它可以执行比Apache要便宜的并发请求. Apache可以以不同的方式配置来处理多个请求(例如,预先分配固定数量的进程或事件驱动的分支),但是一旦您有一定数量的并发请求,事情会减慢,因为请求可能需要等待其他人即使完成,即使那些别无选择,只能等待数据库.
所以,总而言之,为了同步执行单个请求,是PHP可能会更快;但是一旦您有足够的请求超过了Apache配置所设置的限制,并且受到计算机大小的影响,您将看到node.js整体更快.