本文属于个人原创作品、个人总结,谢绝转载、抄袭。如果您有疑问或者希望沟通交流,可以联系QQ:865562060。

一、简述

现阶段服务器、数据库上云的选择越来越多,但不是说服务器和数据库上云管理之后就可以安心睡觉了。做好云服务器和云数据库的备份管理也尤为重要。

最近用C#做阿里云数据库RDS的自动备份,感觉受到了很深的歧视。因为.Net模块里阿里云提供的demo是Java的,.Net SDK文档里的调用示例居然也是Java的。真是不让人省心的调用,经过几个小时的努力总算是摸索着dll弄好了。

我这里实现的思路是这样的:云数据库RDS我们是设置的云上保存7天的备份,每隔一天全量备份、隔一天增量备份,这些备份都有外链和内链支持下载(外网连接阿里云下载使用外链,但速度较慢;阿里云内网下载使用内链,速度非常快)。我要做一个定时运行的程序(我选择控制台应用程序,并在一台windows服务器上添加任务计划,定时运行这个控制台应用程序),自动下载云数据库备份的文件,并转储到指定地点。这里我转储两个地方,一个是公司磁盘(使用外链),另外一个是阿里云对象存储服务OSS(使用内链)。这样即使RDS和OSS都崩了,我本地也还有备份(虽然完全不可能出现这种情况)。

二、代码实现

1、创建控制台应用程序AliyunRDS(可以根据业务选择不同的程序),添加以下三个服务引用:aliyun-net-sdk-Core、aliyun-net-sdk-rds、Aliyun.OSS。

下载地址:https://develop.aliyun.com/tools/sdk?spm=a2c4g.11186623.2.10.7eea5234QGc6PP#/dotnet

主要下载以下三个:

2、 Program.cs中引用

using Aliyun.Acs.Rds;
using Aliyun.Acs.Rds.Model.V20140815;
using Aliyun.Acs.Rds.Transform.V20140815;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Http;
using Aliyun.OSS;
using Aliyun.OSS.Common;

3、主要代码实现

