Запросы занимают слишком много времени ~ 1 с Node Express API (проблема TTFB) - PullRequest
0 голосов
/ 09 мая 2018

Я получаю запросы от внешнего интерфейса (угловой) и получаю данные через код на стороне сервера (узел js / express app) с использованием SQL Server (mssql). Я полагаю, что проблема заключается в том, что я открываю соединение для каждой конечной точки, которую я нажимаю, и закрываю ее, поэтому это будет первый раз, когда я бью по БД каждый раз - (время до первого байта).

Мое фактическое время загрузки контента по сравнению с этим довольно мало. Я не уверен, как оптимизировать это приложение, чтобы оно имело глобальный пул соединений, и каждая конечная точка просто подключалась к этому пулу. Я могу ошибаться, дайте мне знать! Благодарю.

app.js

const express = require('express')
const bodyParser = require('body-parser')
const path = require('path')
const cors = require('cors')
const compression = require('compression')
const helmet = require('helmet')
const expressSanitizer = require('express-sanitizer')
const jwt = require('jwt-simple');
const subjects = require('./routes/subjects')
const responseTime = require('response-time')

const app = express()
// const app = express.createServer()
const port = 3000

var corsOptions = {
    origin: 'http://localhost:8100',
    optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 
}

//added security
app.use(helmet())

// //set logger
// app.use(logger)

//cors options
app.use(cors(corsOptions))

//body parser middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))

// Mount express-sanitizer here
app.use(expressSanitizer()) // this line follows bodyParser() instantiations

//set static path
app.use(express.static(path.join(__dirname, 'client')))
// app.use(express.static(path.join(__dirname, '../../www')))

//Use response time
app.use(responseTime())

// set our default template engine to "ejs"
// which prevents the need for using file extensions
app.set('view engine', 'ejs')

//gzip compression
app.use(compression())

//set views for error and 404 pages
app.set('views', path.join(__dirname, 'views'))


app.use('/subjects/v1', subjects)

app.listen(port, () => {
    console.log('server started on port 3000')
})

subjects.js

const express = require('express')
const sql = require('mssql')
const router = express.Router()
const config = require('../../services/db')

// Select subjects
router.get('/', (req, res) => {
    new sql.ConnectionPool(config).connect().then(pool => {

        let sqlString = `sql string`

        return pool.request().query(sqlString)
    }).then(result => {
        let rows = result.recordset

        let paginationHeader = {
            totalCount: result.rowsAffected[0],
            pageSize: req.query.pageSize,
            currentPage: req.query.pageNumber
        }
        res.setHeader('X-Pagination', JSON.stringify(paginationHeader))
        res.setHeader('Access-Control-Allow-Origin', '*')
        res.setHeader('Access-Control-Expose-Headers', 'X-Pagination', JSON.stringify(paginationHeader))

        sql.close();
        return new sql.ConnectionPool(config).connect()
    }).then(pool => {

        let sqlString = `sql string `

        return pool.request().query(sqlString)
    }).then(result => {
        let rows = result.recordset

        res.status(200).json(rows);
        sql.close();
    }).catch(err => {
        console.log(".catch ERROR:", err)
        res.status(500).send({ message: err})
        sql.close();
    });

});


// Select id
router.get('/:id', (req, res) => {
    new sql.ConnectionPool(config).connect().then(pool => {

        let sqlString = `SQL string here`

        return pool.request().input('input_parameter', sql.Int, req.params.id).query(sqlString)
    }).then(result => {
        let rows = result.recordset[0]

        res.status(200).json(rows);
        sql.close();
    }).catch(err => {
        res.status(500).send({ message: err})
        sql.close();
    });
})

module.exports = router

РЕДАКТИРОВАТЬ На основе приведенного ниже ответа сокращено время TTFB, но время все еще остается высоким.

subjects.js

const express = require('express')
    const sql = require('mssql')
    const router = express.Router()
    const config = require('../../services/db')
    const connectPool = new sql.ConnectionPool(config).connect()

    // Select subjects
    router.get('/', (req, res) => {
        connectPool.then(pool => {

            let sqlString = `sql string`

            return pool.request().query(sqlString)
        }).then(result => {
            let rows = result.recordset

            let paginationHeader = {
                totalCount: result.rowsAffected[0],
                pageSize: req.query.pageSize,
                currentPage: req.query.pageNumber
            }
            res.setHeader('X-Pagination', JSON.stringify(paginationHeader))
            res.setHeader('Access-Control-Allow-Origin', '*')
            res.setHeader('Access-Control-Expose-Headers', 'X-Pagination', JSON.stringify(paginationHeader))


            return connectPool
        }).then(pool => {

            let sqlString = `sql string `

            return pool.request().query(sqlString)
        }).then(result => {
            let rows = result.recordset

            res.status(200).json(rows);

        }).catch(err => {
            console.log(".catch ERROR:", err)
            res.status(500).send({ message: err})

        });

    });


    // Select id
    router.get('/:id', (req, res) => {
        connectPool.then(pool => {

            let sqlString = `SQL string here`

            return pool.request().input('input_parameter', sql.Int, req.params.id).query(sqlString)
        }).then(result => {
            let rows = result.recordset[0]

            res.status(200).json(rows);

        }).catch(err => {
            res.status(500).send({ message: err})

        });
    })

1 Ответ

0 голосов
/ 09 мая 2018

Вам следует создать пул в виде const в вашем файле subjects.js вне вашего маршрутизатора, таким образом, он создается только один раз. Вот так:

const express = require('express')
const sql = require('mssql')
const router = express.Router()
const config = require('../../services/db')
const pool = new sql.ConnectionPool(config).connect()

Тогда вы бы изменили свои конечные точки, чтобы вместо этого использовать этот пул соединений.

Обычной практикой было бы перенести эту задачу в нечто вроде службы базы данных. Отдельный файл, который устанавливает пул соединений и, как правило, ведение журнала или другие полезные методы, а затем экспортирует их вместе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...