偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

如何優(yōu)化你的 Node.js API

開發(fā) 前端
在這篇文章中,我將講解如何優(yōu)化使用 Node.js 編寫的 API。

前提條件

想要充分了解本文內(nèi)容,你必須了解以下概念:

  • Node.js 的設(shè)置與安裝
  • 如何使用 Node 創(chuàng)建 API
  • 如何使用 Postman
  • JavaScript 的 async/await 工作原理
  • Redis 的基礎(chǔ)操作

API 優(yōu)化到底指的是什么

優(yōu)化包含了改善 API 的響應(yīng)時(shí)間。響應(yīng)時(shí)間越短,API 的速度越快。

我將在本文分享一些技巧,幫助你縮短響應(yīng)時(shí)間、降低延遲、管理錯(cuò)誤和吞吐量,并且最大限度地減少 CPU 和內(nèi)存的使用。

如何優(yōu)化 Node.js 的 API

1. 始終使用異步函數(shù)

異步函數(shù)就像 JavaScript 的心臟。因此,優(yōu)化 CPU 使用率的最佳方法就是編寫異步函數(shù)來(lái)執(zhí)行非阻塞 I/O 操作。

I/O 操作包括對(duì)數(shù)據(jù)的讀和寫。它可以在數(shù)據(jù)庫(kù)、云存儲(chǔ)或者任何本地磁盤上進(jìn)行。

在大量使用 I/O 操作的應(yīng)用使用異步函數(shù)可以提高效率。因?yàn)橛捎跊]有阻塞 I/O,當(dāng)一個(gè)請(qǐng)求在做輸入/輸出操作的時(shí)候,CPU 可以同時(shí)處理多個(gè)請(qǐng)求。

舉例如下:

var fs = require('fs');
// 執(zhí)行阻塞I/O
var file = fs.readFileSync('/etc/passwd');
console.log(file);
// 執(zhí)行非阻塞I/O
fs.readFile('/etc/passwd', function(err, file) {
if (err) return err;
console.log(file);
});
  • 使用 Node 包fs來(lái)處理文件
  • readFileSync()是同步函數(shù),會(huì)在執(zhí)行完成前阻塞線程
  • readFile()是異步函數(shù),會(huì)立刻返回并在后臺(tái)運(yùn)行

2. 避免在 API 中使用 session 和 cookie,僅在 API 響應(yīng)中發(fā)送數(shù)據(jù)

當(dāng)我們使用 cookie 或者 session 來(lái)存儲(chǔ)臨時(shí)狀態(tài)的時(shí)候,會(huì)占用非常多的服務(wù)器內(nèi)存。

現(xiàn)在通用無(wú)狀態(tài) API,并且也有 JWT、OAuth 等驗(yàn)證機(jī)制。驗(yàn)證令牌保存在客戶端以便服務(wù)器管理狀態(tài)。

JWT 是基于 JSON 的用于 API 驗(yàn)證的安全令牌。JWT 可以被看到,但一旦發(fā)送就無(wú)法修改。JWT 只是一個(gè)序列并沒有加密。OAuth 不是 API 或服務(wù)——相反,它是授權(quán)的開放標(biāo)準(zhǔn)。OAuth 是一組用于獲取令牌的標(biāo)準(zhǔn)步驟。

同時(shí),也不要把時(shí)間浪費(fèi)在使用 Node.js 來(lái)服務(wù)靜態(tài)文件。這方面 NGINX 和 Apache 做得更好。

使用 Node 搭建 API 的時(shí)候,不要在響應(yīng)中發(fā)送完整的 HTML 頁(yè)面。當(dāng)僅有數(shù)據(jù)通過(guò) API 發(fā)送的時(shí)候,Node 服務(wù)得會(huì)更好。大部分 Node 應(yīng)用都使用 JSON 數(shù)據(jù)。

3. 優(yōu)化數(shù)據(jù)庫(kù)查詢

優(yōu)化 Node API 的重要一環(huán)是優(yōu)化查詢。特別是對(duì)于大型應(yīng)用來(lái)說(shuō),我們需要多次查詢數(shù)據(jù)庫(kù),所以一個(gè)糟糕的查詢會(huì)降低應(yīng)用的整體性能。

索引是一種優(yōu)化數(shù)據(jù)庫(kù)性能的方法,通過(guò)最小化處理查詢時(shí)所需的磁盤訪問次數(shù)來(lái)實(shí)現(xiàn)。它是一種數(shù)據(jù)結(jié)構(gòu)技術(shù),用于快速定位和訪問數(shù)據(jù)庫(kù)中的數(shù)據(jù)。索引是使用幾個(gè)數(shù)據(jù)庫(kù)列創(chuàng)建的。

假設(shè)我們有一個(gè)沒有索引的數(shù)據(jù)庫(kù)模式,并且數(shù)據(jù)庫(kù)包含 100 萬(wàn)條記錄。與帶有索引的模式相比,使用沒有索引的模式做一個(gè)簡(jiǎn)單的 find(查找)查詢將掃描更多的記錄來(lái)找到匹配的記錄。

  • 沒有索引的查詢