namespace AliyunRDS
{class Program{static void Main(string[] args){// 创建DefaultAcsClient实例并初始化DefaultProfile profile = DefaultProfile.GetProfile(ConfigurationManager.AppSettings["RegionID"],// 您的可用区IDConfigurationManager.AppSettings["AccessKey_ID"],// 您的AccessKey IDConfigurationManager.AppSettings["AccessKey_Secret"]);// 您的AccessKey SecretIAcsClient client = new DefaultAcsClient(profile);// 创建API请求并设置参数CommonRequest request = new CommonRequest();request.Method = MethodType.POST;request.Domain = "rds.aliyuncs.com";request.Version = "2014-08-15";request.Action = "DescribeBackups";//查询RDS实例的日志备份文件,包括文件的下载链接。request.AddQueryParameters("DBInstanceId", ConfigurationManager.AppSettings["DBInstanceId"]);//实例IDrequest.AddQueryParameters("BackupStatus", "Success");//实例IDrequest.AddQueryParameters("StartTime", DateTime.Now.AddDays(-7).ToString("yyyy-MM-dd") + "T12:00Z");//查询开始时间。格式:yyyy-MM-ddTHH:mmZ,例如2018-10-31T08:40Zrequest.AddQueryParameters("EndTime", DateTime.Now.ToString("yyyy-MM-dd") + "T12:00Z");//查询结束时间。格式:yyyy-MM-ddTHH:mmZ,例如2018-10-31T08:40Z 必须晚于查询开始时间。request.AddQueryParameters("PageSize", "30");//每页最多显示的日志文件个数。取值:30,50,100默认值:30request.AddQueryParameters("PageNumber", "1");//页码。大于0且不超过Integer的最大值。默认值:1。// 发起请求并处理应答或异常CommonResponse response = new CommonResponse();try{response = client.GetCommonResponse(request);Result model = JsonConvert.DeserializeObject<Result>(response.Data);if (model != null){List<DataBaseBackupFiles> list = model.Items.Backup;if (list.Count > 0){//阿里云接口返回的数据库备份文件为按时间倒序排序。我们每天执行就取第一条下载LogHelper.WriteProgramLog(DateTime.Now.ToString() + " 备份文件内网下载地址为:" + list[0].BackupIntranetDownloadURL);//1、下载、设置参数 HttpWebRequest requestFile = WebRequest.Create(list[0].BackupIntranetDownloadURL) as HttpWebRequest;//发送请求并获取相应回应数据 HttpWebResponse responseFile = requestFile.GetResponse() as HttpWebResponse;//直到requestFile.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = responseFile.GetResponseStream();//2、上传文件目录string uploadPath = ConfigurationManager.AppSettings["uploadPath"];if (!Directory.Exists(uploadPath)){Directory.CreateDirectory(uploadPath);}string[] strArray = list[0].BackupIntranetDownloadURL.Split(new string[] { "?" }, StringSplitOptions.RemoveEmptyEntries);string fileName = "";if (strArray.Length > 0){string[] files = strArray[0].Split('/');fileName = files[files.Length - 1];}elsefileName = DateTime.Now.ToString("yyyyMMddHHssmm") + new Random().Next(10000) + ".zip";string filePath = uploadPath + "\\" + fileName;//3、创建写入流 数据库备份文件可能非常大 所以这里使用分块下载FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);byte[] bytes = new byte[1024 * 512];int readCount = 0;while (true){readCount = responseStream.Read(bytes, 0, bytes.Length);if (readCount <= 0)break;fs.Write(bytes, 0, readCount);fs.Flush();}fs.Close();responseStream.Close();responseFile.Close();string sResult = PutObject(ConfigurationManager.AppSettings["bucketName"], fileName, filePath);if (!string.IsNullOrEmpty(sResult)) //Put Object请求处理成功后,OSS会将收到文件的MD5值放在返回结果的ETag中。用户可以根据ETag检验上传的文件与本地的是否一致。使用下面的方法GetMD5HashFromFile(),这里未做检验。{LogHelper.WriteProgramLog(DateTime.Now.ToString() + " 文件上传文件到OSS成功,删除本地文件!");if (File.Exists(filePath))File.Delete(filePath);LogHelper.WriteProgramLog(DateTime.Now.ToString() + " 备份完成!");}}elseLogHelper.WriteProgramLog(DateTime.Now.ToString() + " 查询到的备份文件列表为空!");}elseConsole.WriteLine(DateTime.Now.ToString() + " 发生错误!");}catch (Exception ex){LogHelper.WriteProgramLog(DateTime.Now.ToString() + " 发生错误:" + ex.Message);throw ex;}}/// <summary>/// 获取随机字符串/// </summary>/// <param name="length">长度</param>/// <param name="useNum">是否使用数字</param>/// <param name="useLow">是否使用小写字母</param>/// <param name="useUpp">是否使用大写字母</param>/// <param name="useSpe">是否使用特殊字符</param>/// <param name="custom">固定字符串</param>/// <returns></returns>public static string GetRandomString(int length, bool useNum, bool useLow, bool useUpp, bool useSpe, string custom){byte[] b = new byte[4];new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);Random r = new Random(BitConverter.ToInt32(b, 0));string s = null, str = custom;if (useNum == true) { str += "0123456789"; }if (useLow == true) { str += "abcdefghijklmnopqrstuvwxyz"; }if (useUpp == true) { str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }if (useSpe == true) { str += "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; }for (int i = 0; i < length; i++){s += str.Substring(r.Next(0, str.Length - 1), 1);}return s;}/// <summary>/// 上传本地的文件到指定的OSS的存储空间/// </summary>/// <param name="bucketName">指定的存储空间名称</param>/// <param name="key">文件的在OSS上保存的名称</param>/// <param name="fileToUpload">指定上传文件的本地完整路径</param>public static string PutObject(string bucketName, string key, string fileToUpload){try{ClientConfiguration ossConfig = new ClientConfiguration();OssClient ossClient = new OssClient(ConfigurationManager.AppSettings["endpoint"],ConfigurationManager.AppSettings["OSSaccessKeyId"],ConfigurationManager.AppSettings["OSSaccessKeySecret"],ossConfig);var result = ossClient.PutObject(bucketName, key, fileToUpload);return result.ETag;}catch (Exception ex){LogHelper.WriteProgramLog(DateTime.Now.ToString() + " 文件上传OSS失败!");LogHelper.WriteProgramLog(DateTime.Now.ToString() + ex.Message);throw ex;}}/// <summary>/// 获取文件的MD5码/// </summary>/// <param name="fileName">传入的文件名(含路径及后缀名)</param>/// <returns></returns>public static string GetMD5HashFromFile(string fileName){try{FileStream file = new FileStream(fileName, System.IO.FileMode.Open);MD5 md5 = new MD5CryptoServiceProvider();byte[] retVal = md5.ComputeHash(file);file.Close();StringBuilder sb = new StringBuilder();for (int i = 0; i < retVal.Length; i++){sb.Append(retVal[i].ToString("x2"));}return sb.ToString();}catch (Exception ex){LogHelper.WriteProgramLog(DateTime.Now.ToString() + " 获取文件的MD5码失败!");throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);}}}
}

三、实现效果

C#实现自动下载阿里云数据库RDS,附转储阿里云OSS服务器相关推荐

  1. 阿里云服务(四)—云数据库RDS

    七.云数据库RDS 1.云数据库RDS的概念   1.1 传统数据库和云数据库     传统数据库搭建过程     阿里云RDS       阿里云关系型数据库(Relational Database ...

  2. 自建数据库与云数据库RDS性能比较

    很多人对数据库是什么不是很清楚,那么数据库到底是什么呢?传统数据库是依照某种数据模型组织起来并存放二级存储器中的数据集合.这种数据集合具有如下特点:尽可能不重复,以最优方式为某个特定组织的多种应用服务 ...

  3. 云原生 - 自建数据库与云数据库RDS性能优势分析,值不值得购买?

    很多人对数据库是什么不是很清楚,那么数据库到底是什么呢?传统数据库是依照某种数据模型组织起来并存放二级存储器中的数据集合.这种数据集合具有如下特点:尽可能不重复,以最优方式为某个特定组织的多种应用服务 ...

  4. 自建数据库与云数据库RDS性能优势与优缺点对比

    很多人对数据库是什么不是很清楚,那么数据库到底是什么呢?传统数据库是依照某种数据模型组织起来并存放二级存储器中的数据集合.这种数据集合具有如下特点:尽可能不重复,以最优方式为某个特定组织的多种应用服务 ...

  5. 自建数据库与云数据库RDS具体内容的优缺点

    很多人对数据库是什么不是很清楚,那么数据库到底是什么呢?传统数据库是依照某种数据模型组织起来并存放二级存储器中的数据集合.这种数据集合具有如下特点:尽可能不重复,以最优方式为某个特定组织的多种应用服务 ...

  6. 云数据库RDS基础版的优势及适用场景

    云栖号快速入门:[点击查看更多云产品快速入门] 不知道怎么入门?这里分分钟解决新手入门等基础问题,可快速完成产品配置操作! 阿里云的产品系列包括基础版.高可用版.集群版.三节点企业版,本文介绍基础版的 ...

  7. 【数据库】云数据库rds是什么意思?有什么优势?

    云数据库rds是什么意思?有什么优势?这两个问题是很多运维人员都想了解的问题,因为大多运维人员思想还停留在自建数据库这种意识上,并没有真正地了解到云数据库的优势,今天跟小编小编一起来简单了解一下. 云 ...

  8. 阿里云云计算ACP学习(五)---云数据库RDS

    云数据库RDS 1.RDS概述 阿里云关系型数据库(Relational Database Service,简称RDS)是一种稳定可靠.可弹性伸缩的在线数据库服务.基于阿里云分布式文件系统和SSD盘高 ...

  9. oracle rds 运维服务_从运维的角度分析使用阿里云数据库RDS的必要性–你不应该在阿里云上使用自建的MySQL/SQL Server/Oracle/PostgreSQL数据库...

    开宗明义,你不应该在阿里云上使用自建的MySQL or SQL Server数据库,对了,还有Oracle or PostgreSQL数据库. 云数据库 RDS(Relational Database ...

最新文章

  1. 赠书 | 详解 4 种爬虫技术
  2. 测试php性能和mysql数据库性能的工具_和找出瓶颈的方法_php面试基础题
  3. Jquery UI dialog 详解 (中文)
  4. python简单代码input-【python系统学习05】input函数——实现人机交互
  5. Android Support 包里到底有什么
  6. Visual Question Answering概述
  7. 《编程题》找出数组中出现次数超过一半的数(时间复杂度O(n),空间复杂度为O(1))
  8. stackexchange_通过Spring Social发推StackExchange问​​题
  9. 英特尔中国祝贺高亭宇夺冠:至强CPU提供更精准训练支持
  10. 3月19日发布!vivo X27配置揭晓:搭载骁龙710处理器
  11. 1.4通过时间的方向传播
  12. SQL CASE 的用法
  13. Vue中引入css文件
  14. ❤️六万字《Spring框架从入门到精通》(建议收藏)❤️
  15. 苹果 macOS 11 Big Sur初体验, 升还是不升?
  16. wincc几个常用c语言编程软件,WINCC几个常用C语言编程
  17. hp打印机装不上服务器系统,winxp系统无法安装HP打印机驱动程序如何解决
  18. 京东员工p级别分几级_一文揭秘字节跳动、华为、京东的薪资职级
  19. python学习14:字典和集合
  20. python 的 int() 函数

热门文章

  1. 小D课堂-jekins-02
  2. 【Python】音乐下载器(for QQ music)
  3. matlab 三相桥式全控整流电路
  4. 对“卸磨杀驴”的理解
  5. js打印和vue打印
  6. 通过身份证号获取出生日期和性别
  7. python 给定日期 返回属于当年第几周
  8. python fontsize_python – Matplotlib图例fontsize
  9. 处理QQ五笔(2.3.622.400)不能保存中文状态使用英文标点的问题
  10. 2万元小投资冷门暴利行业有哪些?投资什么利润大?