Мы столкнулись с проблемой Nodejs времени ответа - PullRequest
1 голос
/ 26 марта 2020

Мы сталкиваемся с проблемой Nodejs времени отклика, когда мы достигаем около 100 онлайн-пользователей, наше время отклика достигает 10 с. Я думаю, что есть грязный код, который замедляет работу моего приложения. Есть ли способ отследить проблему (в коде ведьмы мое приложение замедляется) в моем приложении nodejs? Я использую nodejs, expressjs, mongodb и nginx

NGINX:

upstream http_backend {
   server 127.0.0.1:8087;
   keepalive 32;
}

server {
    listen 80;
    listen [::]:80;
    server_name  cdn.amjilt.com;
    return 301 https://$server_name$request_uri;
}
server {
    listen 7070;
    listen [::]:7070;
    server_name  cdn.amjilt.com;
    return 301 https://$server_name$request_uri;
}


server {
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2 default_server;
    server_name  cdn.amjilt.com;

    ssl on;
    ssl_certificate /etc/nginx/cert/media/media.crt;
    ssl_certificate_key /etc/nginx/cert/media/media.key;

    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    client_max_body_size 500M;
    client_body_buffer_size 500M;
    proxy_buffer_size   16M;
    proxy_buffers   24 8M;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;

    location /images{
            root /home/ubuntu/projects/amjilt_media/static;
    }
    location /tmp{
            root /home/ubuntu/projects/amjilt_media/static;
    }
    location /images/uploads{
            root /home/ubuntu/projects/amjilt_media/static;
    }
    location /images/avatar{
            root /home/ubuntu/projects/amjilt_media/static;
    }
    location /api/video/show{
            expires off;
            proxy_buffering off;
            chunked_transfer_encoding on;
            proxy_pass http://http_backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
    }
    location /api/video/mobile{
            expires off;
            proxy_buffering off;
            chunked_transfer_encoding on;
            proxy_pass http://http_backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
    }
    location /api/pdf/show{
            expires off;
            proxy_buffering off;
            chunked_transfer_encoding on;
            proxy_pass http://http_backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
    }
    location / {
            proxy_pass http://localhost:8087;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
    }

    # gzip
    gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript;
    gzip on;
}

Маршрутизатор:

let flname = '../../..' + video.path;
var file = path.resolve(__dirname, flname);
fs.stat(file, function(err, stats) {
    if (err) {
        winston.error('/video/show/:id fs.stat error ',err);
        if (err.code === 'ENOENT') {
            // 404 Error if file not found
            res.status(404).json({msg: 'log.n_request'});
        }
        res.status(404).json({msg: 'log.n_request'});
    }
    var range = req.headers.range;
    if (!range) {
        var stat_ = fs.statSync(file)
        var header = {
            'Content-Length': stat_.size,
            'Content-Type': (!req.useragent.isSafari ? token : 'mp4'),
        }
        res.writeHead(200, header)
        var stream = fs.createReadStream(file)
            .on("open", function () {
                stream.pipe(res);
            }).on("error", function (err) {
                res.end(err);
            });
    }else{
        var positions = range.replace(/bytes=/, "").split("-");
        var start = parseInt(positions[0]);
        if(isNaN(start)){
            start = 0;
        }
        var total = stats.size;
        var end = positions[1] ? parseInt(positions[1]) : (start+102400);
        if(isNaN(end)){
            end = start+102400;
        }
        if(total <= end){
            end = total-1;
        }
        var chunksize = (end - start) + 1;

        res.writeHead(206, {
            "Content-Range": "bytes " + start + "-" + end + "/" + total,
            "Accept-Ranges": "bytes",
            "Content-Length": chunksize,
            "Content-Type": "video/mp4"
        });

        var stream = fs.createReadStream(file, {start: start, end: end})
            .on("open", function () {
                stream.pipe(res);
            }).on("error", function (err) {
                res.end(err);
            });
    }
});

1 Ответ

0 голосов
/ 26 марта 2020

Вы должны удалить fs.statSync(). Это засоряет событие l oop, поэтому ваш сервер застревает при обработке одного запроса за раз при каждом его запуске. И, как оказалось, вы можете просто полностью удалить вызов, потому что вы уже вызывали fs.stat() для того же файла ранее в функции и можете просто использовать эти результаты.

Я также добавил пару return операторы после отправки ошибок, так как вы не хотите, чтобы остальная часть кода выполнялась после отправки ошибки:

let flname = '../../..' + video.path;
var file = path.resolve(__dirname, flname);
fs.stat(file, function(err, stats) {
    if (err) {
        winston.error('/video/show/:id fs.stat error ',err);
        if (err.code === 'ENOENT') {
            // 404 Error if file not found
            res.status(404).json({msg: 'log.n_request'});
            return;
        }
        res.status(404).json({msg: 'log.n_request'});
        return;
    }
    var range = req.headers.range;
    if (!range) {
        var header = {
            'Content-Length': stats.size,
            'Content-Type': (!req.useragent.isSafari ? token : 'mp4'),
        }
        res.writeHead(200, header)
        var stream = fs.createReadStream(file)
            .on("open", function () {
                stream.pipe(res);
            }).on("error", function (err) {
                res.end(err);
            });
    }else{
        var positions = range.replace(/bytes=/, "").split("-");
        var start = parseInt(positions[0]);
        if(isNaN(start)){
            start = 0;
        }
        var total = stats.size;
        var end = positions[1] ? parseInt(positions[1]) : (start+102400);
        if(isNaN(end)){
            end = start+102400;
        }
        if(total <= end){
            end = total-1;
        }
        var chunksize = (end - start) + 1;

        res.writeHead(206, {
            "Content-Range": "bytes " + start + "-" + end + "/" + total,
            "Accept-Ranges": "bytes",
            "Content-Length": chunksize,
            "Content-Type": "video/mp4"
        });

        var stream = fs.createReadStream(file, {start: start, end: end})
            .on("open", function () {
                stream.pipe(res);
            }).on("error", function (err) {
                res.end(err);
            });
     }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...