2025-12-20 09:37:43 +08:00
|
|
|
|
# IDC设备管理系统 - 安装部署指南
|
|
|
|
|
|
|
|
|
|
|
|
[
|
|
|
|
|
|
[](https://nodejs.org/)
|
|
|
|
|
|
[](https://reactjs.org/)
|
|
|
|
|
|
[]()
|
|
|
|
|
|
|
|
|
|
|
|
## 📋 目录
|
|
|
|
|
|
|
|
|
|
|
|
- [环境要求](#环境要求)
|
|
|
|
|
|
- [快速开始](#快速开始)
|
|
|
|
|
|
- [详细安装步骤](#详细安装步骤)
|
2025-12-20 09:45:13 +08:00
|
|
|
|
- [开发环境部署](#开发环境部署)
|
2025-12-20 09:37:43 +08:00
|
|
|
|
- [生产部署](#生产部署)
|
|
|
|
|
|
- [数据库配置](#数据库配置)
|
|
|
|
|
|
- [监控和维护](#监控和维护)
|
|
|
|
|
|
- [常见问题解决](#常见问题解决)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🖥️ 环境要求
|
|
|
|
|
|
|
|
|
|
|
|
### 开发环境
|
|
|
|
|
|
- **Node.js**: ≥14.0.0
|
|
|
|
|
|
- **npm**: ≥6.0.0 或 **yarn**: ≥1.22.0
|
|
|
|
|
|
- **操作系统**: Windows 10/11, macOS 10.14+, Linux (Ubuntu 18.04+)
|
|
|
|
|
|
- **内存**: 最小 4GB RAM
|
|
|
|
|
|
- **硬盘**: 最小 2GB 可用空间
|
|
|
|
|
|
|
|
|
|
|
|
### 生产环境
|
|
|
|
|
|
- **Node.js**: ≥14.0.0
|
|
|
|
|
|
- **npm**: ≥6.0.0 或 **yarn**: ≥1.22.0
|
|
|
|
|
|
- **Web服务器**: Nginx (推荐) 或 Apache
|
|
|
|
|
|
- **操作系统**: Linux (Ubuntu 18.04+, CentOS 7+, RHEL 7+)
|
|
|
|
|
|
- **内存**: 最小 8GB RAM (推荐 16GB+)
|
|
|
|
|
|
- **硬盘**: 最小 10GB 可用空间 (SSD 推荐)
|
|
|
|
|
|
- **SSL证书**: Let's Encrypt (推荐) 或其他CA证书
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## ⚡ 快速开始
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 克隆项目
|
|
|
|
|
|
```bash
|
|
|
|
|
|
git clone https://gitee.com/zhang1106/idc_assest.git
|
|
|
|
|
|
cd idc_assest
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 安装后端依赖
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
npm install
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 安装前端依赖
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd ../frontend
|
|
|
|
|
|
npm install
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 启动服务
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 启动后端服务(端口8000)
|
|
|
|
|
|
cd backend && npm run dev
|
|
|
|
|
|
|
|
|
|
|
|
# 启动前端服务(端口3000)- 新终端
|
|
|
|
|
|
cd frontend && npm run dev
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**访问地址**:
|
|
|
|
|
|
- 前端应用:http://localhost:3000
|
|
|
|
|
|
- 后端API:http://localhost:8000/api
|
|
|
|
|
|
- 健康检查:http://localhost:8000/health
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📖 详细安装步骤
|
|
|
|
|
|
|
2025-12-20 09:45:13 +08:00
|
|
|
|
> **📝 安装说明**:
|
|
|
|
|
|
> 本文档将部署分为两个阶段:
|
|
|
|
|
|
> 1. **开发环境部署**:在本地机器上配置完整的开发和测试环境
|
|
|
|
|
|
> 2. **生产环境部署**:在Linux服务器上配置生产环境,通过域名访问
|
|
|
|
|
|
|
|
|
|
|
|
> **🎯 建议路径**:
|
|
|
|
|
|
> - **开发人员**:只需要阅读"开发环境部署"部分
|
|
|
|
|
|
> - **运维人员**:需要阅读完整文档,包括"生产部署"部分
|
|
|
|
|
|
|
|
|
|
|
|
### 开发环境部署
|
|
|
|
|
|
|
2025-12-20 09:37:43 +08:00
|
|
|
|
### 后端配置
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 进入后端目录
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 安装依赖包
|
|
|
|
|
|
```bash
|
|
|
|
|
|
npm install
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 配置环境变量
|
|
|
|
|
|
项目支持使用 `.env` 文件进行配置。请按以下步骤操作:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 复制环境变量示例文件
|
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
|
|
|
|
|
|
|
# 编辑 .env 文件,修改配置
|
|
|
|
|
|
# 可以使用任意文本编辑器,如:
|
|
|
|
|
|
# Windows: notepad .env
|
|
|
|
|
|
# macOS: nano .env
|
|
|
|
|
|
# 或IDE: 在编辑器中打开 .env 文件
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**重要说明**:
|
|
|
|
|
|
- `.env` 文件包含了所有可配置的选项和详细注释
|
|
|
|
|
|
- 每个配置项都有默认值,默认情况下可以直接使用
|
|
|
|
|
|
- 如需修改配置,请编辑 `.env` 文件中的相应值
|
|
|
|
|
|
- 建议开发时使用 `NODE_ENV=development`,部署时使用 `NODE_ENV=production`
|
|
|
|
|
|
|
|
|
|
|
|
**配置项说明**:
|
|
|
|
|
|
|
|
|
|
|
|
**服务器配置**:
|
|
|
|
|
|
- `PORT`:服务器端口(默认8000)
|
|
|
|
|
|
- `NODE_ENV`:运行环境
|
|
|
|
|
|
- `development`:开发模式,详细日志便于调试
|
|
|
|
|
|
- `production`:生产模式,性能优化,减少日志输出
|
|
|
|
|
|
|
|
|
|
|
|
**数据库配置**:
|
|
|
|
|
|
- `DB_TYPE`:数据库类型(默认 sqlite,可选 mysql)
|
|
|
|
|
|
- `sqlite`:零配置嵌入式数据库,适合开发和小规模应用
|
|
|
|
|
|
- `mysql`:关系型数据库,适合生产环境和大规模应用
|
|
|
|
|
|
- `DB_PATH`:SQLite数据库文件路径(默认 ./idc_management.db)
|
|
|
|
|
|
- `MYSQL_HOST`:MySQL服务器地址(默认 localhost)
|
|
|
|
|
|
- `MYSQL_PORT`:MySQL端口(默认 3306)
|
|
|
|
|
|
- `MYSQL_USERNAME`:MySQL用户名(默认 root)
|
|
|
|
|
|
- `MYSQL_PASSWORD`:MySQL密码
|
|
|
|
|
|
- `MYSQL_DATABASE`:MySQL数据库名(默认 idc_management)
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. 数据库配置
|
|
|
|
|
|
|
|
|
|
|
|
**默认配置(推荐)**:使用SQLite数据库,无需额外配置
|
|
|
|
|
|
|
|
|
|
|
|
**MySQL配置**:如需使用MySQL数据库,请按以下步骤操作:
|
|
|
|
|
|
|
|
|
|
|
|
1. 确保MySQL服务已安装并运行
|
|
|
|
|
|
2. 创建数据库:
|
|
|
|
|
|
```sql
|
|
|
|
|
|
CREATE DATABASE idc_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
|
|
|
|
```
|
|
|
|
|
|
3. 在 `.env` 文件中修改配置:
|
|
|
|
|
|
```env
|
|
|
|
|
|
DB_TYPE=mysql
|
|
|
|
|
|
MYSQL_HOST=localhost
|
|
|
|
|
|
MYSQL_PORT=3306
|
|
|
|
|
|
MYSQL_USERNAME=root
|
|
|
|
|
|
MYSQL_PASSWORD=your_password
|
|
|
|
|
|
MYSQL_DATABASE=idc_management
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 5. 启动后端服务
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 开发模式(自动重启)
|
|
|
|
|
|
npm run dev
|
|
|
|
|
|
|
|
|
|
|
|
# 生产模式
|
|
|
|
|
|
npm start
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**后端服务将在 http://localhost:8000 启动**(或配置的端口号)
|
|
|
|
|
|
|
|
|
|
|
|
### 前端配置
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 进入前端目录
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd frontend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 安装依赖包
|
|
|
|
|
|
```bash
|
|
|
|
|
|
npm install
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 配置API地址
|
|
|
|
|
|
项目使用Vite代理配置,API地址在 `frontend/vite.config.js` 中配置:
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
proxy: {
|
|
|
|
|
|
'/api': {
|
|
|
|
|
|
target: 'http://localhost:8000',
|
|
|
|
|
|
changeOrigin: true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
如需修改后端地址,更新 `vite.config.js` 中的 `target` 字段。
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. 启动前端开发服务器
|
|
|
|
|
|
```bash
|
|
|
|
|
|
npm run dev
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**前端应用将在 http://localhost:3000 启动**
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-20 09:45:13 +08:00
|
|
|
|
> **✅ 开发环境部署完成**
|
|
|
|
|
|
>
|
|
|
|
|
|
> 至此,开发环境已完全配置完成。您可以:
|
|
|
|
|
|
> - 前端开发:http://localhost:3000
|
|
|
|
|
|
> - 后端API:http://localhost:8000/api
|
|
|
|
|
|
> - 后端健康检查:http://localhost:8000/health
|
|
|
|
|
|
>
|
|
|
|
|
|
> **接下来**:如果您需要部署到生产环境,请继续阅读下一节"生产部署"。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-20 09:37:43 +08:00
|
|
|
|
## 🚀 生产部署
|
|
|
|
|
|
|
2025-12-20 09:45:13 +08:00
|
|
|
|
> **📋 生产部署说明**:
|
|
|
|
|
|
> - **独立部署**:生产部署在专门的Linux服务器上进行,与开发环境完全分离
|
|
|
|
|
|
> - **部署地址**:将通过域名或IP访问,如 `http://your-domain.com`
|
|
|
|
|
|
> - **安全要求**:生产环境有更严格的安全配置要求
|
|
|
|
|
|
> - **前置条件**:您需要拥有Linux服务器的root权限
|
|
|
|
|
|
>
|
2025-12-20 09:37:43 +08:00
|
|
|
|
> **⚠️ 部署前必读**:生产部署涉及服务器安全,请确保在安全环境下操作,并及时更新安全配置。
|
|
|
|
|
|
|
|
|
|
|
|
#### 部署准备
|
|
|
|
|
|
|
|
|
|
|
|
1. **环境检查**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查系统环境
|
|
|
|
|
|
node --version # 确保 Node.js ≥ 14.0
|
|
|
|
|
|
npm --version # 确保 npm 可用
|
|
|
|
|
|
|
|
|
|
|
|
# 检查服务器端口占用
|
|
|
|
|
|
netstat -tulpn | grep :8000
|
|
|
|
|
|
netstat -tulpn | grep :80
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **创建部署目录**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 创建应用目录
|
|
|
|
|
|
mkdir -p /var/www/idc_assest
|
|
|
|
|
|
mkdir -p /var/log/idc_assest
|
|
|
|
|
|
mkdir -p /etc/nginx/sites-available
|
|
|
|
|
|
mkdir -p /etc/nginx/sites-enabled
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 后端部署
|
|
|
|
|
|
|
|
|
|
|
|
1. **设置生产环境配置**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 进入后端目录
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
|
|
|
|
|
|
# 复制并编辑环境配置文件
|
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
|
|
|
|
|
|
|
# 编辑生产环境配置(重要!)
|
|
|
|
|
|
# 设置生产模式
|
|
|
|
|
|
NODE_ENV=production
|
|
|
|
|
|
|
|
|
|
|
|
# 设置安全端口(可选)
|
|
|
|
|
|
PORT=8000
|
|
|
|
|
|
|
|
|
|
|
|
# 数据库配置(推荐使用MySQL)
|
|
|
|
|
|
DB_TYPE=mysql
|
|
|
|
|
|
MYSQL_HOST=localhost
|
|
|
|
|
|
MYSQL_PORT=3306
|
|
|
|
|
|
MYSQL_USERNAME=idc_user # 创建专用数据库用户
|
|
|
|
|
|
MYSQL_PASSWORD=secure_password # 使用强密码
|
|
|
|
|
|
MYSQL_DATABASE=idc_management
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **安装生产依赖**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 安装生产依赖(只安装生产环境需要的包)
|
|
|
|
|
|
npm install --only=production
|
|
|
|
|
|
|
|
|
|
|
|
# 验证关键依赖是否安装成功
|
|
|
|
|
|
ls node_modules | grep -E "(express|sequelize|mysql2)"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3. **配置数据库**
|
|
|
|
|
|
```sql
|
|
|
|
|
|
-- 连接MySQL(使用root用户)
|
|
|
|
|
|
mysql -u root -p
|
|
|
|
|
|
|
|
|
|
|
|
-- 创建专用数据库
|
|
|
|
|
|
CREATE DATABASE idc_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
|
|
|
|
|
|
|
|
|
|
-- 创建专用用户(安全最佳实践)
|
|
|
|
|
|
CREATE USER 'idc_user'@'localhost' IDENTIFIED BY 'secure_password';
|
|
|
|
|
|
GRANT ALL PRIVILEGES ON idc_management.* TO 'idc_user'@'localhost';
|
|
|
|
|
|
FLUSH PRIVILEGES;
|
|
|
|
|
|
EXIT;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
4. **安装并配置PM2(进程管理器)**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 全局安装PM2
|
|
|
|
|
|
npm install -g pm2
|
|
|
|
|
|
|
|
|
|
|
|
# 启动应用
|
|
|
|
|
|
pm2 start server.js --name "idc-backend" --env production
|
|
|
|
|
|
|
|
|
|
|
|
# 设置开机自启
|
|
|
|
|
|
pm2 startup
|
|
|
|
|
|
pm2 save
|
|
|
|
|
|
|
|
|
|
|
|
# 查看运行状态
|
|
|
|
|
|
pm2 status
|
|
|
|
|
|
pm2 logs idc-backend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
5. **配置防火墙**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Ubuntu/Debian
|
|
|
|
|
|
sudo ufw allow 22 # SSH
|
|
|
|
|
|
sudo ufw allow 80 # HTTP
|
|
|
|
|
|
sudo ufw allow 443 # HTTPS
|
|
|
|
|
|
sudo ufw enable
|
|
|
|
|
|
|
|
|
|
|
|
# CentOS/RHEL
|
|
|
|
|
|
sudo firewall-cmd --permanent --add-service=ssh
|
|
|
|
|
|
sudo firewall-cmd --permanent --add-service=http
|
|
|
|
|
|
sudo firewall-cmd --permanent --add-service=https
|
|
|
|
|
|
sudo firewall-cmd --reload
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 前端部署
|
|
|
|
|
|
|
|
|
|
|
|
1. **构建生产版本**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd frontend
|
|
|
|
|
|
|
|
|
|
|
|
# 安装依赖
|
|
|
|
|
|
npm install
|
|
|
|
|
|
|
|
|
|
|
|
# 构建生产版本(会生成优化的静态文件)
|
|
|
|
|
|
npm run build
|
|
|
|
|
|
|
|
|
|
|
|
# 验证构建结果
|
|
|
|
|
|
ls -la dist/
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **部署到Web服务器**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 将构建文件复制到Web目录
|
|
|
|
|
|
sudo cp -r dist/* /var/www/idc-frontend/
|
|
|
|
|
|
|
|
|
|
|
|
# 设置正确的文件权限
|
|
|
|
|
|
sudo chown -R www-data:www-data /var/www/idc-frontend
|
|
|
|
|
|
sudo chmod -R 755 /var/www/idc-frontend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### Nginx配置
|
|
|
|
|
|
|
|
|
|
|
|
1. **创建站点配置文件**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo nano /etc/nginx/sites-available/idc_assest
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **编辑Nginx配置**
|
|
|
|
|
|
```nginx
|
|
|
|
|
|
# 主配置
|
|
|
|
|
|
server {
|
|
|
|
|
|
listen 80;
|
|
|
|
|
|
server_name your-domain.com www.your-domain.com;
|
|
|
|
|
|
|
|
|
|
|
|
# 安全头部
|
|
|
|
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
|
|
|
|
add_header X-XSS-Protection "1; mode=block" always;
|
|
|
|
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
|
|
|
|
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
|
|
|
|
|
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
|
|
|
|
|
|
|
|
|
|
|
|
# 前端静态文件
|
|
|
|
|
|
root /var/www/idc-frontend;
|
|
|
|
|
|
index index.html;
|
|
|
|
|
|
|
|
|
|
|
|
# 静态资源缓存
|
|
|
|
|
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
|
|
|
|
|
expires 1y;
|
|
|
|
|
|
add_header Cache-Control "public, immutable";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 前端路由(SPA支持)
|
|
|
|
|
|
location / {
|
|
|
|
|
|
try_files $uri $uri/ /index.html;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# API代理
|
|
|
|
|
|
location /api {
|
|
|
|
|
|
proxy_pass http://127.0.0.1:8000;
|
|
|
|
|
|
proxy_http_version 1.1;
|
|
|
|
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
|
|
|
|
proxy_set_header Connection 'upgrade';
|
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
|
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
|
|
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
|
|
proxy_cache_bypass $http_upgrade;
|
|
|
|
|
|
|
|
|
|
|
|
# 超时设置
|
|
|
|
|
|
proxy_connect_timeout 60s;
|
|
|
|
|
|
proxy_send_timeout 60s;
|
|
|
|
|
|
proxy_read_timeout 60s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 日志配置
|
|
|
|
|
|
access_log /var/log/nginx/idc_assest-access.log;
|
|
|
|
|
|
error_log /var/log/nginx/idc_assest-error.log;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# HTTPS配置(推荐)
|
|
|
|
|
|
server {
|
|
|
|
|
|
listen 443 ssl http2;
|
|
|
|
|
|
server_name your-domain.com www.your-domain.com;
|
|
|
|
|
|
|
|
|
|
|
|
# SSL证书配置(使用Let's Encrypt)
|
|
|
|
|
|
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
|
|
|
|
|
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
|
|
|
|
|
|
|
|
|
|
|
# SSL安全配置
|
|
|
|
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
|
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
|
|
|
|
|
ssl_prefer_server_ciphers off;
|
|
|
|
|
|
ssl_session_cache shared:SSL:10m;
|
|
|
|
|
|
|
|
|
|
|
|
# HSTS
|
|
|
|
|
|
add_header Strict-Transport-Security "max-age=63072000" always;
|
|
|
|
|
|
|
|
|
|
|
|
# 其他配置同HTTP
|
|
|
|
|
|
root /var/www/idc-frontend;
|
|
|
|
|
|
index index.html;
|
|
|
|
|
|
|
|
|
|
|
|
location / {
|
|
|
|
|
|
try_files $uri $uri/ /index.html;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
location /api {
|
|
|
|
|
|
proxy_pass http://127.0.0.1:8000;
|
|
|
|
|
|
proxy_http_version 1.1;
|
|
|
|
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
|
|
|
|
proxy_set_header Connection 'upgrade';
|
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
|
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
|
|
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
|
|
proxy_cache_bypass $http_upgrade;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# HTTP重定向到HTTPS
|
|
|
|
|
|
server {
|
|
|
|
|
|
listen 80;
|
|
|
|
|
|
server_name your-domain.com www.your-domain.com;
|
|
|
|
|
|
return 301 https://$server_name$request_uri;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3. **启用站点并重启Nginx**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 启用站点
|
|
|
|
|
|
sudo ln -s /etc/nginx/sites-available/idc_assest /etc/nginx/sites-enabled/
|
|
|
|
|
|
|
|
|
|
|
|
# 测试配置
|
|
|
|
|
|
sudo nginx -t
|
|
|
|
|
|
|
|
|
|
|
|
# 重启Nginx
|
|
|
|
|
|
sudo systemctl restart nginx
|
|
|
|
|
|
sudo systemctl enable nginx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### SSL证书配置(推荐)
|
|
|
|
|
|
|
|
|
|
|
|
1. **安装Certbot**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Ubuntu/Debian
|
|
|
|
|
|
sudo apt update
|
|
|
|
|
|
sudo apt install certbot python3-certbot-nginx
|
|
|
|
|
|
|
|
|
|
|
|
# CentOS/RHEL
|
|
|
|
|
|
sudo yum install certbot python3-certbot-nginx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **获取SSL证书**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 自动配置SSL证书
|
|
|
|
|
|
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
|
|
|
|
|
|
|
|
|
|
|
|
# 设置自动续期
|
|
|
|
|
|
sudo crontab -e
|
|
|
|
|
|
# 添加以下行:
|
|
|
|
|
|
0 12 * * * /usr/bin/certbot renew --quiet
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🗄️ 数据库配置
|
|
|
|
|
|
|
|
|
|
|
|
### 数据库选择建议
|
|
|
|
|
|
|
|
|
|
|
|
| 数据库类型 | 适用场景 | 优势 | 劣势 |
|
|
|
|
|
|
|------------|----------|------|------|
|
|
|
|
|
|
| **SQLite** | 开发环境、小规模应用、个人使用 | 零配置、无需安装、数据文件便携 | 并发能力有限、大数据量性能差 |
|
|
|
|
|
|
| **MySQL** | 生产环境、企业级应用、大规模数据 | 高性能、并发处理能力强、数据完整性好 | 需要额外配置和维护 |
|
|
|
|
|
|
|
|
|
|
|
|
### SQLite配置(推荐开发使用)
|
|
|
|
|
|
|
|
|
|
|
|
1. **默认配置**
|
|
|
|
|
|
```env
|
|
|
|
|
|
# .env 文件中保持默认配置
|
|
|
|
|
|
DB_TYPE=sqlite
|
|
|
|
|
|
DB_PATH=./idc_management.db
|
|
|
|
|
|
NODE_ENV=development
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **文件位置管理**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 备份SQLite数据库
|
|
|
|
|
|
mkdir -p backup
|
|
|
|
|
|
cp backend/idc_management.db backup/database_$(date +%Y%m%d_%H%M%S).db
|
|
|
|
|
|
|
|
|
|
|
|
# 查看数据库信息
|
|
|
|
|
|
sqlite3 backend/idc_management.db ".schema"
|
|
|
|
|
|
sqlite3 backend/idc_management.db ".tables"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### MySQL配置(推荐生产使用)
|
|
|
|
|
|
|
|
|
|
|
|
1. **创建生产数据库**
|
|
|
|
|
|
```sql
|
|
|
|
|
|
-- 创建专用数据库
|
|
|
|
|
|
CREATE DATABASE idc_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
|
|
|
|
|
|
|
|
|
|
-- 创建专用用户
|
|
|
|
|
|
CREATE USER 'idc_prod_user'@'localhost' IDENTIFIED BY 'secure_password_123!';
|
|
|
|
|
|
GRANT ALL PRIVILEGES ON idc_management.* TO 'idc_prod_user'@'localhost';
|
|
|
|
|
|
FLUSH PRIVILEGES;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **配置生产环境变量**
|
|
|
|
|
|
```env
|
|
|
|
|
|
# .env 文件
|
|
|
|
|
|
NODE_ENV=production
|
|
|
|
|
|
DB_TYPE=mysql
|
|
|
|
|
|
MYSQL_HOST=localhost
|
|
|
|
|
|
MYSQL_PORT=3306
|
|
|
|
|
|
MYSQL_USERNAME=idc_prod_user
|
|
|
|
|
|
MYSQL_PASSWORD=secure_password_123!
|
|
|
|
|
|
MYSQL_DATABASE=idc_management
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 数据备份与恢复
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 自动备份脚本
|
|
|
|
|
|
```bash
|
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
# backup_database.sh - 自动数据库备份脚本
|
|
|
|
|
|
|
|
|
|
|
|
# 设置备份目录
|
|
|
|
|
|
BACKUP_DIR="/var/backups/idc_assest"
|
|
|
|
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
|
|
|
|
|
BACKUP_FILE="$BACKUP_DIR/database_$DATE"
|
|
|
|
|
|
|
|
|
|
|
|
# 创建备份目录
|
|
|
|
|
|
mkdir -p $BACKUP_DIR
|
|
|
|
|
|
|
|
|
|
|
|
# SQLite备份
|
|
|
|
|
|
if [ -f "backend/idc_management.db" ]; then
|
|
|
|
|
|
cp backend/idc_management.db "$BACKUP_FILE.db"
|
|
|
|
|
|
echo "SQLite备份完成: $BACKUP_FILE.db"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# MySQL备份
|
|
|
|
|
|
mysqldump -u idc_prod_user -pYourPassword123! idc_management > "$BACKUP_FILE.sql"
|
|
|
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
|
|
echo "MySQL备份完成: $BACKUP_FILE.sql"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 压缩备份文件
|
|
|
|
|
|
gzip "$BACKUP_FILE.db"
|
|
|
|
|
|
gzip "$BACKUP_FILE.sql"
|
|
|
|
|
|
|
|
|
|
|
|
# 清理30天前的备份
|
|
|
|
|
|
find $BACKUP_DIR -name "database_*.gz" -mtime +30 -delete
|
|
|
|
|
|
|
|
|
|
|
|
echo "备份任务完成"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 定时任务配置
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 添加到crontab
|
|
|
|
|
|
crontab -e
|
|
|
|
|
|
|
|
|
|
|
|
# 每天凌晨2点执行备份
|
|
|
|
|
|
0 2 * * * /path/to/backup_database.sh
|
|
|
|
|
|
|
|
|
|
|
|
# 每周日凌晨3点执行完整备份
|
|
|
|
|
|
0 3 * * 0 /path/to/full_backup.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 数据恢复
|
|
|
|
|
|
|
|
|
|
|
|
**SQLite恢复**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 停止应用
|
|
|
|
|
|
pm2 stop idc-backend
|
|
|
|
|
|
|
|
|
|
|
|
# 恢复数据库
|
|
|
|
|
|
cp backup/database_20240101.db backend/idc_management.db
|
|
|
|
|
|
|
|
|
|
|
|
# 重启应用
|
|
|
|
|
|
pm2 start idc-backend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**MySQL恢复**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 停止应用
|
|
|
|
|
|
pm2 stop idc-backend
|
|
|
|
|
|
|
|
|
|
|
|
# 恢复数据库
|
|
|
|
|
|
gunzip backup/database_20240101.sql.gz
|
|
|
|
|
|
mysql -u idc_prod_user -p idc_management < backup/database_20240101.sql
|
|
|
|
|
|
|
|
|
|
|
|
# 重启应用
|
|
|
|
|
|
pm2 start idc-backend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 监控和维护
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 数据库健康检查
|
|
|
|
|
|
```bash
|
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
# health_check.sh - 数据库健康检查
|
|
|
|
|
|
|
|
|
|
|
|
# 检查SQLite
|
|
|
|
|
|
if [ -f "backend/idc_management.db" ]; then
|
|
|
|
|
|
echo "SQLite数据库文件存在"
|
|
|
|
|
|
sqlite3 backend/idc_management.db "PRAGMA integrity_check;"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "SQLite数据库文件不存在"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 检查MySQL
|
|
|
|
|
|
mysql -u idc_prod_user -pYourPassword123! -e "SELECT 1;" idc_management > /dev/null 2>&1
|
|
|
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
|
|
echo "MySQL连接正常"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "MySQL连接失败"
|
|
|
|
|
|
fi
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 性能监控
|
|
|
|
|
|
```sql
|
|
|
|
|
|
-- MySQL性能监控查询
|
|
|
|
|
|
SHOW PROCESSLIST;
|
|
|
|
|
|
SHOW ENGINE INNODB STATUS;
|
|
|
|
|
|
SELECT * FROM information_schema.innodb_trx;
|
|
|
|
|
|
SELECT * FROM information_schema.innodb_locks;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🔧 常见问题解决
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 端口冲突
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查端口占用
|
|
|
|
|
|
netstat -tulpn | grep :8000
|
|
|
|
|
|
netstat -tulpn | grep :3000
|
|
|
|
|
|
|
|
|
|
|
|
# 修改端口
|
|
|
|
|
|
PORT=8001 npm run dev # 后端
|
|
|
|
|
|
npm run dev -- --port 3001 # 前端
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 权限问题
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Linux/macOS权限修复
|
|
|
|
|
|
chmod +x backend/server.js
|
|
|
|
|
|
chown -R $USER:$USER backend/
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 依赖安装失败
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 清理缓存重新安装
|
|
|
|
|
|
npm cache clean --force
|
|
|
|
|
|
rm -rf node_modules package-lock.json
|
|
|
|
|
|
npm install
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 数据库连接失败
|
|
|
|
|
|
|
|
|
|
|
|
**SQLite连接问题**:
|
|
|
|
|
|
- 检查数据库文件权限
|
|
|
|
|
|
- 确保有写入权限
|
|
|
|
|
|
- 验证磁盘空间充足
|
|
|
|
|
|
|
|
|
|
|
|
**MySQL连接问题**:
|
|
|
|
|
|
- 检查MySQL服务是否运行:`systemctl status mysql` 或 `netstat -tulpn | grep :3306`
|
|
|
|
|
|
- 验证MySQL连接参数是否正确
|
|
|
|
|
|
- 确保数据库已创建:`CREATE DATABASE idc_management;`
|
|
|
|
|
|
- 检查MySQL用户权限
|
|
|
|
|
|
- 查看MySQL错误日志
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📊 监控和维护
|
|
|
|
|
|
|
|
|
|
|
|
### 服务监控
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查服务状态
|
|
|
|
|
|
curl http://localhost:8000/health
|
|
|
|
|
|
|
|
|
|
|
|
# 查看日志
|
|
|
|
|
|
pm2 logs idc-backend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 数据迁移
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 导出数据
|
|
|
|
|
|
node scripts/export-data.js
|
|
|
|
|
|
|
|
|
|
|
|
# 导入数据
|
|
|
|
|
|
node scripts/import-data.js backup/data.json
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 性能优化
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. PM2性能配置
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// ecosystem.config.js
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
|
apps: [{
|
|
|
|
|
|
name: 'idc-backend',
|
|
|
|
|
|
script: 'server.js',
|
|
|
|
|
|
instances: 'max', // 使用所有CPU核心
|
|
|
|
|
|
exec_mode: 'cluster',
|
|
|
|
|
|
env: {
|
|
|
|
|
|
NODE_ENV: 'production',
|
|
|
|
|
|
PORT: 8000
|
|
|
|
|
|
},
|
|
|
|
|
|
max_memory_restart: '1G', // 内存超过1G自动重启
|
|
|
|
|
|
node_args: '--max-old-space-size=1024'
|
|
|
|
|
|
}]
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 数据库优化
|
|
|
|
|
|
```sql
|
|
|
|
|
|
-- MySQL性能优化
|
|
|
|
|
|
SET GLOBAL innodb_buffer_pool_size = 1073741824; -- 1GB
|
|
|
|
|
|
SET GLOBAL query_cache_size = 67108864; -- 64MB
|
|
|
|
|
|
|
|
|
|
|
|
-- 创建索引优化查询
|
|
|
|
|
|
CREATE INDEX idx_device_rack ON devices(rackId);
|
|
|
|
|
|
CREATE INDEX idx_device_type ON devices(deviceType);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🔒 安全配置
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 防火墙配置
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Ubuntu/Debian UFW
|
|
|
|
|
|
sudo ufw default deny incoming
|
|
|
|
|
|
sudo ufw default allow outgoing
|
|
|
|
|
|
sudo ufw allow ssh
|
|
|
|
|
|
sudo ufw allow 80/tcp
|
|
|
|
|
|
sudo ufw allow 443/tcp
|
|
|
|
|
|
sudo ufw enable
|
|
|
|
|
|
|
|
|
|
|
|
# CentOS/RHEL firewalld
|
|
|
|
|
|
sudo firewall-cmd --set-default-zone=public
|
|
|
|
|
|
sudo firewall-cmd --permanent --add-service=ssh
|
|
|
|
|
|
sudo firewall-cmd --permanent --add-service=http
|
|
|
|
|
|
sudo firewall-cmd --permanent --add-service=https
|
|
|
|
|
|
sudo firewall-cmd --reload
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 系统安全加固
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 更新系统
|
|
|
|
|
|
sudo apt update && sudo apt upgrade -y
|
|
|
|
|
|
|
|
|
|
|
|
# 配置fail2ban防止暴力破解
|
|
|
|
|
|
sudo apt install fail2ban
|
|
|
|
|
|
sudo systemctl enable fail2ban
|
|
|
|
|
|
sudo systemctl start fail2ban
|
|
|
|
|
|
|
|
|
|
|
|
# 配置SSH密钥登录
|
|
|
|
|
|
ssh-keygen -t rsa -b 4096
|
|
|
|
|
|
ssh-copy-id user@server-ip
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 应用程序安全
|
|
|
|
|
|
```env
|
|
|
|
|
|
# .env 生产环境安全配置
|
|
|
|
|
|
NODE_ENV=production
|
|
|
|
|
|
PORT=8000
|
|
|
|
|
|
|
|
|
|
|
|
# 设置强密码
|
|
|
|
|
|
DATABASE_PASSWORD=ComplexPassword123!@#
|
|
|
|
|
|
|
|
|
|
|
|
# 启用HTTPS(使用反向代理)
|
|
|
|
|
|
FORCE_HTTPS=true
|
|
|
|
|
|
|
|
|
|
|
|
# 设置会话密钥
|
|
|
|
|
|
SESSION_SECRET=random_session_secret_key_here
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📞 技术支持
|
|
|
|
|
|
|
|
|
|
|
|
如果在安装部署过程中遇到问题,请:
|
|
|
|
|
|
|
|
|
|
|
|
1. **查看日志文件**
|
|
|
|
|
|
- 后端日志:`pm2 logs idc-backend`
|
|
|
|
|
|
- Nginx日志:`tail -f /var/log/nginx/idc_assest-error.log`
|
|
|
|
|
|
|
|
|
|
|
|
2. **检查服务状态**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
pm2 status
|
|
|
|
|
|
sudo systemctl status nginx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3. **验证配置文件**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 测试Nginx配置
|
|
|
|
|
|
sudo nginx -t
|
|
|
|
|
|
|
|
|
|
|
|
# 测试数据库连接
|
|
|
|
|
|
mysql -u idc_prod_user -p -e "SELECT 1;" idc_management
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-26 11:03:47 +08:00
|
|
|
|
## 更新升级流程
|
|
|
|
|
|
|
|
|
|
|
|
### 手动更新步骤
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 备份当前版本
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 创建备份目录
|
|
|
|
|
|
mkdir -p /var/backups/idc_assest/$(date +%Y%m%d)
|
|
|
|
|
|
cd /var/backups/idc_assest/$(date +%Y%m%d)
|
|
|
|
|
|
|
|
|
|
|
|
# 备份数据库
|
|
|
|
|
|
mysqldump -u idc_prod_user -p idc_management > database_backup.sql
|
|
|
|
|
|
|
|
|
|
|
|
# 备份配置文件
|
|
|
|
|
|
cp -r /var/www/idc_assest/backend/.env ./
|
|
|
|
|
|
cp -r /var/www/idc_assest/frontend/.env ./
|
|
|
|
|
|
|
|
|
|
|
|
# 备份上传文件
|
|
|
|
|
|
cp -r /var/www/idc_assest/backend/uploads ./
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 下载最新代码
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd /var/www/idc_assest
|
|
|
|
|
|
|
|
|
|
|
|
# 拉取最新代码
|
|
|
|
|
|
git fetch origin
|
|
|
|
|
|
git checkout main
|
|
|
|
|
|
git pull origin main
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 更新依赖
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 更新后端依赖
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
npm install
|
|
|
|
|
|
cd ..
|
|
|
|
|
|
|
|
|
|
|
|
# 更新前端依赖并构建
|
|
|
|
|
|
cd frontend
|
|
|
|
|
|
npm install
|
|
|
|
|
|
npm run build
|
|
|
|
|
|
cd ..
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. 重启服务
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 重启后端
|
|
|
|
|
|
pm2 restart idc-backend
|
|
|
|
|
|
|
|
|
|
|
|
# 重启Nginx
|
|
|
|
|
|
sudo systemctl restart nginx
|
|
|
|
|
|
|
|
|
|
|
|
# 验证服务
|
|
|
|
|
|
curl http://localhost:8000/health
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Docker环境更新
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd /var/www/idc_assest/docker
|
|
|
|
|
|
|
|
|
|
|
|
# 拉取最新代码
|
|
|
|
|
|
cd ..
|
|
|
|
|
|
git pull origin main
|
|
|
|
|
|
cd docker
|
|
|
|
|
|
|
|
|
|
|
|
# 重新构建并启动
|
|
|
|
|
|
docker-compose down
|
|
|
|
|
|
docker-compose up -d --build
|
|
|
|
|
|
|
|
|
|
|
|
# 验证服务
|
|
|
|
|
|
curl http://localhost/health
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 回滚操作
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 查看历史版本
|
|
|
|
|
|
cd /var/www/idc_assest
|
|
|
|
|
|
git log --oneline -10
|
|
|
|
|
|
|
|
|
|
|
|
# 回滚到指定版本
|
|
|
|
|
|
git checkout <commit-hash>
|
|
|
|
|
|
|
|
|
|
|
|
# 重新构建
|
|
|
|
|
|
cd frontend && npm run build && cd ..
|
|
|
|
|
|
cd backend && npm install && cd ..
|
|
|
|
|
|
|
|
|
|
|
|
# 重启服务
|
|
|
|
|
|
pm2 restart idc-backend
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 版本兼容性检查
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查Node.js版本
|
|
|
|
|
|
node --version
|
|
|
|
|
|
|
|
|
|
|
|
# 检查依赖版本
|
|
|
|
|
|
cd backend && npm list | grep -E "(express|sequelize|mysql2)" && cd ..
|
|
|
|
|
|
cd frontend && npm list | grep -E "(react|antd|vite)" && cd ..
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📊 系统架构说明
|
|
|
|
|
|
|
|
|
|
|
|
### 整体架构图
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ 用户访问层 │
|
|
|
|
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
|
|
|
|
│ │ 浏览器 │ │ 移动端 │ │ API客户端 │ │
|
|
|
|
|
|
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
|
|
|
|
|
|
└─────────┼──────────────────┼──────────────────┼───────────────┘
|
|
|
|
|
|
│ │ │
|
|
|
|
|
|
└──────────────────┼──────────────────┘
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ Web服务层 │
|
|
|
|
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
|
|
|
|
│ │ Nginx / Apache │ │
|
|
|
|
|
|
│ │ • 静态资源服务 • 反向代理 • SSL终端 • 负载均衡 │ │
|
|
|
|
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
|
|
|
|
└─────────────────────────┬───────────────────────────────────────┘
|
|
|
|
|
|
│
|
|
|
|
|
|
┌───────────────┼───────────────┐
|
|
|
|
|
|
│ │ │
|
|
|
|
|
|
▼ ▼ ▼
|
|
|
|
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
|
|
|
|
│ 前端应用 │ │ 后端API │ │ 静态资源 │
|
|
|
|
|
|
│ (React) │ │ (Express) │ │ (Nginx) │
|
|
|
|
|
|
│ 端口: 3000 │ │ 端口: 8000 │ │ 端口: 80/443 │
|
|
|
|
|
|
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ 数据存储层 │
|
|
|
|
|
|
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
|
|
|
|
│ │ MySQL │ │ SQLite │ │ 文件存储 │ │
|
|
|
|
|
|
│ │ 端口: 3306 │ │ 嵌入式 │ │ uploads/ │ │
|
|
|
|
|
|
│ │ │ │ │ │ │ │
|
|
|
|
|
|
│ │ • 设备信息 │ │ • 开发环境 │ │ • 设备图片 │ │
|
|
|
|
|
|
│ │ • 用户数据 │ │ • 快速部署 │ │ • 附件 │ │
|
|
|
|
|
|
│ │ • 工单记录 │ │ │ │ • 备份文件 │ │
|
|
|
|
|
|
│ │ • 耗材库存 │ │ │ │ │ │
|
|
|
|
|
|
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
|
|
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈版本
|
|
|
|
|
|
|
|
|
|
|
|
| 层级 | 技术 | 版本要求 | 用途 |
|
|
|
|
|
|
|------|------|----------|------|
|
|
|
|
|
|
| 前端 | React | 18.2.0+ | UI框架 |
|
|
|
|
|
|
| 前端 | Ant Design | 5.8.6+ | 组件库 |
|
|
|
|
|
|
| 前端 | Vite | 4.4.9+ | 构建工具 |
|
|
|
|
|
|
| 前端 | Three.js | 0.160.0+ | 3D可视化 |
|
|
|
|
|
|
| 后端 | Node.js | 14.0.0+ | 运行时 |
|
|
|
|
|
|
| 后端 | Express | 4.18.2+ | Web框架 |
|
|
|
|
|
|
| 后端 | Sequelize | 6.32.1+ | ORM框架 |
|
|
|
|
|
|
| 数据库 | MySQL | 8.0+ | 主数据库 |
|
|
|
|
|
|
| 数据库 | SQLite | 5.1.6+ | 嵌入式数据库 |
|
|
|
|
|
|
| 服务器 | Nginx | 1.18+ | 反向代理 |
|
|
|
|
|
|
| 进程管理 | PM2 | 5.0+ | 进程管理 |
|
|
|
|
|
|
|
|
|
|
|
|
### 数据流说明
|
|
|
|
|
|
|
|
|
|
|
|
1. **用户请求流程**
|
|
|
|
|
|
- 用户通过浏览器访问系统
|
|
|
|
|
|
- 请求首先到达Nginx
|
|
|
|
|
|
- Nginx判断请求类型:
|
|
|
|
|
|
- 静态资源:直接返回
|
|
|
|
|
|
- API请求:转发到后端服务
|
|
|
|
|
|
- 前端路由:返回index.html
|
|
|
|
|
|
|
|
|
|
|
|
2. **数据处理流程**
|
|
|
|
|
|
- 后端接收API请求
|
|
|
|
|
|
- 验证用户身份和权限
|
|
|
|
|
|
- 通过Sequelize操作数据库
|
|
|
|
|
|
- 返回JSON响应
|
|
|
|
|
|
|
|
|
|
|
|
3. **实时通信**
|
|
|
|
|
|
- WebSocket用于实时告警推送
|
|
|
|
|
|
- HTTP轮询用于数据刷新
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🔍 故障排查指南
|
|
|
|
|
|
|
|
|
|
|
|
### 常见错误及解决方案
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 后端服务无法启动
|
|
|
|
|
|
|
|
|
|
|
|
**错误信息**:Error: listen EADDRINUSE: address already in use :::8000
|
|
|
|
|
|
|
|
|
|
|
|
**原因分析**:端口8000已被其他进程占用
|
|
|
|
|
|
|
|
|
|
|
|
**解决方案**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 查看占用端口的进程
|
|
|
|
|
|
netstat -tulpn | grep :8000
|
|
|
|
|
|
lsof -i :8000
|
|
|
|
|
|
|
|
|
|
|
|
# 终止占用进程
|
|
|
|
|
|
kill -9 <PID>
|
|
|
|
|
|
|
|
|
|
|
|
# 或修改为其他端口
|
|
|
|
|
|
PORT=8001 npm run dev
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 数据库连接失败
|
|
|
|
|
|
|
|
|
|
|
|
**错误信息**:SequelizeConnectionError: Access denied for user
|
|
|
|
|
|
|
|
|
|
|
|
**原因分析**:数据库用户名或密码错误
|
|
|
|
|
|
|
|
|
|
|
|
**解决方案**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查.env配置
|
|
|
|
|
|
cat backend/.env | grep -E "(MYSQL|USERNAME|PASSWORD)"
|
|
|
|
|
|
|
|
|
|
|
|
# 测试数据库连接
|
|
|
|
|
|
mysql -u idc_user -p -h localhost
|
|
|
|
|
|
|
|
|
|
|
|
# 检查MySQL服务状态
|
|
|
|
|
|
sudo systemctl status mysql
|
|
|
|
|
|
sudo systemctl start mysql
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 前端构建失败
|
|
|
|
|
|
|
|
|
|
|
|
**错误信息**:Error: Cannot find module 'node-sass'
|
|
|
|
|
|
|
|
|
|
|
|
**原因分析**:依赖安装不完整
|
|
|
|
|
|
|
|
|
|
|
|
**解决方案**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 清理并重新安装依赖
|
|
|
|
|
|
cd frontend
|
|
|
|
|
|
rm -rf node_modules package-lock.json
|
|
|
|
|
|
npm install
|
|
|
|
|
|
|
|
|
|
|
|
# 检查Node.js版本兼容性
|
|
|
|
|
|
node --version
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. Nginx 502 Bad Gateway
|
|
|
|
|
|
|
|
|
|
|
|
**原因分析**:后端服务未运行或连接超时
|
|
|
|
|
|
|
|
|
|
|
|
**解决方案**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查后端服务状态
|
|
|
|
|
|
pm2 status
|
|
|
|
|
|
|
|
|
|
|
|
# 查看后端日志
|
|
|
|
|
|
pm2 logs idc-backend
|
|
|
|
|
|
|
|
|
|
|
|
# 检查Nginx错误日志
|
|
|
|
|
|
tail -f /var/log/nginx/idc_assest-error.log
|
|
|
|
|
|
|
|
|
|
|
|
# 测试后端服务
|
|
|
|
|
|
curl http://127.0.0.1:8000/health
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 5. 文件上传失败
|
|
|
|
|
|
|
|
|
|
|
|
**错误信息**:Error: ENOENT: no such file or directory
|
|
|
|
|
|
|
|
|
|
|
|
**原因分析**:上传目录不存在或权限不足
|
|
|
|
|
|
|
|
|
|
|
|
**解决方案**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 创建上传目录
|
|
|
|
|
|
mkdir -p backend/uploads
|
|
|
|
|
|
chmod 755 backend/uploads
|
|
|
|
|
|
|
|
|
|
|
|
# 检查目录权限
|
|
|
|
|
|
ls -la backend/ | grep uploads
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 6. CORS跨域错误
|
|
|
|
|
|
|
|
|
|
|
|
**错误信息**:Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy
|
|
|
|
|
|
|
|
|
|
|
|
**原因分析**:CORS配置不正确
|
|
|
|
|
|
|
|
|
|
|
|
**解决方案**:
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// 检查backend/server.js中的CORS配置
|
|
|
|
|
|
const cors = require('cors');
|
|
|
|
|
|
app.use(cors({
|
|
|
|
|
|
origin: 'http://your-domain.com',
|
|
|
|
|
|
credentials: true
|
|
|
|
|
|
}));
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 诊断命令速查表
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查端口占用
|
|
|
|
|
|
netstat -tulpn | grep -E "(80|443|8000|3306)"
|
|
|
|
|
|
|
|
|
|
|
|
# 检查进程状态
|
|
|
|
|
|
ps aux | grep -E "(node|nginx|mysql)"
|
|
|
|
|
|
|
|
|
|
|
|
# 检查磁盘空间
|
|
|
|
|
|
df -h
|
|
|
|
|
|
|
|
|
|
|
|
# 检查内存使用
|
|
|
|
|
|
free -m
|
|
|
|
|
|
|
|
|
|
|
|
# 检查系统负载
|
|
|
|
|
|
top -bn1 | head -5
|
|
|
|
|
|
|
|
|
|
|
|
# 网络连通性测试
|
|
|
|
|
|
curl -I http://localhost:8000/health
|
|
|
|
|
|
curl -I http://localhost/api/devices
|
|
|
|
|
|
|
|
|
|
|
|
# 查看系统日志
|
|
|
|
|
|
tail -f /var/log/syslog
|
|
|
|
|
|
journalctl -xe
|
|
|
|
|
|
|
|
|
|
|
|
# Docker诊断(Docker部署)
|
|
|
|
|
|
docker-compose ps
|
|
|
|
|
|
docker-compose logs --tail=100
|
|
|
|
|
|
docker stats
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 日志文件位置
|
|
|
|
|
|
|
|
|
|
|
|
| 服务 | 日志位置 |
|
|
|
|
|
|
|------|----------|
|
|
|
|
|
|
| 后端(PM2) | `pm2 logs idc-backend` |
|
|
|
|
|
|
| 后端(文件) | `/var/log/idc_assest/backend/` |
|
|
|
|
|
|
| Nginx | `/var/log/nginx/idc_assest-access.log` |
|
|
|
|
|
|
| Nginx | `/var/log/nginx/idc_assest-error.log` |
|
|
|
|
|
|
| MySQL | `/var/log/mysql/error.log` |
|
|
|
|
|
|
| Docker | `docker-compose logs` |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## ⚡ 性能优化
|
|
|
|
|
|
|
|
|
|
|
|
### 后端性能优化
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. PM2集群模式
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// ecosystem.config.js
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
|
apps: [{
|
|
|
|
|
|
name: 'idc-backend',
|
|
|
|
|
|
script: 'server.js',
|
|
|
|
|
|
instances: 'max', // 使用所有CPU核心
|
|
|
|
|
|
exec_mode: 'cluster', // 集群模式
|
|
|
|
|
|
env: {
|
|
|
|
|
|
NODE_ENV: 'production',
|
|
|
|
|
|
PORT: 8000
|
|
|
|
|
|
},
|
|
|
|
|
|
max_memory_restart: '1G', // 内存超过1G自动重启
|
|
|
|
|
|
node_args: '--max-old-space-size=1024',
|
|
|
|
|
|
listen_timeout: 3000, // 监听超时
|
|
|
|
|
|
kill_timeout: 5000, // 终止超时
|
|
|
|
|
|
max_restarts: 10, // 最大重启次数
|
|
|
|
|
|
min_uptime: '10s' // 最小运行时间
|
|
|
|
|
|
}]
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 数据库连接池优化
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// backend/db.js
|
|
|
|
|
|
const sequelize = new Sequelize({
|
|
|
|
|
|
dialect: 'mysql',
|
|
|
|
|
|
host: process.env.MYSQL_HOST,
|
|
|
|
|
|
port: process.env.MYSQL_PORT,
|
|
|
|
|
|
username: process.env.MYSQL_USERNAME,
|
|
|
|
|
|
password: process.env.MYSQL_PASSWORD,
|
|
|
|
|
|
database: process.env.MYSQL_DATABASE,
|
|
|
|
|
|
pool: {
|
|
|
|
|
|
max: 20, // 最大连接数
|
|
|
|
|
|
min: 5, // 最小连接数
|
|
|
|
|
|
acquire: 60000, // 获取连接最大等待时间
|
|
|
|
|
|
idle: 10000 // 连接空闲最大时间
|
|
|
|
|
|
},
|
|
|
|
|
|
logging: false, // 关闭SQL日志
|
|
|
|
|
|
dialectOptions: {
|
|
|
|
|
|
charset: 'utf8mb4'
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 缓存策略
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// 使用内存缓存热点数据
|
|
|
|
|
|
const cache = new Map();
|
|
|
|
|
|
|
|
|
|
|
|
// 设备统计缓存(5分钟过期)
|
|
|
|
|
|
function getDeviceStats() {
|
|
|
|
|
|
const cacheKey = 'device_stats';
|
|
|
|
|
|
const cached = cache.get(cacheKey);
|
|
|
|
|
|
|
|
|
|
|
|
if (cached && Date.now() - cached.time < 5 * 60 * 1000) {
|
|
|
|
|
|
return cached.data;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const stats = calculateDeviceStats();
|
|
|
|
|
|
cache.set(cacheKey, { data: stats, time: Date.now() });
|
|
|
|
|
|
return stats;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 数据库性能优化
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 创建索引
|
|
|
|
|
|
|
|
|
|
|
|
```sql
|
|
|
|
|
|
-- 设备表索引
|
|
|
|
|
|
CREATE INDEX idx_device_rack ON devices(rackId);
|
|
|
|
|
|
CREATE INDEX idx_device_type ON devices(deviceType);
|
|
|
|
|
|
CREATE INDEX idx_device_status ON devices(status);
|
|
|
|
|
|
CREATE INDEX idx_device_created ON devices(createdAt);
|
|
|
|
|
|
|
|
|
|
|
|
-- 工单表索引
|
|
|
|
|
|
CREATE INDEX idx_ticket_status ON tickets(status);
|
|
|
|
|
|
CREATE INDEX idx_ticket_priority ON tickets(priority);
|
|
|
|
|
|
CREATE INDEX idx_ticket_device ON tickets(deviceId);
|
|
|
|
|
|
CREATE INDEX idx_ticket_created ON tickets(createdAt);
|
|
|
|
|
|
|
|
|
|
|
|
-- 耗材表索引
|
|
|
|
|
|
CREATE INDEX idx_consumable_category ON consumables(category);
|
|
|
|
|
|
CREATE INDEX idx_consumable_status ON consumables(status);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. MySQL配置优化
|
|
|
|
|
|
|
|
|
|
|
|
```ini
|
|
|
|
|
|
# /etc/mysql/mysql.conf.d/mysqld.cnf
|
|
|
|
|
|
|
|
|
|
|
|
[mysqld]
|
|
|
|
|
|
# 缓冲池大小(建议为物理内存的70%)
|
|
|
|
|
|
innodb_buffer_pool_size = 2G
|
|
|
|
|
|
|
|
|
|
|
|
# 日志文件大小
|
|
|
|
|
|
innodb_log_file_size = 512M
|
|
|
|
|
|
|
|
|
|
|
|
# 刷新策略
|
|
|
|
|
|
innodb_flush_log_at_trx_commit = 2
|
|
|
|
|
|
innodb_flush_method = O_DIRECT
|
|
|
|
|
|
|
|
|
|
|
|
# 连接数
|
|
|
|
|
|
max_connections = 200
|
|
|
|
|
|
|
|
|
|
|
|
# 查询缓存(MySQL 8.0已移除)
|
|
|
|
|
|
# query_cache_type = 0
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 前端性能优化
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 构建优化
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// vite.config.js
|
|
|
|
|
|
import { defineConfig } from 'vite';
|
|
|
|
|
|
import react from '@vitejs/plugin-react';
|
|
|
|
|
|
|
|
|
|
|
|
export default defineConfig({
|
|
|
|
|
|
plugins: [react()],
|
|
|
|
|
|
build: {
|
|
|
|
|
|
// 开启压缩
|
|
|
|
|
|
minify: 'terser',
|
|
|
|
|
|
terserOptions: {
|
|
|
|
|
|
compress: {
|
|
|
|
|
|
drop_console: true,
|
|
|
|
|
|
drop_debugger: true
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 代码分割
|
|
|
|
|
|
rollupOptions: {
|
|
|
|
|
|
output: {
|
|
|
|
|
|
manualChunks: {
|
|
|
|
|
|
'antd': ['antd', '@ant-design/icons'],
|
|
|
|
|
|
'charts': ['recharts'],
|
|
|
|
|
|
'three': ['three']
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 资源优化
|
|
|
|
|
|
assetsDir: 'assets',
|
|
|
|
|
|
chunkSizeWarningLimit: 1000
|
|
|
|
|
|
},
|
|
|
|
|
|
// 依赖预构建
|
|
|
|
|
|
optimizeDeps: {
|
|
|
|
|
|
include: ['antd', 'axios', 'react-router-dom']
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 路由懒加载
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// App.jsx
|
|
|
|
|
|
import { lazy, Suspense } from 'react';
|
|
|
|
|
|
|
|
|
|
|
|
const Dashboard = lazy(() => import('./pages/Dashboard'));
|
|
|
|
|
|
const DeviceManagement = lazy(() => import('./pages/DeviceManagement'));
|
|
|
|
|
|
|
|
|
|
|
|
// 使用
|
|
|
|
|
|
<Suspense fallback={<Loading />}>
|
|
|
|
|
|
<Routes>
|
|
|
|
|
|
<Route path="/" element={<Dashboard />} />
|
|
|
|
|
|
</Routes>
|
|
|
|
|
|
</Suspense>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Nginx性能优化
|
|
|
|
|
|
|
|
|
|
|
|
```nginx
|
|
|
|
|
|
# /etc/nginx/nginx.conf
|
|
|
|
|
|
|
|
|
|
|
|
worker_processes auto;
|
|
|
|
|
|
worker_rlimit_nofile 65535;
|
|
|
|
|
|
|
|
|
|
|
|
events {
|
|
|
|
|
|
worker_connections 2048;
|
|
|
|
|
|
use epoll;
|
|
|
|
|
|
multi_accept on;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
http {
|
|
|
|
|
|
# 打开文件缓存
|
|
|
|
|
|
open_file_cache max=10000 inactive=20s;
|
|
|
|
|
|
open_file_cache_valid 30s;
|
|
|
|
|
|
open_file_cache_min_uses 2;
|
|
|
|
|
|
|
|
|
|
|
|
# Gzip压缩
|
|
|
|
|
|
gzip on;
|
|
|
|
|
|
gzip_vary on;
|
|
|
|
|
|
gzip_min_length 1024;
|
|
|
|
|
|
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
|
|
|
|
|
|
|
|
|
|
|
|
# 缓冲区优化
|
|
|
|
|
|
client_body_buffer_size 16K;
|
|
|
|
|
|
client_max_body_size 100M;
|
|
|
|
|
|
proxy_buffer_size 128K;
|
|
|
|
|
|
proxy_buffers 4 256K;
|
|
|
|
|
|
proxy_busy_buffers_size 256K;
|
|
|
|
|
|
|
|
|
|
|
|
# 连接超时
|
|
|
|
|
|
keepalive_timeout 65;
|
|
|
|
|
|
keepalive_requests 100;
|
|
|
|
|
|
|
|
|
|
|
|
# 上游服务器配置
|
|
|
|
|
|
upstream backend {
|
|
|
|
|
|
server 127.0.0.1:8000;
|
|
|
|
|
|
keepalive 32;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📝 日志管理
|
|
|
|
|
|
|
|
|
|
|
|
### 日志配置
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
// backend/logger.js
|
|
|
|
|
|
const winston = require('winston');
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
|
|
|
|
const logDir = process.env.LOG_DIR || './logs';
|
|
|
|
|
|
|
|
|
|
|
|
const logger = winston.createLogger({
|
|
|
|
|
|
level: process.env.LOG_LEVEL || 'info',
|
|
|
|
|
|
format: winston.format.combine(
|
|
|
|
|
|
winston.format.timestamp({
|
|
|
|
|
|
format: 'YYYY-MM-DD HH:mm:ss'
|
|
|
|
|
|
}),
|
|
|
|
|
|
winston.format.errors({ stack: true }),
|
|
|
|
|
|
winston.format.json()
|
|
|
|
|
|
),
|
|
|
|
|
|
defaultMeta: { service: 'idc-backend' },
|
|
|
|
|
|
transports: [
|
|
|
|
|
|
// 错误日志
|
|
|
|
|
|
new winston.transports.File({
|
|
|
|
|
|
filename: path.join(logDir, 'error.log'),
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
maxsize: 10485760, // 10MB
|
|
|
|
|
|
maxFiles: 10
|
|
|
|
|
|
}),
|
|
|
|
|
|
// 组合日志
|
|
|
|
|
|
new winston.transports.File({
|
|
|
|
|
|
filename: path.join(logDir, 'combined.log'),
|
|
|
|
|
|
maxsize: 10485760,
|
|
|
|
|
|
maxFiles: 10
|
|
|
|
|
|
}),
|
|
|
|
|
|
// 控制台输出
|
|
|
|
|
|
new winston.transports.Console({
|
|
|
|
|
|
format: winston.format.combine(
|
|
|
|
|
|
winston.format.colorize(),
|
|
|
|
|
|
winston.format.simple()
|
|
|
|
|
|
)
|
|
|
|
|
|
})
|
|
|
|
|
|
]
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = logger;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 日志轮转配置
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 使用logrotate(Linux)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# /etc/logrotate.d/idc_assest
|
|
|
|
|
|
/var/log/idc_assest/*.log {
|
|
|
|
|
|
daily
|
|
|
|
|
|
missingok
|
|
|
|
|
|
rotate 14
|
|
|
|
|
|
compress
|
|
|
|
|
|
delaycompress
|
|
|
|
|
|
notifempty
|
|
|
|
|
|
create 0640 www-data www-data
|
|
|
|
|
|
sharedscripts
|
|
|
|
|
|
postrotate
|
|
|
|
|
|
pm2 restart idc-backend > /dev/null 2>&1 || true
|
|
|
|
|
|
endscript
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 使用PM2日志轮转
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 安装pm2-logrotate
|
|
|
|
|
|
pm2 install pm2-logrotate
|
|
|
|
|
|
|
|
|
|
|
|
# 配置
|
|
|
|
|
|
pm2 set pm2-logrotate:max_size 50M # 单个文件最大50MB
|
|
|
|
|
|
pm2 set pm2-logrotate:retain 30 # 保留30个文件
|
|
|
|
|
|
pm2 set pm2-logrotate:compress true # 压缩历史文件
|
|
|
|
|
|
pm2 set pm2-logrotate:dateFormat YYYY-MM-DD_HH-mm-ss
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 日志分析示例
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 查看错误日志
|
|
|
|
|
|
tail -f /var/log/idc_assest/error.log
|
|
|
|
|
|
|
|
|
|
|
|
# 统计API响应时间
|
|
|
|
|
|
grep -o '"duration":[0-9]*' /var/log/idc_assest/combined.log | \
|
|
|
|
|
|
awk -F: '{sum+=$2; count++} END {print "平均响应时间:", sum/count, "ms"}'
|
|
|
|
|
|
|
|
|
|
|
|
# 统计用户登录情况
|
|
|
|
|
|
grep "登录成功" /var/log/idc_assest/combined.log | \
|
|
|
|
|
|
awk '{print $4}' | sort | uniq -c | sort -rn
|
|
|
|
|
|
|
|
|
|
|
|
# 查找异常请求
|
|
|
|
|
|
grep -E "(ERROR|500|401)" /var/log/idc_assest/error.log
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 💾 备份与灾难恢复
|
|
|
|
|
|
|
|
|
|
|
|
### 备份策略
|
|
|
|
|
|
|
|
|
|
|
|
| 备份类型 | 频率 | 保留时间 | 说明 |
|
|
|
|
|
|
|----------|------|----------|------|
|
|
|
|
|
|
| 全量备份 | 每周日凌晨3点 | 4周 | 完整数据库备份 |
|
|
|
|
|
|
| 增量备份 | 每天凌晨2点 | 7天 | 每日变更数据 |
|
|
|
|
|
|
| 实时备份 | 持续 | 永久 | 二进制日志 |
|
|
|
|
|
|
| 配置备份 | 每次变更 | 12个月 | 配置文件和代码 |
|
|
|
|
|
|
|
|
|
|
|
|
### 自动化备份脚本
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
# backup_full.sh - 完整备份脚本
|
|
|
|
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
|
|
# 配置
|
|
|
|
|
|
BACKUP_DIR="/var/backups/idc_assest"
|
|
|
|
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
|
|
|
|
|
BACKUP_FILE="$BACKUP_DIR/full_backup_$DATE"
|
|
|
|
|
|
KEEP_DAYS=30
|
|
|
|
|
|
|
|
|
|
|
|
# 创建备份目录
|
|
|
|
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
|
|
|
|
|
|
|
|
# 1. 备份数据库
|
|
|
|
|
|
echo "正在备份数据库..."
|
|
|
|
|
|
mysqldump -u idc_prod_user -p"$MYSQL_PASSWORD" \
|
|
|
|
|
|
--single-transaction \
|
|
|
|
|
|
--routines \
|
|
|
|
|
|
--triggers \
|
|
|
|
|
|
--events \
|
|
|
|
|
|
idc_management | gzip > "$BACKUP_FILE.sql.gz"
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 备份配置文件
|
|
|
|
|
|
echo "正在备份配置文件..."
|
|
|
|
|
|
tar czf "$BACKUP_DIR/config_$DATE.tar.gz" \
|
|
|
|
|
|
backend/.env \
|
|
|
|
|
|
nginx/conf.d/
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 备份上传文件
|
|
|
|
|
|
echo "正在备份上传文件..."
|
|
|
|
|
|
tar czf "$BACKUP_DIR/uploads_$DATE.tar.gz" \
|
|
|
|
|
|
backend/uploads/
|
|
|
|
|
|
|
|
|
|
|
|
# 4. 备份代码(排除node_modules)
|
|
|
|
|
|
echo "正在备份代码..."
|
|
|
|
|
|
tar czf "$BACKUP_DIR/code_$DATE.tar.gz" \
|
|
|
|
|
|
--exclude=node_modules \
|
|
|
|
|
|
--exclude=dist \
|
|
|
|
|
|
--exclude=uploads \
|
|
|
|
|
|
.
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 清理旧备份
|
|
|
|
|
|
echo "正在清理旧备份..."
|
|
|
|
|
|
find "$BACKUP_DIR" -name "full_backup_*.sql.gz" -mtime +$KEEP_DAYS -delete
|
|
|
|
|
|
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +$KEEP_DAYS -delete
|
|
|
|
|
|
|
|
|
|
|
|
# 6. 验证备份
|
|
|
|
|
|
echo "正在验证备份..."
|
|
|
|
|
|
if [ -f "$BACKUP_FILE.sql.gz" ]; then
|
|
|
|
|
|
gunzip -t "$BACKUP_FILE.sql.gz" && echo "数据库备份验证成功"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 7. 生成备份清单
|
|
|
|
|
|
echo "备份完成,文件列表:"
|
|
|
|
|
|
ls -lh "$BACKUP_DIR"/*"$DATE"*
|
|
|
|
|
|
|
|
|
|
|
|
# 8. 发送通知(可选)
|
|
|
|
|
|
# curl -X POST "https://hooks.example.com/notify" -d "backup completed"
|
|
|
|
|
|
|
|
|
|
|
|
echo "备份任务完成:$DATE"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 定时任务配置
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# crontab配置
|
|
|
|
|
|
crontab -e
|
|
|
|
|
|
|
|
|
|
|
|
# 每日增量备份(凌晨2点)
|
|
|
|
|
|
0 2 * * * /var/www/idc_assest/scripts/backup_incremental.sh
|
|
|
|
|
|
|
|
|
|
|
|
# 每周完整备份(周日凌晨3点)
|
|
|
|
|
|
0 3 * * 0 /var/www/idc_assest/scripts/backup_full.sh
|
|
|
|
|
|
|
|
|
|
|
|
# 每月清理旧备份(每月1日凌晨4点)
|
|
|
|
|
|
0 4 1 * * /var/www/idc_assest/scripts/cleanup_old_backups.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 灾难恢复流程
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 数据恢复步骤
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 1. 停止服务
|
|
|
|
|
|
pm2 stop idc-backend
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 恢复数据库
|
|
|
|
|
|
gunzip -c /var/backups/idc_assest/full_backup_20240101_030000.sql.gz | \
|
|
|
|
|
|
mysql -u idc_prod_user -p idc_management
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 恢复配置文件
|
|
|
|
|
|
tar xzf /var/backups/idc_assest/config_20240101.tar.gz -C /
|
|
|
|
|
|
|
|
|
|
|
|
# 4. 恢复上传文件
|
|
|
|
|
|
tar xzf /var/backups/idc_assest/uploads_20240101.tar.gz -C /
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 重启服务
|
|
|
|
|
|
pm2 restart idc-backend
|
|
|
|
|
|
|
|
|
|
|
|
# 6. 验证恢复
|
|
|
|
|
|
curl http://localhost:8000/health
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 完整系统恢复
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 1. 创建新服务器
|
|
|
|
|
|
# 2. 安装必要软件
|
|
|
|
|
|
# 3. 从Git克隆代码
|
|
|
|
|
|
# 4. 恢复配置文件
|
|
|
|
|
|
# 5. 恢复数据库
|
|
|
|
|
|
# 6. 恢复上传文件
|
|
|
|
|
|
# 7. 重新安装依赖
|
|
|
|
|
|
# 8. 重启服务
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 备份验证
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
# verify_backup.sh - 备份验证脚本
|
|
|
|
|
|
|
|
|
|
|
|
BACKUP_FILE="$1"
|
|
|
|
|
|
|
|
|
|
|
|
if [ -z "$BACKUP_FILE" ]; then
|
|
|
|
|
|
echo "用法: $0 <备份文件>"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "正在验证备份文件:$BACKUP_FILE"
|
|
|
|
|
|
|
|
|
|
|
|
# 检查文件存在
|
|
|
|
|
|
if [ ! -f "$BACKUP_FILE" ]; then
|
|
|
|
|
|
echo "错误:文件不存在"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 检查文件大小(至少1KB)
|
|
|
|
|
|
FILE_SIZE=$(stat -f%z "$BACKUP_FILE" 2>/dev/null || stat -c%s "$BACKUP_FILE")
|
|
|
|
|
|
if [ "$FILE_SIZE" -lt 1024 ]; then
|
|
|
|
|
|
echo "警告:文件大小异常小"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 对于SQL备份,验证SQL语法
|
|
|
|
|
|
if [[ "$BACKUP_FILE" == *.sql.gz ]]; then
|
|
|
|
|
|
echo "验证SQL语法..."
|
|
|
|
|
|
gunzip -c "$BACKUP_FILE" | head -100 | grep -q "INSERT INTO\|CREATE TABLE"
|
|
|
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
|
|
echo "✓ SQL语法验证通过"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "✗ SQL语法验证失败"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 对于压缩包,验证完整性
|
|
|
|
|
|
if [[ "$BACKUP_FILE" == *.tar.gz ]]; then
|
|
|
|
|
|
echo "验证压缩包完整性..."
|
|
|
|
|
|
tar -tzf "$BACKUP_FILE" > /dev/null 2>&1
|
|
|
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
|
|
echo "✓ 压缩包验证通过"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "✗ 压缩包验证失败"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "备份验证完成"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🔐 安全加固清单
|
|
|
|
|
|
|
|
|
|
|
|
### 服务器安全
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 配置防火墙规则(仅开放必要端口)
|
|
|
|
|
|
- [ ] 启用SSH密钥认证,禁用密码登录
|
|
|
|
|
|
- [ ] 安装配置fail2ban防止暴力破解
|
|
|
|
|
|
- [ ] 定期更新系统安全补丁
|
|
|
|
|
|
- [ ] 配置自动安全更新
|
|
|
|
|
|
- [ ] 启用系统审计日志
|
|
|
|
|
|
- [ ] 限制root用户登录
|
|
|
|
|
|
|
|
|
|
|
|
### 数据库安全
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 使用强密码策略
|
|
|
|
|
|
- [ ] 创建专用数据库用户,禁用root远程登录
|
|
|
|
|
|
- [ ] 定期备份数据库
|
|
|
|
|
|
- [ ] 启用数据库审计日志
|
|
|
|
|
|
- [ ] 限制数据库用户权限(最小权限原则)
|
|
|
|
|
|
- [ ] 加密数据库连接(SSL/TLS)
|
|
|
|
|
|
|
|
|
|
|
|
### 应用安全
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 配置HTTPS强制跳转
|
|
|
|
|
|
- [ ] 设置安全的Cookie属性(HttpOnly, Secure)
|
|
|
|
|
|
- [ ] 启用CSRF防护
|
|
|
|
|
|
- [ ] 实现请求速率限制
|
|
|
|
|
|
- [ ] 配置安全的HTTP头
|
|
|
|
|
|
- [ ] 敏感信息加密存储
|
|
|
|
|
|
- [ ] 实现完善的权限控制
|
|
|
|
|
|
|
|
|
|
|
|
### 监控与告警
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 配置异常登录告警
|
|
|
|
|
|
- [ ] 启用API访问日志
|
|
|
|
|
|
- [ ] 监控服务状态和资源使用
|
|
|
|
|
|
- [ ] 配置磁盘空间告警
|
|
|
|
|
|
- [ ] 设置数据库连接数告警
|
|
|
|
|
|
- [ ] 实现自动化健康检查
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-12-20 09:37:43 +08:00
|
|
|
|
**🎉 部署完成后,您就可以开始使用IDC设备管理系统了!**
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
**⭐ 如果这个部署指南对您有帮助,请给我们一个Star!**
|