Nodejs从入门到高阶-大虫小呓三部曲(高阶篇)

欢迎来到 Node.js 高阶教程!在本教程中,你将学习到 Node.js 的性能优化、微服务架构、测试策略和部署等方面的知识。

本教程共三篇分别是:入门篇、进阶篇、高阶篇。适用于有一定web前端基础,想通过学习nodejs发展为全栈工程师的人群。

目录

  1. 性能优化
  2. 微服务架构
  3. 测试策略
  4. 部署与容器化
  5. 总结

性能优化

Node.js 应用的性能优化是一个重要话题。让我们通过一些实际示例来了解如何优化 Node.js 应用。

创建 performance_example.js

javascript 复制代码
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} 已启动`);
}

运行示例:

bash 复制代码
node performance_example.js

这个示例展示了如何使用 Node.js 的 cluster 模块来利用多核 CPU,从而提高应用的并发处理能力。

微服务架构

微服务架构是一种将大型应用拆分为多个小型、独立服务的架构模式。让我们看看如何在 Node.js 中实现一个简单的微服务。

首先创建 user-service.js

javascript 复制代码
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

javascript 复制代码
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 来协调这些服务:

javascript 复制代码
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}`);
});

要运行这些服务,需要先安装依赖:

bash 复制代码
npm install express http-proxy-middleware

然后在不同的终端窗口中分别运行:

bash 复制代码
# 终端 1
node user-service.js

# 终端 2
node order-service.js

# 终端 3
node api-gateway.js

现在你可以通过 API 网关访问用户和订单服务:

bash 复制代码
# 获取所有用户
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

javascript 复制代码
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 测试框架):

javascript 复制代码
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:

bash 复制代码
npm install --save-dev jest

package.json 中添加测试脚本:

json 复制代码
{
  "scripts": {
    "test": "jest"
  }
}

运行测试:

bash 复制代码
npm test

部署与容器化

在生产环境中部署 Node.js 应用通常涉及使用 Docker 容器化技术。

创建 Dockerfile

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 文件:

lua 复制代码
node_modules
npm-debug.log

创建一个简单的 server.js 作为示例应用:

javascript 复制代码
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 镜像:

bash 复制代码
docker build -t my-node-app .

运行容器:

bash 复制代码
docker run -p 3000:3000 my-node-app

现在你可以在 http://localhost:3000 访问你的应用。

总结

通过本教程,你学习了 Node.js 的性能优化、微服务架构、测试策略和部署等高级主题。这些知识将帮助你构建高质量、可扩展的 Node.js 应用。继续学习和实践,你将成为一名优秀的 Node.js 开发者!

相关推荐
敲敲敲敲暴你脑袋10 小时前
地图瓦片批量改色来啦!
node.js·gis·数据可视化
狂师11 小时前
最近火爆出圈的,FDE 到底是个什么岗位?
人工智能·程序员·全栈
太子釢1 天前
AI 开发个人记账 App(服务端篇)
node.js·ai编程
用户64340495148511 天前
Elpis 项目构建工具与前端基建实践总结
node.js
FungLeo1 天前
成为全栈·Node 后端篇·后端测试策略:单元、集成与测试数据库
单元测试·node.js·集成测试·测试策略·成为全栈·测试数据库
FungLeo1 天前
成为全栈·Node 后端篇·评论内容安全:敏感词过滤、三态审核与级联删除
node.js·敏感词过滤·成为全栈·评论内容安全·评论审核·级联删除
FungLeo2 天前
成为全栈·Node 后端篇·阅读量防刷:去重、冷却与计数写分离
node.js·读写分离·数据去重·接口防刷·成为全栈·数据冷却
脉动数据行情12 天前
Node.js WebSocket 实现贵金属实时行情监听 伦敦金 / 伦敦银自动重连方案
websocket·node.js·vim
不老刘2 天前
一行命令解决 Node.js 版本兼容问题:`--openssl-legacy-provider` 深度解析
node.js
万敏3 天前
Vue3 全栈实战:第一阶段复盘(第1-8周)
vue.js·node.js·全栈