侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

微信小程序云开发如何实现数据库自动备份实现

微信(小程序)  /  管理员 发布于 3年前   420

前言

数据是无价的,我们通常会把重要的业务数据存放在数据库中,并需要对数据库做定时的自动备份工作,防止数据异常丢失,造成无法挽回的损失。

小程序云开发提供了方便的云数据库供我们直接使用,云开发使用了腾讯云提供的云数据库,拥有完善的数据保障机制,无需担心数据丢失。但是,我们还是不可避免的会担心数据库中数据的安全,比如不小心删除了数据集合,写入了脏数据等。

还好,云开发控制台提供了数据集合的导出,导入功能,我们可以手动备份数据库。不过,总是手动备份数据库也太麻烦了点,所有重复的事情都应该让代码去解决,下面我们就说说怎么搞定云开发数据库自动备份。

通过查阅微信的文档,可以发现云开发提供了数据导出接口databaseMigrateExport

POST https://api.weixin.qq.com/tcb/databasemigrateexport?access_token=ACCESS_TOKEN

通过这个接口,结合云函数的定时触发功能,我们就可以做数据库定时自动备份了。梳理一下大致的流程:

  • 创建一个定时触发的云函数
  • 云函数调用接口,导出数据库备份文件
  • 将备份文件上传到云存储中以供使用

1. 获取 access_token

调用微信的接口需要 access_token,所以我们首先要获取 access_token。通过文档了解到使用 auth.getAccessToken 接口可以用小程序的 appid 和 secret 获取 access_token。

// 获取 access_tokenrequest.get(  `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`,  (err, res, body) => {    if (err) {      // 处理错误      return;    }    const data = JSON.parse(body);    // data.access_token  });

2. 创建数据库导出任务

获取 access_token 后,就可以使用 databaseMigrateExport 接口导出数据进行备份。

databaseMigrateExport 接口会创建一个数据库导出任务,并返回一个 job_id,这个 job_id 怎么用我们下面再说。显然数据库的数据导出并不是同步的,而是需要一定时间的,数据量越大导出所要花费的时间就越多,个人实测,2W 条记录,2M 大小,导出大概需要 3~5 S。

调用 databaseMigrateExport 接口需要传入环境 Id,存储文件路径,导出文件类型(1 为 JSON,2 为 CSV),以及一个 query 查询语句。

因为我们是做数据库备份,所以这里就导出 JSON 类型的数据,兼容性更好。需要备份的数据可以用 query 来约束,这里还是很灵活的,既可以是整个集合的数据,也可以是指定的部分数据,这里我们就使用 db.collection('data').get() 备份 data 集合的全部数据。同时我们使用当前时间作为文件名,方便以后使用时查找。

