zhibo/upload-server-example/README.md

6.7 KiB
Raw Permalink Blame History

文件上传服务器

这是一个独立的文件上传服务器,用于处理头像、作品封面、视频等文件的上传。

功能特性

  • 支持图片上传jpg, jpeg, png, gif, bmp, webp
  • 支持视频上传mp4, mov, avi, flv
  • 自动按日期分类存储文件
  • 文件大小限制500MB
  • 使用 UUID 生成唯一文件名
  • 支持 CORS 跨域请求
  • 提供静态文件访问服务

安装依赖

npm install

启动服务

开发模式(自动重启)

npm run dev

生产模式

npm start

使用 PM2 部署(推荐)

安装 PM2

npm install -g pm2

启动服务

pm2 start server.js --name file-upload-server

查看状态

pm2 status

查看日志

pm2 logs file-upload-server

停止服务

pm2 stop file-upload-server

重启服务

pm2 restart file-upload-server

设置开机自启

pm2 startup
pm2 save

接口说明

1. 健康检查

GET http://1.15.149.240:30005/health

响应:

{
  "status": "ok",
  "message": "文件上传服务器运行正常",
  "timestamp": "2024-01-06T10:00:00.000Z"
}

2. 文件上传

POST http://1.15.149.240:30005/upload
Content-Type: multipart/form-data

file: [文件]
model: avatar|works|cover|video

响应:

{
  "status": 200,
  "message": "上传成功",
  "data": {
    "url": "http://1.15.149.240/uploads/avatar/2024/01/06/xxx.jpg",
    "fileName": "test.jpg",
    "fileSize": 123456,
    "mimeType": "image/jpeg"
  }
}

3. 文件访问

GET http://1.15.149.240/uploads/{model}/{year}/{month}/{day}/{filename}

示例:

http://1.15.149.240/uploads/avatar/2024/01/06/a1b2c3d4-e5f6-7890-abcd-ef1234567890.jpg

目录结构

/data/uploads/
├── avatar/          # 头像
│   └── 2024/01/06/
├── works/           # 作品图片
│   └── 2024/01/06/
├── cover/           # 封面图片
│   └── 2024/01/06/
└── video/           # 视频文件
    └── 2024/01/06/

测试命令

测试上传图片

curl -X POST http://1.15.149.240:30005/upload \
  -F "file=@test.jpg" \
  -F "model=avatar"

测试上传视频

curl -X POST http://1.15.149.240:30005/upload \
  -F "file=@test.mp4" \
  -F "model=works"

测试健康检查

curl http://1.15.149.240:30005/health

配置 Nginx

在服务器上配置 Nginx 提供静态文件访问:

server {
    listen 80;
    server_name 1.15.149.240;
    
    # 文件上传大小限制
    client_max_body_size 500M;
    
    # 静态文件访问
    location /uploads/ {
        alias /data/uploads/;
        autoindex off;
        
        # 跨域配置
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
        add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        
        # 缓存设置
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    
    # 上传接口代理(可选,如果需要通过 80 端口访问)
    location /api/upload/ {
        proxy_pass http://127.0.0.1:30005/;
        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_connect_timeout 600;
        proxy_send_timeout 600;
        proxy_read_timeout 600;
    }
}

重启 Nginx

sudo nginx -t
sudo systemctl restart nginx

防火墙配置

Ubuntu/Debian (UFW)

sudo ufw allow 30005/tcp
sudo ufw allow 80/tcp

CentOS/RHEL (firewalld)

sudo firewall-cmd --permanent --add-port=30005/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload

日志

查看实时日志

# 使用 PM2
pm2 logs file-upload-server

# 或直接查看
tail -f /path/to/logs/file-upload-server.log

监控

磁盘使用情况

df -h /data/uploads
du -sh /data/uploads/*

文件数量统计

find /data/uploads -type f | wc -l

最大的文件

find /data/uploads -type f -exec du -h {} + | sort -rh | head -20

定期清理(可选)

创建定时任务清理旧文件:

# 编辑 crontab
crontab -e

# 添加任务:每天凌晨 2 点清理 30 天前的临时文件
0 2 * * * find /data/uploads/temp -type f -mtime +30 -delete

故障排查

1. 端口被占用

# 查看端口占用
lsof -i :30005

# 或
netstat -tulpn | grep 30005

2. 权限问题

# 检查目录权限
ls -la /data/uploads

# 修改权限
sudo chown -R $USER:$USER /data/uploads
sudo chmod -R 755 /data/uploads

3. 磁盘空间不足

# 查看磁盘使用情况
df -h

# 清理空间
sudo apt clean
sudo journalctl --vacuum-time=7d

4. 服务无法启动

# 查看错误日志
pm2 logs file-upload-server --err

# 检查 Node.js 版本
node --version  # 需要 v14 或更高版本

性能优化

1. 使用 Nginx 缓存

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=upload_cache:10m max_size=1g inactive=60m;

location /uploads/ {
    proxy_cache upload_cache;
    proxy_cache_valid 200 30d;
    # ...
}

2. 启用 Gzip 压缩

gzip on;
gzip_types image/jpeg image/png image/gif;
gzip_min_length 1000;

3. 使用 CDN

将上传的文件同步到 CDN提高访问速度。

安全建议

  1. 限制文件类型:只允许特定的文件类型上传
  2. 文件大小限制:防止恶意上传大文件
  3. 病毒扫描:集成 ClamAV 等病毒扫描工具
  4. 访问控制:添加 API 认证机制
  5. HTTPS:使用 SSL 证书加密传输
  6. 防火墙:只开放必要的端口
  7. 日志审计:记录所有上传操作

备份策略

定期备份到远程服务器

# 使用 rsync
rsync -avz /data/uploads/ backup-server:/backup/uploads/

# 或使用 rclone支持云存储
rclone sync /data/uploads/ remote:backup/uploads/

创建备份脚本

#!/bin/bash
# backup-uploads.sh

DATE=$(date +%Y%m%d)
BACKUP_DIR="/backup/uploads-$DATE"

# 创建备份
tar -czf "$BACKUP_DIR.tar.gz" /data/uploads/

# 上传到云存储
# rclone copy "$BACKUP_DIR.tar.gz" remote:backups/

# 删除 7 天前的备份
find /backup -name "uploads-*.tar.gz" -mtime +7 -delete

echo "备份完成: $BACKUP_DIR.tar.gz"

添加到 crontab

0 3 * * * /path/to/backup-uploads.sh

环境要求

  • Node.js >= 14.0.0
  • npm >= 6.0.0
  • 磁盘空间 >= 100GB根据实际需求调整
  • 内存 >= 512MB

许可证

MIT