> db.user.find({email: 'ofan@skyshi.com'}).explain("executionStats")
  • 有索引的查詢
> db.getCollection("user").createIndex({ "email": 1 }, { "name": "email_1", "unique": true })
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}

兩者之間掃描文件的數(shù)量相差巨大 ~ 1038:

方法

掃描文件

沒有索引

1039

有索引

1

4. 使用 PM2 集群模式優(yōu)化 API

PM2 是為 Node.js 應(yīng)用程序設(shè)計(jì)的生產(chǎn)流程管理器。它內(nèi)置了負(fù)載平衡器,允許應(yīng)用程序在不修改代碼的情況下,作為多個(gè)進(jìn)程運(yùn)行。

使用 PM2 時(shí)的應(yīng)用停機(jī)時(shí)間幾乎為零??傮w來(lái)說(shuō),PM2 確實(shí)可以提升 API 性能和并發(fā)性。

在生產(chǎn)環(huán)境中部署代碼并運(yùn)行以下命令以查看 PM2 集群如何在所有可用 CPU 上進(jìn)行擴(kuò)展:

pm2 start  app.js -i 0

5. 減少 TTFB(第一字節(jié)時(shí)間)

第一字節(jié)時(shí)間是一種測(cè)量方式,用作表示 Web 服務(wù)器或者其他網(wǎng)絡(luò)資源的響應(yīng)時(shí)間。TTFB 測(cè)量從用戶或客戶發(fā)出 HTTP 請(qǐng)求到客戶的瀏覽器收到頁(yè)面的第一個(gè)字節(jié)的時(shí)間。

所有用戶訪問瀏覽器的同一頁(yè)面加載速度不可能在 100 毫秒之內(nèi),這僅僅是因?yàn)榉?wù)器和用戶之間的物理距離。

我們可以通過(guò)使用 CDN 和全球本地?cái)?shù)據(jù)中心緩存內(nèi)容來(lái)減少第一個(gè)字節(jié)的時(shí)間。這有助于用戶以最小的延遲訪問內(nèi)容。你可以從 Cloudflare 提供的 CDN 解決方案開始著手。

6. 使用帶日志的錯(cuò)誤腳本

監(jiān)視 API 是否正常工作最好的辦法是記錄行為,于是記錄日志就派上用場(chǎng)。

一個(gè)常見的辦法是將記錄打印在控制臺(tái)上(使用console.log())。

比console.log()更高效的方法是使用 Morgan、Buyan 和 Winston。我將在這里以 Winston 為例。

如何使用 Winston 記錄 – 功能

  • 支持 4 個(gè)可以自由選擇的日志等級(jí),如:info、error、verbose、debug、silly 和 warn
  • 支持查詢?nèi)罩?/li>
  • 簡(jiǎn)單的分析
  • 可以使用相同的類型進(jìn)行多個(gè) transports 輸出
  • 捕獲并記錄 uncaughtException

可以使用以下命令行設(shè)置 Winston:

npm install winston --save

這里是使用 Winston 記錄的基本配置:

const winston = require('winston');

let logger = new winston.Logger({
transports: [
new winston.transports.File({
level: 'verbose',
timestamp: new Date(),
filename: 'filelog-verbose.log',
json: false,
}),
new winston.transports.File({
level: 'error',
timestamp: new Date(),
filename: 'filelog-error.log',
json: false,
})
]
});

logger.stream = {
write: function(message, encoding) {
logger.info(message);
}
};

7. 使用 HTTP/2 而不是 HTTP

除了上述使用的這些技巧,我們還可以使用 HTTP/2 而不是 HTTP,因?yàn)樗邆湟韵聝?yōu)勢(shì):

  • 多路復(fù)用
  • 頭部壓縮
  • 服務(wù)器推送
  • 二進(jìn)制格式

它專注提高性能,并解決 HTTP 的問題。它使網(wǎng)頁(yè)瀏覽更快、更容易,并且消耗更少的帶寬。

8. 并行任務(wù)

使用 async.js 來(lái)運(yùn)行任務(wù)。并行任務(wù)對(duì) API 的性能有很大改善,它減少了延遲并最大限度地減少了阻塞操作。

并行意味著同時(shí)運(yùn)行多個(gè)任務(wù)。當(dāng)你并行任務(wù)的時(shí)候,不需要控制程序的執(zhí)行順序。

以下是一個(gè)數(shù)組異步并行的簡(jiǎn)單例子:

const async = require("async");
// 使用對(duì)象而不是數(shù)組
async.parallel({
task1: function(callback) {
setTimeout(function() {
console.log('Task One');
callback(null, 1);
}, 200);
},
task2: function(callback) {
setTimeout(function() {
console.log('Task Two');
callback(null, 2);
}, 100);
}
}, function(err, results) {
console.log(results);
// 結(jié)果相當(dāng)于: {task2: 2, task1: 1}
});

在以上例子中,我們使用了 async.js 以異步的形式執(zhí)行了兩個(gè)任務(wù)。task 1 需要 200 毫秒完成,但是 task 2 不需要等待 task 1 完成后再執(zhí)行 – 它在設(shè)定的 100 毫秒后執(zhí)行。

