环境 ubuntu 14.04 nginx 1.10.2 node.js 0.10.32 express 3.5.1 sequelize 1.7.0 设置了最大连接数
pool: {
maxConnections: 1000,
maxIdleTime: 30
}
mysql 5.5
我遇到的问题:
- 在使用nginx做反向代理时: 当文件小于100M时 上传成功 当文件大于100M时 上传失败 前端收到502 Bad Gateway 后端node.js报错mysql too many connections
- 不使用nginx直接访问 任意文件都可以上传成功
我所查到的最类似与我的问题为 502 Bad Gateway with “large” file uploads
现阶段我所做的工作 根据网上查询到方法,修改nginx的配置 加上了如下的 在http模块中加入
keepalive_timeout 600;
send_timeout 10m;
client_header_timeout 10m;
client_body_timeout 10m;
client_max_body_size 512m;
large_client_header_buffers 8 32k;
在server中加入
client_max_body_size 512m;
proxy_buffer_size 512k;
proxy_buffers 4 1024k;
proxy_busy_buffers_size 1024k;
其中这部分的配置将512k修改为128k 1024k修改为256k 有成功过一次 完整的nginx.conf文件如下
user root root;
worker_processes 6;
worker_cpu_affinity 000000000000000000000001 000000000000000000000010 000000000000000000000100 000000000000000000001000 000000000000000000010000 000000000000000000100000;
worker_rlimit_nofile 65530;
events {
worker_connections 65530;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
#keepalive_timeout 0;
keepalive_timeout 600;
send_timeout 10m;
client_header_timeout 10m;
client_body_timeout 10m;
client_max_body_size 512m;
large_client_header_buffers 8 32k;
gzip on;
upstream tvbox {
server 127.0.0.1:9123;
}
server {
listen 80;
server_name myip;
client_max_body_size 512m;
proxy_buffer_size 512k;
proxy_buffers 4 1024k;
proxy_busy_buffers_size 1024k;
location / {
keepalive_timeout 600;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass http://tvbox;
proxy_redirect off;
}
location ~ ^/(softwares|ad|images_activity|images_recommends|images_film|images_screen_protector|apk_dir|app_shop_dir)/ {
root /uploads;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
}
}
node.js中的接收上传文件的部分代码如下
module.exports.uploadfile = function (req, res) {
var software_version = {};
var source = req.files.uploadingfile.path;
var size = req.files.uploadingfile.size;
var minetype = req.files.uploadingfile.type;
var suffix = getExtension(req.files.uploadingfile.name);
software_version.minetype = minetype;
async.series([
// 计算文件HASH
function(callback){
var sha1 = crypto.createHash('sha1');
var s = fs.ReadStream(source);
s.on('data', function (d) {
sha1.update(d);
});
s.on('end', function () {
var hash = sha1.digest('hex');
callback(null, hash);
});
},
// 获取文件大小
function(callback){
fs.stat(source, function(err, stats){
if(err) throw err;
callback(null, stats.size);
});
}
], function(err, results){
var hash = results[0];
var size = results[1];
//查询数据库中是否有记录
db.software_version.find({
where: {
id: req.body.id
}
}).success(function(item){
if(item == null)
{
// 创建
db.software_version.create({
hash: hash,
size: size,
suffix: suffix,
minetype: minetype,
url: '/softwares/'+hash+suffix
}).success(function (software_version) {
res.json({
status: 'ok',
result: software_version
});
}).failure(function (error) {
res.json({
status: 'error',
result: {
msg: '数据库错误,请联系管理员'
}
})
});
}else{
// 更新
db.software_version.update({
hash: hash,
size: size,
suffix: suffix,
minetype: minetype,
url: '/softwares/'+hash+suffix
}, {
id: item.id
}).success(function (affected_rows) {
db.software_version.find(item.id).success(function(row){
res.json({
status: 'ok',
result: row.dataValues
});
});
}).failure(function (error) {
res.json({
status: 'error',
result: {
msg: '数据库错误,请联系管理员'
}
})
});;
}
});
});
};
最后求各位大神看下能否有什么办法解决这个问题
调整nginx的http超时以及最大允许的body size。
@stonephp client_header_timeout
client_body_timeout
keepalive_timeout
都有设置过600 client_max_body_size
也有设置为512m
检查一下你的环境是不是用nginx代理了多次
@willmynew upload file 也调大
谢谢各位 问题找到了 是sequelize的问题 我的理解为 当连接时间超过指定时间 sequelize就自动报错了 我修改了sequelize的pool设置 文件就可以上传成功了
@willmynew 应该实现断点续传功能,不应该这么大的文件直接上传,将文件分片上传,比如一片1M
来自酷炫的 CNodeMD
有上网搜过,有动手测试,这才是提问的正确姿势