欢迎来到 Node.js 高阶教程!在本教程中,你将学习到 Node.js 的性能优化、微服务架构、测试策略和部署等方面的知识。
本教程共三篇分别是:入门篇、进阶篇、高阶篇。适用于有一定web前端基础,想通过学习nodejs发展为全栈工程师的人群。
目录
性能优化
Node.js 应用的性能优化是一个重要话题。让我们通过一些实际示例来了解如何优化 Node.js 应用。
创建 performance_example.js
:
const http = require('http');
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
// 模拟 CPU 密集型任务
function cpuIntensiveTask(n) {
let result = 0;
for (let i = 0; i < n; i++) {
result += Math.sqrt(i);
}
return result;
}
if (cluster.isMaster) {
console.log(`主进程 ${process.pid} 正在运行`);
// 衍生工作进程
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`工作进程 ${worker.process.pid} 已退出`);
});
} else {
// 工作进程可以共享任何 TCP 连接
// 在本例中,它是 HTTP 服务器
http.createServer((req, res) => {
if (req.url === '/cpu-task') {
const result = cpuIntensiveTask(1000000);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ result }));
} else {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, 大虫小呓! This is a clustered Node.js server.');
}
}).listen(3000);
console.log(`工作进程 ${process.pid} 已启动`);
}
运行示例:
node performance_example.js
这个示例展示了如何使用 Node.js 的 cluster 模块来利用多核 CPU,从而提高应用的并发处理能力。
微服务架构
微服务架构是一种将大型应用拆分为多个小型、独立服务的架构模式。让我们看看如何在 Node.js 中实现一个简单的微服务。
首先创建 user-service.js
:
const express = require('express');
const app = express();
const port = 3001;
app.use(express.json());
// 模拟用户数据存储
let users = [
{ id: 1, name: '大虫小呓', email: 'dachongxiaoyi@example.com' },
{ id: 2, name: '张三', email: 'zhangsan@example.com' }
];
// 获取所有用户
app.get('/users', (req, res) => {
res.json(users);
});
// 根据 ID 获取用户
app.get('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = users.find(u => u.id === userId);
if (!user) {
return res.status(404).json({ message: '用户未找到' });
}
res.json(user);
});
app.listen(port, () => {
console.log(`用户服务运行在 http://localhost:${port}`);
});
再创建 order-service.js
:
const express = require('express');
const app = express();
const port = 3002;
app.use(express.json());
// 模拟订单数据存储
let orders = [
{ id: 1, userId: 1, product: 'Node.js 书籍', amount: 59.99 },
{ id: 2, userId: 2, product: 'Express.js 课程', amount: 99.99 }
];
// 获取所有订单
app.get('/orders', (req, res) => {
res.json(orders);
});
// 根据用户 ID 获取订单
app.get('/orders/user/:userId', (req, res) => {
const userId = parseInt(req.params.userId);
const userOrders = orders.filter(order => order.userId === userId);
res.json(userOrders);
});
app.listen(port, () => {
console.log(`订单服务运行在 http://localhost:${port}`);
});
最后创建一个 API 网关 api-gateway.js
来协调这些服务:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const port = 3000;
// 代理到用户服务
app.use('/api/users', createProxyMiddleware({
target: 'http://localhost:3001',
changeOrigin: true,
pathRewrite: {
'^/api/users': '/users',
},
}));
// 代理到订单服务
app.use('/api/orders', createProxyMiddleware({
target: 'http://localhost:3002',
changeOrigin: true,
pathRewrite: {
'^/api/orders': '/orders',
},
}));
app.listen(port, () => {
console.log(`API 网关运行在 http://localhost:${port}`);
});
要运行这些服务,需要先安装依赖:
npm install express http-proxy-middleware
然后在不同的终端窗口中分别运行:
# 终端 1
node user-service.js
# 终端 2
node order-service.js
# 终端 3
node api-gateway.js
现在你可以通过 API 网关访问用户和订单服务:
# 获取所有用户
curl http://localhost:3000/api/users
# 获取特定用户
curl http://localhost:3000/api/users/1
# 获取所有订单
curl http://localhost:3000/api/orders
# 获取特定用户的订单
curl http://localhost:3000/api/orders/user/1
测试策略
良好的测试策略对于保证代码质量至关重要。Node.js 有多种测试框架可供选择,如 Jest、Mocha 等。
创建 math.js
:
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
function multiply(a, b) {
return a * b;
}
function divide(a, b) {
if (b === 0) {
throw new Error('除数不能为零');
}
return a / b;
}
module.exports = {
add,
subtract,
multiply,
divide
};
创建测试文件 math.test.js
(使用 Jest 测试框架):
const { add, subtract, multiply, divide } = require('./math');
describe('数学运算函数测试', () => {
test('加法运算', () => {
expect(add(2, 3)).toBe(5);
expect(add(-1, 1)).toBe(0);
});
test('减法运算', () => {
expect(subtract(5, 3)).toBe(2);
expect(subtract(0, 5)).toBe(-5);
});
test('乘法运算', () => {
expect(multiply(3, 4)).toBe(12);
expect(multiply(-2, 3)).toBe(-6);
});
test('除法运算', () => {
expect(divide(10, 2)).toBe(5);
expect(divide(9, 3)).toBe(3);
});
test('除零异常', () => {
expect(() => divide(5, 0)).toThrow('除数不能为零');
});
});
首先安装 Jest:
npm install --save-dev jest
在 package.json
中添加测试脚本:
{
"scripts": {
"test": "jest"
}
}
运行测试:
npm test
部署与容器化
在生产环境中部署 Node.js 应用通常涉及使用 Docker 容器化技术。
创建 Dockerfile
:
# 使用官方 Node.js 运行时作为基础镜像
FROM node:18
# 设置工作目录
WORKDIR /usr/src/app
# 复制 package.json 和 package-lock.json(如果存在)
COPY package*.json ./
# 安装应用依赖
RUN npm install
# 复制应用源代码
COPY . .
# 暴露端口
EXPOSE 3000
# 定义运行应用的命令
CMD [ "node", "server.js" ]
创建 .dockerignore
文件:
node_modules
npm-debug.log
创建一个简单的 server.js
作为示例应用:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, 大虫小呓! This is a Dockerized Node.js app.');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
构建 Docker 镜像:
docker build -t my-node-app .
运行容器:
docker run -p 3000:3000 my-node-app
现在你可以在 http://localhost:3000
访问你的应用。
总结
通过本教程,你学习了 Node.js 的性能优化、微服务架构、测试策略和部署等高级主题。这些知识将帮助你构建高质量、可扩展的 Node.js 应用。继续学习和实践,你将成为一名优秀的 Node.js 开发者!