本文包含知识点:
1、nginx服务搭建
2、nginx文件上传模块搭建
3、文件重命名服务搭建
3、nginx整体配置
4、测试
引言
一般可以应用在上传不是跟频繁的场景,都可以采用Nginx上传文件。我们都知道,上传文件几乎是每个项目必备,nginx在web项目中又是不可缺的,如果能将上传功能附在nginx上,可以省掉一个文件服务系统的搭建,大大降低维护部署成本和维护成本。
文件树
nginx服务搭建
参照之前的文章:Nginx 离线安装,基于centos7 --^_^-- Linux服务启动脚本范例_cyzz谭 的博客-CSDN博客
在此基础上需要安装 openssl
参考:安装openssl和openssl-devel_thanklife的专栏-CSDN博客
nginx文件上传模块搭建
1、下载nginx-upload-module模块:
注:来源 nginx-upload-module模块使用_MyBlog-CSDN博客_nginx-upload-module
2、编译与安装
cd /usr/local/nginx/nginx-1.17.2
./configure --prefix=/usr/local/nginx/ --add-module=../nginx-upload-module-master --with-openssl=../openssl-1.0.2h --with-http_gzip_static_module --with-http_ssl_module --with-pcre=../pcre-8.43/ --with-zlib=../zlib-1.2.11
make
make install
文件重命名服务搭建
因为nginx上传的文件会自动命名,而且还没有扩展名。所以需要有个重命名的服务来处理。这里采用简单的node服务。
1、安装node
参考:Linux nodejs 安装以及配置环境 - huangenai - 博客园
2、创建 rename.js 文件
目录 :/usr/local
内容:
const http = require('http');
const fs = require('fs');
/**
* 服务入口
*/
http.createServer((req, res) => {
var emp = new Object;
try {
let body = '';
req.on('data', chunk => {
body += chunk; // 获取form-data
});
// 返回结果;ip需要配置, emp.data 地址与nginx配置匹配
emp.resultCode = "10000";
emp.resultMsg = "接口请求成功";
emp.data = "http://192.168.1.1:8087/upload/public/";
req.on('end', () => {
const params = parseForm(body); // json化参数
if (params.file_name != null) {
var index = params.file_name.lastIndexOf(".");
var suffix = params.file_name.substring(index);
//没有扩展名就不需要加到名称中
if (index == -1) {
suffix = "";
}
//文件名 = 时间戳 + 原文件md5 + 文件大小
let filename = Date.now() + "_" + params.file_md5 + "_" + params.file_size + suffix;
rename(params.file_path, filename);
//JSON.stringify用于将对象转成JSON文本,JSON.parse用于将JSON文本转成对象
emp.data = emp.data + filename;
} else {
emp.resultCode = "99999";
emp.resultMsg = "上传文件异常";
emp.data = "";
}
var retval = JSON.stringify(emp);
res.end(retval);
console.log(params.file_name + " result:");
console.log(retval);
console.log("==================================================================================\n");
})
} catch (err) {
emp.resultCode = "99999";
emp.resultMsg = "异常";
emp.data = "";
var retval = JSON.stringify(emp);
res.end(retval);
}
}).listen(8288)
// 格式化参数
function parseForm(data) {
const reg = /name="([\w_]+)"\s+(.+)\s/g;
const params = {};
let matched;
while ((matched = reg.exec(data))) {
params[matched[1]] = matched[2];
}
console.log("params:");
console.log(params);
return params;
}
// 重命名方法
function rename(source, name) {
const path = require('path');
const dir = path.dirname(source);
fs.renameSync(source, path.join(dir, name));
}
启动:
nohup node rename.js >> rename.log &
关闭:直接 kill
注意:有伙伴发现关掉终端以后js程序自己就断了,需要用tmux起一个后台运行的终端去跑。
nginx整体配置
nginx安装完毕后,修改nginx.conf 文件。主要配置的地方
1、暴露外部的端口:这里采用 8087 (和 rename.js 里面的 返回地址 对应)
2、指向重命名服务的配置,端口这里用 8288 (和 rename.js 的监听端口对应)
3、文件上传模块 nginx-upload-module 的配置
nginx.conf 内容如下(文件目录:/usr/local/nginx/conf)
#user nobody;
user heandev;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件;小于设置值的文件将不会被压缩
gzip_min_length 1k;
# gzip 压缩级别 1-10
gzip_comp_level 2;
# 进行压缩的文件类型。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 100M;
client_body_buffer_size 128k;
upstream nodes {
# 本机地址
server 192.168.2.2:8087;
}
server {
# 暴露端口
listen 8087;
# 本机地址
server_name 192.168.2.2;
location /upload {
client_max_body_size 100m;
default_type application/json;
if ($request_method ~* "OPTIONS") {
return 200 '{"code": -1,"msg": "正在处理中..."}';
}
upload_pass /rename_js;
upload_resumable on; #断点续传
upload_store /program/nginx_file; #文件保存地址
upload_limit_rate 0; #上传限速 0 表示不限速
upload_store_access user:rw; #临时文件权限
upload_set_form_field "${upload_field_name}_name" $upload_file_name; #表单name值
upload_set_form_field "${upload_field_name}_content_type" $upload_content_type; #上传文件的类型
upload_set_form_field "${upload_field_name}_path" $upload_tmp_path; #文件上传后保存在服务器上的地址
upload_aggregate_form_field "${upload_field_name}_md5" $upload_file_md5; #文件md5
upload_aggregate_form_field "${upload_field_name}_size" $upload_file_size; #文件大小
#upload_pass_form_field "^submit$|^description$";
upload_pass_form_field "^.*$"; #表单参数
upload_pass_args on; #转发参数
upload_cleanup 400 404 499 500-505; #如果出现这些错误将删除保存的文件
}
# 重命名js服务
location /rename_js {
proxy_pass http://localhost:8288;
}
# 外部访问文件服务
location /upload/public/ {
alias /program/nginx_file/;
# 能看到目录所有文件
autoindex on;
}
}
}
整体结构与运行步骤
测试
1、测试工具是postman,模拟文件上传测试
2、rename.js服务日志
注意:
1、如果上传的文件访问不到,可能是nginx配置的使用用户没权限,两个方法解决
①修改/home 文件夹以及下面的所有文件的所属用户组为 fan
sudo chgrp -R fan /home
② 修改nginx配置
找到安装nginx的目录进去找到配置文件执行:vim nginx.conf
进入编辑模式将配置文件头部注释行:# user nobody;的注释去掉并改为user root;
2、如果 上传文件请求是 OPTIONS
上传后跳转到java程序重命名,这个需要自己写 java服务处理