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

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

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

目录

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

性能优化

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 开发者!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值