php - NodeJS 比 PHP 慢很多?

标签 php mysql node.js apache performance

我目前在 Apache + PHP + MySQL 下运行一个小型 Web 服务器,并且想探索使用 NodeJS 的选项。服务器实际上做了两件事:

  1. 提供一些静态文件(HTML/CSS/图像资源等)
  2. 查询数据库(仅选择和插入,不更新或删除)

但是,我遇到了一些性能问题,我正试图找出问题所在。为了隔离这个问题,我创建了一个最小的 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 个请求(以免对单线程 Node 应用不利),结果如下:

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 中的代码:

<?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 倍,例如 20 毫秒对 400 毫秒),或者并发级别增加,差异会更大。

我尝试在 Node 应用程序中添加最多 4 个工作程序(我在具有 4 个内核的 Raspberry Pi 2 上运行服务器)并查看它是否有帮助,不幸的是它仍然不接近 PHP 中的结果.你能告诉我我可能做错了什么吗?或者 NodeJS 不是我想要实现的目标的好选择?

[已编辑]

非常感谢您的所有评论。似乎大多数人怀疑问题是由 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

作为总结,以下是我目前得到的结果。只有网络服务器部分不同,而数据库始终是 Raspberry Pi 上的 MySQL:

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,仅供引用)

最佳答案

By using ApacheBench to fire 1000 requests at a concurrency level of 1 (in order not to disadvantage the single-threaded Node app)

通过将并发限制为 1,您实际上剥夺了 Node 的最大优势,即异步 IO。即使 node.js 是单线程的,它也会在等待 db.query 调用时处理其他请求。

因为node没有为此使用系统线程,而是它自己的轻量级调度器,它可以执行并发请求比Apache便宜得多。 Apache 可以以不同的方式配置来处理多个请求(例如,预先 fork 固定数量的进程或事件驱动的 fork ),但是一旦你有一定数量的并发请求,事情就会变慢,因为请求可能不得不等待其他人要完成,即使其他人什么都不做,只是在等待数据库。

因此,总而言之,对于同步执行单个请求,是的,PHP 可能会更快;但是一旦你有足够多的请求超过了 Apache 的配置设置的限制并且也受到你机器大小的影响,你应该会看到 node.js 总体上更快。

关于php - NodeJS 比 PHP 慢很多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41928870/

相关文章:

mysql - int 和 varchar 数据类型需要使用多少字节来优化?

node.js - 缓冲区通常比流处理更快吗?

PHP PDO 清理变量

php - 数据库中的第一行未通过 mysql_fetch_row 或 mysql_fetch_assoc 显示在表中

php - 构建面向对象软件的好资源或书籍

Mysql相关文章

javascript - AngularJS $resource 'GET' 访问正确的 API,但 'PUT' 和 'POST' 不访问

javascript - ExpressJS 不会在 app.use 中触发下一个路由

php - Opencart - 登录后多商店管理员登录重定向到默认商店

php - PHP 中的连接被拒绝错误