---恢复内容开始---
如何做到将客户服务器数据库的备份,下载到本地的云服务上? 在开发这个程序中中途也遇到了一下问题,下面我将自己如何进解决的办法写出来供大家参考。
一.首先我需要进行描述一下问题:
1.比如有两台服务器A,B(云服务器) 将A中的服务器中的数据库的备份进行下载到B的云服务中并保存。
2.当然这台A服务器的外网是可以进行访问,如果外网访问不了的话,那也是没有办法的。
3.然后在B服务器中定期的进行删除数据库备份,定时的下载。并进行保存最新一个星期的数据库备份。
4.在云服务需要保存最新的数据库备份,当然不止一个数据库备份了,并进行定期的删除以及下载。
二:遇到的一些问题:
1.WebServices安全通道建立信任关系的异常。
2.数据库备份过大问题,无法下载。采用文件流的方式进行压缩。
3.在做定时删除以及下载的程序的时候使用Windows服务开发还是使用控制台然后挂在任务计划程序上。
4.如何进行读或者取数据库备份。通过FilesGetter.GetFiles(_fileDir, filter)方法。
5.压缩问题等等。应用BZip2.Compress(srcFile, zipFile, 8192);进行压缩以8M为一个压缩块。
6.备份策略,每天,每周,每月。应用任务计划程序。
二:需要的使用那些技术:
1.经过考虑了一下需要创建一个WebServices。
2.需要创建3个控制台应用程序其中分别包括(下载控制台应用程序,删除的控制台应用程序,压缩的控制台应用程序)。
3.文件流的使用,webClient 的应用等等
三:整个下载过程的流程图
四:各个模块的代码
1.先进行通过控制台应用程序进行对客户服务器的数据库备份进行压缩。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 string fileDir = Properties.Settings.Default.DB_FILE_PATH;//客户的服务器的数据库备份文件的路径 6 7 string saveCompress = Properties.Settings.Default.DB_COMPRESS_PATH; 8 try 9 { 10 #region 1.数据库文件所在服务器的目录的位置 11 if (string.IsNullOrEmpty(fileDir) || !Directory.Exists(fileDir)) 12 { 13 throw new Exception("配置文件目录不正确,请检查" + fileDir); 14 } 15 #endregion 16 #region 2.进行获取其中的压缩后的所有的文件 17 string[] dir = new string[] { "*.001" }; 18 List<string> dbFileUrl = new List<string>(); 19 if (dir != null) 20 { 21 foreach (var filter in dir) 22 { 23 dbFileUrl.AddRange(FilesGetter.GetFiles(fileDir, filter)); 24 } 25 } 26 #endregion 27 #region 3.引用第三方进行压缩文件并将文件放到指定的压缩的目录下面 28 if (dbFileUrl != null) 29 { 30 foreach (var url in dbFileUrl) 31 { 32 //引用第三方的ZIP压缩的方法进行压缩文件并将压缩的文件进行保存到客户的服务器的指定的目录下面 33 string zipDownUrl = saveCompress + Path.GetFileName(url) + ".rar"; 34 //进行压缩文件越大那么压缩的时间越长 35 if (url != null && zipDownUrl != null) 36 { 37 Console.WriteLine("数据库{0}文件{1}压缩开始", Path.GetFileName(url),DateTime.Now); 38 if (BZipFile(url, zipDownUrl) == true) 39 { 40 using (StreamWriter sw = new StreamWriter(saveCompress + "数据库备份压缩日志.txt", true)) 41 { 42 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + "数据库备份压缩开始" + "数据库的备份的文件压缩的文件的名称:" + Path.GetFileName(url) + "数据库备份压缩的路径:" + fileDir); 43 } 44 Console.WriteLine("数据库{0}文件{1}压缩结束", Path.GetFileName(url), DateTime.Now); 45 } 46 else 47 { 48 Console.WriteLine("数据库文件压缩失败!"); 49 } 50 } 51 else 52 { 53 Console.WriteLine("数据库文件压缩失败!"); 54 } 55 } 56 //当所有的数据库备份文件压缩完成后那么将压缩的日志进行写入到记事本中 57 using (StreamWriter sw = new StreamWriter(saveCompress + "数据库备份压缩日志.txt", true)) 58 { 59 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + "数据库备份压缩结束"); 60 } 61 } 62 63 #endregion 64 } 65 catch(Exception ex) 66 { 67 //将数据库备份的日志写入到记事本中去 68 using (StreamWriter sw = new StreamWriter(saveCompress + "数据库备份压缩日志.txt", true)) 69 { 70 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "数据库备份的压缩中进行捕捉的异常" + ex.Message); 71 } 72 } 73 74 } 75 76 /// <summary> 77 ///进行压缩数据库的备份的文件 78 /// </summary> 79 /// <param name="sourcefilename"></param> 80 /// <param name="zipfilename"></param> 81 /// <returns></returns> 82 public static bool BZipFile(string sourcefilename, string zipfilename) 83 { 84 bool blResult;//表示压缩是否成功的返回结果 85 //为源文件创建文件流实例,作为压缩方法的输入流参数 86 FileStream srcFile = File.OpenRead(sourcefilename); 87 //为压缩文件创建文件流实例,作为压缩方法的输出流参数 88 FileStream zipFile = File.Open(zipfilename, FileMode.Create); 89 try 90 { 91 //以8192节作为一个块的方式压缩文件8M一块进行压缩 92 BZip2.Compress(srcFile, zipFile, 8192); 93 blResult = true; 94 } 95 catch (Exception ex) 96 { 97 Console.WriteLine(ex.Message); 98 blResult = false; 99 } 100 srcFile.Close();//关闭源文件流 101 zipFile.Close();//关闭压缩文件流 102 return blResult; 103 } 104 }
通过创建一个控制台来进行压缩数据库备份文件
2.读取客户服务器数据库的备份压缩文件的名称,通过拼接一个下载的路径URL,返回多个数据库备份文件路径的集合。
1 namespace DBDownLoad.Server.Services 2 { 3 /// <summary> 4 /// Summary description for DbFileProvider 5 /// </summary> 6 [WebService(Namespace = "http://tempuri.org/")] 7 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 8 [System.ComponentModel.ToolboxItem(false)] 9 public class DbFileProvider : System.Web.Services.WebService 10 { 11 private static string _fileDir; 12 private static string _rootUrl; 13 [WebMethod] 14 public List<string> GetDbFile() 15 { 16 //对方客户的数据库文件所在服务器的目录的位置 17 _fileDir = System.Configuration.ConfigurationManager.AppSettings["DbBackupFilePath"]; 18 //实现文件下载地址的拼接 将所有的数据库的文件进行下载后然后进行其中的文件的拼接。 19 _rootUrl = System.Configuration.ConfigurationManager.AppSettings["DbBackupFileRootUrl"]; 20 #region 1.数据库文件所在服务器的目录的位置 21 List<string> displayUrlList = new List<string>(); 22 if (string.IsNullOrEmpty(_fileDir) || !Directory.Exists(_fileDir)) 23 { 24 throw new Exception("配置文件目录不正确,请检查" + _fileDir); 25 } 26 #endregion 27 #region 2.确定其中的文件是否下载成功 28 string[] txt = new string[] { "*.txt" }; 29 List<string> dbTxt = new List<string>(); 30 if (txt != null) 31 { 32 foreach (var items in txt) 33 { 34 dbTxt.AddRange(FilesGetter.GetFiles(_fileDir, items)); 35 } 36 } 37 #endregion 38 if (dbTxt.Count()>0) 39 { 40 #region 3.进行获取其中的压缩后的所有的文件 41 string[] dir = new string[] { "*.rar" }; 42 List<string> dbFileUrl = new List<string>(); 43 if (dir != null) 44 { 45 foreach (var filter in dir) 46 { 47 dbFileUrl.AddRange(FilesGetter.GetFiles(_fileDir, filter)); 48 } 49 } 50 #endregion 51 #region 4.进行获取备份文件的文件名和时间的集合 52 List<DBNameAndTime> dbFileNameList = new List<DBNameAndTime>(); 53 if (dbFileUrl != null) 54 { 55 foreach (var url in dbFileUrl) 56 { 57 FileInfo fi = new FileInfo(url); 58 DBNameAndTime file = new DBNameAndTime(); 59 file.FileName = fi.Name;// 文件名 60 file.FileTime = fi.LastWriteTime;// 文件时间 61 file.Url = url; 62 //进行获取数据库名称 63 var strArr = fi.Name.Split(‘.‘); 64 if (strArr.Length > 0) 65 { 66 //分离其中的文件的名称 67 file.DataName = strArr[0].ToString(); 68 } 69 if (file != null) 70 { 71 dbFileNameList.Add(file); 72 } 73 } 74 } 75 #endregion 76 #region 5.进行获取备份文件的数据库名称的集合 77 List<string> dataNameList = new List<string>(); 78 foreach (var item in dbFileNameList) 79 { 80 if (!dataNameList.Contains(item.DataName)) 81 { 82 dataNameList.Add(item.DataName); 83 } 84 } 85 #endregion 86 #region 6.进行遍历数据库名称集合,获取到每个数据库备份的最新的文件路径 87 88 foreach (var dataName in dataNameList) 89 { 90 //第一步将每个数据库的备份找出来 91 List<DBNameAndTime> tempList = new List<DBNameAndTime>(); 92 foreach (var fileName in dbFileNameList) 93 { 94 if (dataName == fileName.DataName) 95 { 96 tempList.Add(fileName); 97 } 98 } 99 //第二步筛选出最新的文件 100 var newFile = tempList.OrderByDescending(a => a.FileTime).FirstOrDefault(); 101 102 //第三步将最新的文件的路径添加到要下载的集合中 103 if (newFile != null) 104 { 105 //进行返回下载的文件的URL的压缩包格式的文件 106 string downUrl = newFile.DownUrl; 107 displayUrlList.Add(downUrl); 108 } 109 } 110 #endregion 111 } 112 return displayUrlList; 113 } 114 115 //进行声明备份数据库的类 116 public class DBNameAndTime 117 { 118 private string fileName; 119 /// <summary> 120 /// 文件名称 121 /// </summary> 122 public string FileName { get { return fileName; } set { fileName = value; } } 123 124 private DateTime fileTime; 125 /// <summary> 126 /// 文件的最后修改时间 127 /// </summary> 128 public DateTime FileTime { get { return fileTime; } set { fileTime = value; } } 129 130 private string dataName; 131 /// <summary> 132 /// 数据库名称 133 /// </summary> 134 public string DataName { get { return dataName; } set { dataName = value; } } 135 136 private string url; 137 /// <summary> 138 /// 文件路径 139 /// </summary> 140 public string Url { get { return url; } set { url = value; } } 141 142 public string DownUrl { get { return _rootUrl + fileName; } } 143 } 144 } 145 }
应用WebServices进行开发应用程序来返回下载路径的集合
3.创建控制台应用程序进行远程下载通过获取WebServices 返回的List<string> 进行下载
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //通过代码进行建立SSL认证关系否则会出现未能为 SSL/TLS 安全通道建立信任关系. 6 ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; 7 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; }); 8 WebClient client = new WebClient(); 9 DbFileUrlProviderSvc.DbFileProviderSoapClient svcClient = new DbFileUrlProviderSvc.DbFileProviderSoapClient(); 10 DbFileUrlProviderSvc.ArrayOfString latstFileUrlArray = svcClient.GetDbFile(); 11 string receivePath = Properties.Settings.Default.LOCAL_PATH;//公司的云服务器保存下载文件的路径 12 try 13 { 14 // 对从svc取出的url循环下载获取最新的文件 15 if (receivePath != null) 16 { 17 if (latstFileUrlArray != null) 18 { 19 foreach (var downloadPath in latstFileUrlArray.ToList()) 20 { 21 //将下载的文件进行保存到指定的文件夹 22 if (downloadPath != null) 23 { 24 //将数据库备份的日志写入到记事本中去 25 using (StreamWriter sw = new StreamWriter(receivePath + "数据库下载的日志.txt", true)) 26 { 27 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "数据库备份下载开始:" + "下载的路径:" + downloadPath + "接收的路径:" + receivePath + "下载文件的名称:" + Path.GetFileName(downloadPath)); 28 } 29 //下载数据库备份文件 30 Console.WriteLine("数据库备份压缩包下载开始{0}!", DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss")); 31 client.DownloadFile(downloadPath, receivePath + Path.GetFileName(downloadPath)); 32 Console.WriteLine("恭喜你备份{0}文件时间{1}下载完成,进入本地{2}下面进行查看!", Path.GetFileName(downloadPath), DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss"), receivePath); 33 } 34 } 35 } 36 } 37 } 38 catch(Exception ex) 39 { 40 //将数据库备份的日志写入到记事本中去 41 using (StreamWriter sw = new StreamWriter(receivePath + "数据库下载的日志.txt", true)) 42 { 43 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "数据库备份下载中进行捕捉的异常:"+ex.Message); 44 } 45 } 46 47 } 48 49 }
创建控制台应用程序进行远程下载通过获取WebServices 返回的List<string>URL 集合进行下载
4.定期的进行删除数据库备份文件
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //获取其中的数据库的备份的路径 6 string strDirfile = Properties.Settings.Default.DB_FILE_PATH; 7 int keepFileCnt = int.Parse(Properties.Settings.Default.KEEP_FILE_CNT); 8 try 9 { 10 //获取该目录下的所有文件,筛选出最新的 现将所有的数据库的文件进行获取出来。 11 if (string.IsNullOrEmpty(strDirfile) || !Directory.Exists(strDirfile)) 12 { 13 Console.WriteLine("配置的文件的路径不正确请检查{0}" + strDirfile); 14 } 15 if (keepFileCnt <= 0) 16 { 17 Console.WriteLine("没有配置删除的天数"); 18 } 19 20 if (strDirfile != null) 21 { 22 if (Directory.Exists(strDirfile)) 23 { 24 string[] strDirs = Directory.GetDirectories(strDirfile); 25 string[] strFiles = Directory.GetFiles(strDirfile); 26 DBNameAndTime file = new DBNameAndTime(); 27 //进行获取根目录下面所有的数据库的文件的URL 28 if (strFiles!=null) 29 { 30 foreach (string strFile in strFiles) 31 { 32 if (strFile != null) 33 { 34 FileInfo fi = new FileInfo(strFile); 35 string[] strArr = fi.Name.Split(‘.‘); 36 file.DataName = fi.Name;//文件的名称也就是备份数据库的名称 37 file.FileTime = strArr[4];// 文件中备份的时间 38 file.Url = strFile; 39 DateTime dt1 =fi.LastWriteTime;//文件最后的写入的时间 40 //然后进行分离其中的数据库的备份的时间 41 if (strArr.Length > 0) 42 { 43 IFormatProvider provider = new CultureInfo("zh-CN"); 44 string tarStr = "yyyyMMddHHmmss"; 45 DateTime dt2 = DateTime.ParseExact(file.FileTime.ToString(), tarStr, provider); 46 TimeSpan ts = dt1 - dt2; 47 //进行日期的比较是不是3天前的如果是那么就进行删除 48 if (ts.TotalDays >= keepFileCnt) 49 { 50 //进行删除其中时间为3天的旧文件 51 if (strFile != null) 52 { 53 //进行根据文件中的创建的时间 54 File.Delete(strFile); 55 //将数据库备份的日志写入到记事本中去 56 using (StreamWriter sw = new StreamWriter(strDirfile + "数据库备份的删除日志.txt", true)) 57 { 58 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "数据库备份删除开始:" + "删除的路径:" + strDirfile); 59 } 60 Console.WriteLine("{0}数据库备份文件删除成功!", DateTime.Now); 61 } 62 else 63 { 64 Console.WriteLine("删除文件失败!"); 65 } 66 } 67 else 68 { 69 Console.WriteLine("其他的备份文件都是最新的没有3天前的备份!"); 70 } 71 } 72 } 73 } 74 } 75 76 //保存删除的根目录的文件夹 77 foreach (string strdir in strDirs) 78 { 79 Directory.Delete(strdir, true); 80 } 81 82 } 83 else 84 { 85 Console.WriteLine("此目录中只有根目录了!"); 86 } 87 } 88 else 89 { 90 Console.WriteLine("此目录不存在!"); 91 } 92 93 } 94 catch (Exception ex) 95 { 96 //将数据库备份的异常写入到记事本中 97 using (StreamWriter sw = new StreamWriter(strDirfile + "数据库备份的删除的日志.txt", true)) 98 { 99 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "备份文件都是最新的没有3天前的备份"); 100 } 101 } 102 } 103 } 104 //进行声明备份数据库的类 105 public class DBNameAndTime 106 { 107 private string fileName; 108 /// <summary> 109 /// 文件名称 110 /// </summary> 111 public string FileName { get { return fileName; } set { fileName = value; } } 112 113 private string fileTime; 114 /// <summary> 115 /// 文件的最后修改时间 116 /// </summary> 117 public string FileTime { get { return fileTime; } set { fileTime = value; } } 118 119 private string dataName; 120 /// <summary> 121 /// 数据库名称 122 /// </summary> 123 public string DataName { get { return dataName; } set { dataName = value; } } 124 125 private string url; 126 /// <summary> 127 /// 文件路径 128 /// </summary> 129 public string Url { get { return url; } set { url = value; } } 130 131 public string DownUrl { get { return fileName; } } 132 }
定期的进行删除数据库备份文件
5.当所用的程序开发完毕后那么就可以进行测试了,首先需要进行在任务计划程序中进行部署计划任务将.exe 程序添加其中,并进行设置确定的时间。
6.当所用的计划任务程序都进行部署完成后那么需要将webServices进行托管到IIS上。
7.当这些任务完成后那么就可以了下载数据库备份了。
---恢复内容结束--- 2016.11.17