最近在用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:localagentport:localhost:remotemongodprocessportremoteloginusername@remoteserveraddress这里的本地机指的是一台服务器,因为我想写一个专门用来备份的nodejs应用,部署到一个上备份服务器。项目目录如下:├─dump//数据库存放目录├─app.js//服务器启动├─config.js//配置文件├─cronFunc.js//定时任务├─init.js//初始化function├─mongodump.js//备份数据库├─sslProxy.js//ssh正向代理├─util.js//工具功能├─package.json├─README.md├─server.json项目一共使用of3packages:"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',//数据库所在服务器登录用户NameREMOTE_DB_NAME:'my-db',//要备份的数据库名称CRON_RULE:'000/6**?',//指定cron规则,并根据这个规则进行定时备份}核心代码主要有两处:ssh正向代理//sslProxy.jsconstcmd=require('node-cmd');const{DUMPPROXY_PORT,REMOTE_MONGOD_PORT,REMOTE_HOST,REMOTE_PORT,REMOTE_USER}=require('./config')letfun={}fun.startProxy=异步函数(){try{constline=`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{thrownewError('proxyfailed')}})}catch(error){console.log('proxyfailed++++++++++++++++++++++++++++~~~~+'+error.msg)}}module.exports=fun这里我没有像mongodump.js中那样使用承诺的cmd.get方法,因为程序启动后会先运行startProxy,这里会等待继续阻塞,导致定时任务无法运行,使用异步方式不会影响备份服务器//mongodump.jsconstDUMP_DIR=path.join(__dirname,'./dump');//数据库备份地址/***@param{*}dirname目录名*@param{*}dbname对应的数据库名*/asyncfunctionbackup(dirname,dbname){try{//确定问卷文件夹constsaveDir=`${DUMP_DIR}${path.sep}${dirname}`;如果(!fs.existsSync(DUMP_DIR)){fs.mkdirSync(DUMP_DIR);}if(!fs.existsSync(saveDir)){fs.mkdirSync(saveDir);}constline=`mongodump--port${DUMPPROXY_PORT}-d${dbname}-o${saveDir}`;console.log('executecommand:'+line)//做一个备份awaitcmdPromise(line);returndbname+'数据库备份完成'+dirname;}catch(error){return`backupfailed-${error.message}`;}};对于每次备份,我只是简单地使用时间戳作为路径名,备份数据的数据库名与数据库名保持一致。项目运行后,可以先缩短定时器间隔,测试CRON_RULE:'*/60****?',我在linux(unbuntu16)上启动没问题,功能正常。备份文件带有时间戳路径名排列整齐:打开某一个,可以看到标准的bson数据库文件,可以使用mongorestore恢复。但是我在windows上启动的时候会报这个错误,功能无法实现。虽然不会在windows上使用,但还是想知道原因。希望知道的朋友可以在评论区告诉我哦!附上github项目地址:https://github.com/WkArtist/m...完
