简易 Node.js + MySQL 项目实现
项目结构
project/
├── server.js # 主入口文件
├── package.json
├── db.js # 数据库连接模块
├── .env # 环境变量配置
└── users/ # 用户功能模块
├── users.controller.js
└── users.route.js
代码实现
- 安装依赖
bash
npm init -y
npm install express mysql2 dotenv body-parser
- db.js (数据库连接)
javascript
const mysql = require('mysql2/promise');
require('dotenv').config();
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10
});
module.exports = pool;
- users.controller.js (业务逻辑)
javascript
const pool = require('../db');
exports.getUsers = async (req, res) => {
try {
const [rows] = await pool.query('SELECT * FROM users');
res.json(rows);
} catch (err) {
res.status(500).json({ error: err.message });
}
};
exports.createUser = async (req, res) => {
const { name, email } = req.body;
try {
const [result] = await pool.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
res.status(201).json({ id: result.insertId, name, email });
} catch (err) {
res.status(400).json({ error: err.message });
}
};
- users.route.js (路由)
javascript
const express = require('express');
const router = express.Router();
const { getUsers, createUser } = require('./users.controller');
router.get('/', getUsers);
router.post('/', createUser);
module.exports = router;
- server.js (主入口)
javascript
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
require('dotenv').config();
app.use(bodyParser.json());
app.use('/users', require('./users/users.route'));
app.get('/', (req, res) => {
res.send('API Running');
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server started on port ${PORT}`);
});
- .env (环境变量)
env
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_mysql_password
DB_NAME=test_db
PORT=3000
数据库准备
sql
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
部署到云服务器流程 (以 Ubuntu 20.04 为例)
1. 服务器准备
bash
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装 Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# 安装 MySQL
sudo apt install mysql-server -y
sudo mysql_secure_installation
2. 配置 MySQL
bash
sudo mysql -u root -p
sql
CREATE DATABASE test_db;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'strong_password';
GRANT ALL PRIVILEGES ON test_db.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
3. 部署应用
bash
# 克隆项目
git clone https://your-repo-url.git
cd project
# 安装依赖
npm install
# 配置环境变量
nano .env
# 修改为:
DB_HOST=localhost
DB_USER=appuser
DB_PASSWORD=strong_password
DB_NAME=test_db
4. 启动服务
bash
# 测试启动
node server.js
# 使用 PM2 守护进程
sudo npm install -g pm2
pm2 start server.js --name "my-api"
pm2 save
pm2 startup # 生成开机启动脚本
5. 防火墙配置
bash
sudo ufw allow 3000/tcp # 开放API端口
sudo ufw allow 22 # 保留SSH访问
sudo ufw enable
前端访问 API
请求示例
javascript
// 获取所有用户
fetch('http://<服务器IP>:3000/users')
.then(response => response.json())
.then(data => console.log(data));
// 创建新用户
fetch('http://<服务器IP>:3000/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Alice',
email: 'alice@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));
安全建议
- 生产环境使用 Nginx 反向代理
- 配置 HTTPS (使用 Let's Encrypt)
- 添加 API 身份验证 (JWT/OAuth)
后续维护方案
1. 监控与日志
bash
# 查看实时日志
pm2 logs my-api
# 监控资源使用
pm2 monit
# 设置日志轮转
pm2 install pm2-logrotate
2. 持续部署
- 配置 GitHub Actions 自动化部署
- 添加测试脚本 (
npm test) - 使用 Webhook 触发自动更新
3. 备份策略
bash
# 数据库每日备份 (添加到cron)
0 3 * * * mysqldump -u appuser -pstrong_password test_db > /backups/db-$(date +%F).sql
# 代码备份
0 4 * * * tar -zcvf /backups/code-$(date +%F).tar.gz /path/to/project
4. 安全更新
bash
# 每月执行
sudo apt update && sudo apt upgrade -y
npm update
5. 性能优化
- 数据库连接池调优 (
db.js) - 添加 Redis 缓存层
- 使用 Cluster 模式启动 Node.js
javascript
// server.js 修改
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
// 原有启动代码
}
注意事项:
- 生产环境务必删除调试
console.log- 使用
helmet增强安全头部- 定期审查依赖漏洞 (
npm audit)- 设置进程崩溃自动重启 (
pm2 ecosystem)