---恢復內容開始---
如何做到將客戶服務器數據庫的備份,下載到本地的雲服務上? 在開發這個程序中中途也遇到了一下問題,下面我將自己如何進解決的辦法寫出來供大家參考。
一.首先我需要進行描述一下問題:
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