request.post(  `https://api.weixin.qq.com/tcb/databasemigrateexport?access_token=${accessToken}`,  {    body: JSON.stringify({      env,      file_path: `${date}.json`,      file_type: '1',      query: 'db.collection("data").get()'    })  },  (err, res, body) => {    if (err) {      // 处理错误      return;    }    const data = JSON.parse(body);    // data.job_id  });

3. 查询任务状态,获取文件地址

在创建号数据库导出任务后,我们会得到一个 job_id,如果导出集合比较大,就会花费较长时间,这时我们可以使用 databaseMigrateQueryInfo 接口查询数据库导出的进度。

当导出完成后,会返回一个 file_url,即可以下载数据库导出文件的临时链接。

request.post(  `https://api.weixin.qq.com/tcb/databasemigratequeryinfo?access_token=${accessToken}`,  {    body: JSON.stringify({      env,      job_id: jobId    })  },  (err, res, body) => {    if (err) {      reject(err);    }    const data = JSON.parse(body);    // data.file_url  });

获取到文件下载链接之后,我们可以将文件下载下来,存入到自己的云存储中,做备份使用。如果不需要长时间的保留备份,就可以不用下载文件,只需要将 job_id 存储起来,当需要恢复备份的时候,通过 job_id 查询到新的链接,下载数据恢复即可。

至于 job_id 存在哪,就看个人想法了,这里就选择存放在数据库里。

await db.collection('db_back_info').add({  data: {    date: new Date(),    jobId: job_id  }});

4. 函数定时触发器

云函数支持定时触发器,可以按照设定的时间自动执行。云开发的定时触发器采用的 Cron 表达式语法,最大精度可以做的秒级,详细的使用方法可以参考官方文档:定时触发器 | 微信开放文档

这里我们配置函数每天凌晨 2 点触发,这样就可以每天都对数据库进行备份。在云函数目录下新建 config.json文件,写入如下内容:

{ "triggers": [  {   "name": "dbTrigger",   "type": "timer",   "config": "0 0 2 * * * *"  } ]}

完整代码

最后,贴出可以在云函数中使用的完整代码,只需要创建一个定时触发的云函数,并设置好相关的环境变量即可使用

  • appid
  • secret
  • backupColl:需要备份的集合名称,如 ‘data'
  • backupInfoColl:存储备份信息的集合名称,如 ‘db_back_info'

注意,云函数的默认超时时间是 3 秒,创建备份函数时,建议将超时时间设定到最大值 20S,留有足够的时间查询任务结果。

/* eslint-disable */const request = require('request');const cloud = require('wx-server-sdk');// 环境变量const env = 'xxxx';cloud.init({  env});// 换取 access_tokenasync function getAccessToken(appid, secret) {  return new Promise((resolve, reject) => {    request.get(      `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`,      (err, res, body) => {        if (err) {          reject(err);          return;        }        resolve(JSON.parse(body));      }    );  });}// 创建导出任务async function createExportJob(accessToken, collection) {  const date = new Date().toISOString();  return new Promise((resolve, reject) => {    request.post(      `https://api.weixin.qq.com/tcb/databasemigrateexport?access_token=${accessToken}`,      {        body: JSON.stringify({          env,          file_path: `${date}.json`,          file_type: '1',          query: `db.collection("${collection}").get()`        })      },      (err, res, body) => {        if (err) {          reject(err);        }        resolve(JSON.parse(body));      }    );  });}// 查询导出任务状态async function waitJobFinished(accessToken, jobId) {  return new Promise((resolve, reject) => {    // 轮训任务状态    const timer = setInterval(() => {      request.post(        `https://api.weixin.qq.com/tcb/databasemigratequeryinfo?access_token=${accessToken}`,        {          body: JSON.stringify({            env,            job_id: jobId          })        },        (err, res, body) => {          if (err) {            reject(err);          }          const { status, file_url } = JSON.parse(body);          console.log('查询');          if (status === 'success') {            clearInterval(timer);            resolve(file_url);          }        }      );    }, 500);  });}exports.main = async (event, context) => {  // 从云函数环境变量中读取 appid 和 secret 以及数据集合  const { appid, secret, backupColl, backupInfoColl } = process.env;  const db = cloud.database();  try {    // 获取 access_token    const { errmsg, access_token } = await getAccessToken(appid, secret);    if (errmsg && errcode !== 0) {      throw new Error(`获取 access_token 失败:${errmsg}` || '获取 access_token 为空');    }    // 导出数据库    const { errmsg: jobErrMsg, errcode: jobErrCode, job_id } = await createExportJob(access_token, backupColl);    // 打印到日志中    console.log(job_id);    if (jobErrCode !== 0) {      throw new Error(`创建数据库备份任务失败:${jobErrMsg}`);    }    // 将任务数据存入数据库    const res = await db.collection('db_back_info').add({      data: {        date: new Date(),        jobId: job_id      }    });    // 等待任务完成    const fileUrl = await waitJobFinished(access_token, job_id);    console.log('导出成功', fileUrl);    // 存储到数据库    await db      .collection(backupInfoColl)      .doc(res._id)      .update({        data: {          fileUrl        }      });  } catch (e) {    throw new Error(`导出数据库异常:${e.message}`);  }};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:

  • 微信小程序云函数使用mysql数据库过程详解
  • python操作小程序云数据库实现简单的增删改查功能
  • 详解小程序云开发数据库
  • 微信小程序云开发修改云数据库中的数据方法
  • 微信小程序实现获取用户信息并存入数据库操作示例
  • 微信小程序云开发之数据库操作


  • 上一条:
    微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析
    下一条:
    微信小程序框架的页面布局代码
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 小程序开发之跳转微信直播示例api(0个评论)
    • 在uni_app中开发小程序之常用功能示例代码汇总(0个评论)
    • 小程序开发之多端框架:taro(0个评论)
    • 微信小程序前端使用七牛云官方SDK上传七牛云代码示例(0个评论)
    • 百度小程序审核未通过,真机审核存在点击返回键退出小程序...解决方式之一tabBar(0个评论)
    • 近期文章
    • 在laravel框架中的5个HTTP客户端技巧分享(0个评论)
    • 在go语言中使用FFmpeg库实现PCM音频文件编码为mp3格式文件流程步骤(0个评论)
    • gopacket免安装Pcap实现驱动层流量抓包流程步骤(0个评论)
    • 在laravel项目中实现密码强度验证功能推荐扩展包:password-strength(0个评论)
    • 在go语言中用filepath.Match()函数以通配符模式匹配字符串示例(0个评论)
    • Laravel Response Classes 响应类使用优化浅析(0个评论)
    • mysql中sql_mode的各模式浅析(0个评论)
    • 百度文心一言今天发布,个人第一批内测体验记录,不好别打我(0个评论)
    • 嘿加密世界让我们谈谈在共识中将中本聪主流化(0个评论)
    • 在go语言中寻找两个切片或数组中的相同元素/共同点/交集并集示例代码(0个评论)
    • 近期评论
    • 博主 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 @ xiaoB 你只管努力,剩下的叫给天意;天若有情天亦老,..
    • xiaoB 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 会不会春节放假后又阳一次?..
    • BUG4 在

      你翻墙过吗?国内使用vpn翻墙可能会被网警抓,你需了解的事中评论 不是吧?..
    • 博主 在

      go语言+beego框架中获取get,post请求的所有参数中评论 @ t1  直接在router.go文件中配就ok..
    • Jade 在

      如何在MySQL查询中获得当月记录中评论 Dear zongscan.com team, We can skyroc..
    • 2017-10
    • 2018-01
    • 2020-03
    • 2021-06
    • 2021-10
    • 2022-03
    • 2023-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客