并行任務(wù)對(duì) API 的性能有很大的影響。它減少了延遲并最大限度地減少了阻塞操作。

9. 使用 Redis 緩存應(yīng)用

Redis 是 Memcached 的高級(jí)版本。它通過(guò)在服務(wù)器的主內(nèi)存中存儲(chǔ)和檢索數(shù)據(jù)來(lái)優(yōu)化 API 響應(yīng)時(shí)間。它提高了數(shù)據(jù)庫(kù)查詢的性能,也減少了訪問延遲。

在下面的代碼片段中,我們分別調(diào)用了不使用 Redis 和使用 Redis 的 API,并比較了響應(yīng)時(shí)間。

響應(yīng)時(shí)間差異巨大~ 899.37 毫秒:

方法

響應(yīng)時(shí)間

不使用 Redis

900ms

使用 Redis

0.621ms

以下是不使用 Redis 的 Node:

'use strict';

//定義需要的所有依賴項(xiàng)
const express = require('express');
const responseTime = require('response-time')
const axios = require('axios');

//加載 Express 框架
var app = express();

//創(chuàng)建在響應(yīng)頭中添加 X-Response-Time 的中間件
app.use(responseTime());

const getBook = (req, res) => {
let isbn = req.query.isbn;
let url = `https://www.googleapis.com/books/v1/volumes?q=isbn:${isbn}`;
axios.get(url)
.then(response => {
let book = response.data.items
res.send(book);
})
.catch(err => {
res.send('The book you are looking for is not found !!!');
});
};

app.get('/book', getBook);

app.listen(3000, function() {
console.log('Your node is running on port 3000 !!!')
});

以下是使用 Redis 的 Node:

'use strict';

//定義需要的所有依賴項(xiàng)
const express = require('express');
const responseTime = require('response-time')
const axios = require('axios');
const redis = require('redis');
const client = redis.createClient();

//加載 Express 框架
var app = express();

//創(chuàng)建在響應(yīng)頭中添加 X-Response-Time 的中間件
app.use(responseTime());

const getBook = (req, res) => {
let isbn = req.query.isbn;
let url = `https://www.googleapis.com/books/v1/volumes?q=isbn:${isbn}`;
return axios.get(url)
.then(response => {
let book = response.data.items;
//設(shè)置string-key:緩存中的 isbn。以及緩存的內(nèi)容: title
// 設(shè)置緩存的過(guò)期時(shí)間為 1 個(gè)小時(shí)(60分鐘)
client.setex(isbn, 3600, JSON.stringify(book));

res.send(book);
})
.catch(err => {
res.send('The book you are looking for is not found !!!');
});
};

const getCache = (req, res) => {
let isbn = req.query.isbn;
//對(duì)照服務(wù)器的 redis 檢查緩存數(shù)據(jù)
client.get(isbn, (err, result) => {
if (result) {
res.send(result);
} else {
getBook(req, res);
}
});
}
app.get('/book', getCache);

app.listen(3000, function() {
console.log('Your node is running on port 3000 !!!')
)};

總結(jié)

在本指南中,我們了解了如何優(yōu)化 Node.js API 的響應(yīng)時(shí)間。

JavaScript 重度依賴函數(shù),因此,使用異步函數(shù)可以使腳本運(yùn)行得更快并且不阻塞。

除此之外,我們還可以使用緩存記憶(Redis)、數(shù)據(jù)庫(kù)索引、TTFB 和 PM2 集群來(lái)提高響應(yīng)速度。

最后請(qǐng)記住,注意路由的安全性并盡可能優(yōu)化路由也很重要。我們不能為了提高 API 響應(yīng)速度而妥協(xié)掉安全性。因此,在 Node.js 中構(gòu)建優(yōu)化的 API 時(shí),應(yīng)該保留所有標(biāo)準(zhǔn)安全檢查。

責(zé)任編輯:華軒 來(lái)源: freeCodeCamp
相關(guān)推薦

2023-01-10 14:11:26

2011-09-09 14:23:13

Node.js

2025-05-26 00:31:31

2022-03-08 15:13:34

Fetch APINode.js開發(fā)者

2024-09-25 08:04:58

2021-11-16 08:51:29

Node JavaScript變量類型

2023-10-18 16:39:32

2013-11-01 09:34:56

Node.js技術(shù)

2021-05-27 09:00:00

Node.js開發(fā)線程

2015-03-10 10:59:18

Node.js開發(fā)指南基礎(chǔ)介紹

2011-12-09 11:16:48

Node.js

2020-05-29 15:33:28

Node.js框架JavaScript

2012-02-03 09:25:39

Node.js

2023-04-19 08:31:57

Node.jsLTS版本

2021-08-20 09:00:00

Node.js開發(fā)API

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)

2020-01-03 16:04:10

Node.js內(nèi)存泄漏

2023-10-04 07:35:03

2023-03-02 23:09:53

Node.jsC++JS

2020-10-12 17:40:34

.NET Core開發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)