最近在应用nodejs,express,mongodb做一些后端我的项目,数据量不是很大,最开始在数据库备份这一块抉择在主目录创立一个dump文件夹,程序启动时开启一个定时工作,每天凌晨1点mongodump一下以后的数据库。但总放心以后服务器硬盘坏了怎么办,我的数据不就没了?所以有了一个想法:在另一台服务器上也去定时备份我的我的项目服务器上的数据库。mongodump自身有着弱小的性能,能够近程备份数据库:
mongodump -h 远端IP地址 -u 登录用户 -p 登录明码 -d 数据库名 --port 远端mongod端口(默认27017) -o 输入到本机的门路
然而当初企业中服务器都是通过ssh去登录拜访的,mongodump提供了用户名明码的形式但没有提供应用ssh拜访的性能配置,所以这是我要解决的问题。
咱们晓得ssh命令除了登陆外还有三种代理性能:正向代理(-L)、反向代理(-R)、socks5 代理(-D),在这里咱们能够应用正向代理来代理到咱们本机的某个端口,而后再mongodump本机不就实现我的目标了吗?
ssh -L :本机代理端口:localhost:近程mongod过程端口 近程登录用户名@近程服务器地址
这里的本机指的也是一个服务器,因为我要写一个专门用来备份的nodejs利用,并部署到一个备份服务器上。
我的项目目录如下:
├─dump //数据库寄存目录├─app.js //服务器启动├─config.js //配置文件├─cronFunc.js //定时工作├─init.js //初始化性能├─mongodump.js //备份数据库├─sslProxy.js //ssh正向代理├─util.js //工具函数├─package.json├─README.md├─server.json
我的项目中一共应用了3个包:
"dependencies": { "express": "^4.17.1", //启动服务 "node-cmd": "^4.0.0", //调用零碎终端执行命令 "node-cron": "^2.0.3" //开启定时工作 }
- 配置文件
// config.jsmodule.exports = { APP_PORT: 7003, //本利用的端口 DUMPPROXY_PORT: 9876, //mongo本机代理端口 REMOTE_MONGOD_PORT: 27017, //数据库所在的服务器mongod服务端口 REMOTE_HOST: '*.*.*.*',//数据库所在的服务器地址 REMOTE_PORT: 22, //数据库所在的服务器ssh登录端口 REMOTE_USER: 'root', //数据库所在的服务器登录用户名 REMOTE_DB_NAME: 'my-db', //所需备份的数据库名 CRON_RULE: '0 0 0/6 * * ?', //指定cron规定,按此规定进行定时备份}
外围代码次要包含两处:
- ssh正向代理
// sslProxy.jsconst cmd = require('node-cmd');const {DUMPPROXY_PORT,REMOTE_MONGOD_PORT,REMOTE_HOST,REMOTE_PORT,REMOTE_USER} = require('./config')let fun = {}fun.startProxy = async function () { try{ const line = `ssh -L :${DUMPPROXY_PORT}:localhost:${REMOTE_MONGOD_PORT} ${REMOTE_USER}@${REMOTE_HOST} -p ${REMOTE_PORT}`; console.log('开始ssh正向代理'+line) cmd.get(line, (err, data) => { if (!err){ console.log('代理胜利--------------------------') }else { throw new Error('代理失败') } }) } catch(error) { console.log('代理失败++++++++++++++++++++++++++~~~~+'+error.msg) }}module.exports = fun
在这里我没有像mongodump.js中应用promise化后的cmd.get办法,是因为程序启动后先运行startProxy,在这里await时会继续阻塞,导致定时工作无奈运行,应用异步的形式就不会影响。
- 备份服务器
// mongodump.jsconst DUMP_DIR = path.join(__dirname, './dump'); // 数据库备份地址/** * @param {*} dirname 目录名称 * @param {*} dbname 对应数据库名 */async function backup(dirname, dbname) { try { // 判断问卷夹 const saveDir = `${DUMP_DIR}${path.sep}${dirname}`; if (!fs.existsSync(DUMP_DIR)) { fs.mkdirSync(DUMP_DIR); } if (!fs.existsSync(saveDir)) { fs.mkdirSync(saveDir); } const line = `mongodump --port ${DUMPPROXY_PORT} -d ${dbname} -o ${saveDir}`; console.log('执行命令:'+line) // 进行备份 await cmdPromise(line); return dbname+'数据库备份实现'+dirname; } catch (error) { return `备份失败-${error.message}`; }};
在每次备份时,我只是非常简单的应用工夫戳作为路径名,备份数据数据库名和数据库名称统一。
我的项目跑起来后能够先把定时器距离调短测试一下CRON_RULE: '*/60 * * * * ?'
,
我在linux(unbuntu16)上启动是没问题的,性能也都失常,备份文件以工夫戳未路径名参差排列:
关上某一个,能够看到规范的bson数据库文件,能够应用mongorestore进行复原。
但我在windows上启动会报这个谬误导致性能无奈实现,虽说不会在windows上应用,但还是想晓得起因,心愿晓得的小伙伴在评论区能通知一下我!
附上github我的项目地址:https://github.com/WkArtist/m...
完