Red de conocimiento informático - Conocimiento del nombre de dominio - Cómo implementar una copia de seguridad automática de la base de datos en el desarrollo en la nube del mini programa WeChat

Cómo implementar una copia de seguridad automática de la base de datos en el desarrollo en la nube del mini programa WeChat

Prólogo

Los datos no tienen precio. Generalmente almacenamos datos comerciales importantes en la base de datos y necesitamos realizar copias de seguridad automáticas de la base de datos con regularidad para evitar pérdidas anormales de datos y pérdidas irreparables.

El mini programa de desarrollo en la nube proporciona una base de datos en la nube conveniente para que la usemos directamente. El desarrollo en la nube utiliza la base de datos en la nube proporcionada por Tencent Cloud, que tiene un mecanismo completo de protección de datos, por lo que no hay necesidad de preocuparse por los datos. pérdida. Sin embargo, todavía nos preocupamos inevitablemente por la seguridad de los datos en la base de datos, como eliminar accidentalmente los datos recopilados, escribir datos sucios, etc.

Afortunadamente, Cloud Development Console proporciona funciones de exportación e importación para colecciones de datos, por lo que podemos realizar una copia de seguridad manual de la base de datos. Sin embargo, hacer siempre una copia de seguridad manual de la base de datos es demasiado problemático y todas las cosas repetitivas deben dejarse en manos del código, así que hablemos sobre cómo solucionar el problema de la copia de seguridad automática de las bases de datos de desarrollo en la nube.

Al consultar la documentación de WeChat, puede encontrar que el desarrollo en la nube proporciona una base de datos de interfaz de exportación de datosMigrateExport

POST /tcb/databasemigrateexport?access_token=ACCESS_TOKEN

A través de esto interfaz, para resumir el proceso:

Cree una función en la nube y actívela regularmente

La función en la nube llama a esta interfaz para exportar el archivo de copia de seguridad de la base de datos

Cargue el archivo de copia de seguridad en almacenamiento en la nube Utilizado en

1. Obtener access_token

Llamar a la interfaz WeChat requiere un access_token. Primero necesitamos obtener el token de acceso. Según la documentación, podemos usar la interfaz auth.getAccessToken para obtener el token de acceso con el appid y el secreto del subprograma.

//Obtener access_token

request.get()

`/cgi-bin/token?grant_type=client_credentialamp;appid=${appid}amp; secret=${secret}`,

(err, res, body) =gt; {

if (err) {

// Manejar el error

retorno;

}

datos constantes = JSON.parse(cuerpo);

// datos.access_token

}

);

2. Crear exportación de base de datos Una vez que la tarea

obtiene el token de acceso, puede utilizar la interfaz de base de datosMigrateExport para exportar los datos. respaldo.

La interfaz de base de datosMigrateExport creará una tarea de exportación de base de datos y devolverá un job_id, que analizaremos a continuación. Obviamente, la exportación de datos de la base de datos no es sincrónica, pero lleva una cierta cantidad de tiempo. Cuanto mayor es la cantidad de datos exportados, más tiempo lleva. En las pruebas personales, con registros de 2W y un tamaño de 2M, la exportación demora entre 3 y 5 segundos. .

Llamar a la interfaz de base de datosMigrateExport requiere pasar el ID del entorno, la ruta para almacenar el archivo, el tipo de archivo de exportación (1 significa JSON, 2 significa CSV), el nombre del archivo (2 significa CSV, JSON es 1 , CSV es 2) y la declaración de consulta.

Dado que estamos haciendo una copia de seguridad de la base de datos, estamos exportando datos de tipo JSON aquí para una mejor compatibilidad.

Los datos de los que se va a realizar una copia de seguridad se pueden limitar mediante consulta. Esto es muy flexible. Pueden ser los datos de todo el conjunto de datos o una parte específica de los datos. para hacer una copia de seguridad de todos los datos del conjunto de datos. Al mismo tiempo, utilizamos la hora actual como nombre del archivo para que sea más fácil encontrarlo para uso futuro.

request.post(

`/tcb/databasemigrateexport?access_token=${accessToken}`,

{

cuerpo: JSON .stringify({

env ,

file_path: `${date}.json`,

file_type: '1',

consulta: 'db.collection("data").get()'

})

},

},

(err, res.body) =gt; {

if (err) {

// manejar el error

return;

}

const data = JSON.parse(body);

// data.job_id

}

);

p>

3. Consulta el estado de la tarea para obtener la dirección del archivo

Después de crear la tarea de exportación de la base de datos, obtendremos un job_id. Si la colección de exportación es grande, lo hará. Toma mucho tiempo, por lo que podemos usar la base de datosMigrateQueryInfo Interfaz para consultar el progreso de la exportación de la base de datos.

Cuando se complete la exportación, se devolverá file_url, que es un enlace temporal para descargar el archivo de exportación de la base de datos.

request.post( `/tcb/databasemigratequeryinfo?access_token=${accessToken}`,

{

cuerpo: JSON.stringify({

env,

job_id: jobId

})

},

(err, res, body) =gt ; {

si (err) {

rechazar (err

}

datos constantes = JSON.parse (cuerpo) ;

// data.file_url

}

);

Después de obtener el enlace de descarga del archivo, podemos descargar el archivo y Guárdelo en su propio almacenamiento en la nube para realizar copias de seguridad. Si no es necesario guardar la copia de seguridad durante mucho tiempo, no es necesario descargar el archivo, simplemente almacene el job_id. Cuando sea necesario restaurar la copia de seguridad, se puede encontrar el nuevo enlace a través de job_id y los datos. descargado para restauración.

En cuanto a dónde almacenar job_id, depende del individuo decidir, aquí se almacena en la base de datos.

await db.collection('db_back_info').add({

datos: {

fecha: nueva fecha(),

jobId: job_id

}

});

4. Función de activación de tiempo

El soporte de la función de nube se puede configurar en un conjunto tiempo Activadores programados para ejecución automática.

Los activadores de tiempo desarrollados en la nube utilizan la sintaxis de expresión Cron y la precisión máxima puede estar en el segundo nivel. Para un uso detallado, consulte la documentación oficial: Timing Trigger | la función como Triggers todos los días a las 2 am para hacer una copia de seguridad de la base de datos todos los días. Cree un nuevo archivo config.json en el directorio de funciones de la nube y escriba el siguiente contenido:

{

"triggers": [

{

p>

"nombre": "dbTrigger",

"tipo": "temporizador",

"config": " 0 0 2 * * * * "

}

]

}

Código completo

Finalmente, publica el código completo que se puede utilizar en la nube. funciones, simplemente cree una función de nube activada por temporizador y configure las variables de entorno relevantes para usar

appid

secret

backupColl: el nombre de la colección que se respaldado, por ejemplo "datos"

. Por ejemplo, "datos"

backupInfoColl: el nombre de la colección que almacena información de respaldo, por ejemplo, "db_back_info"

Tenga en cuenta que el tiempo de espera predeterminado de las funciones de la nube es de 3 segundos. y se recomienda establecer el tiempo de espera. El límite de tiempo máximo es 20 segundos para permitir tiempo suficiente para consultar los resultados de la tarea.

/* eslint-disable */

const request = require('solicitud');

const cloud = require('wx-server-sdk' );

//Variables de entorno

const env = 'xxxx';

cloud.init({

env

});

//Exchange access_token

función asíncrona getAccessToken(appid, secret) {

return new Promise((resolver, rechazar) =gt; {

request.get(

`/cgi-bin/token?grant_type=client_credentialamp;appid=${appid}amp;secret=${secret}`,

(err, res, cuerpo) =gt; {

if (err) {

rechazar

return; ;

}

resolver( JSON.parse(cuerpo));

}

);

});

});

}

// Crear tarea de exportación

función asíncrona createExportJob(accessToken, collection) {

const date = new Date().toISOString();

return new Promise((resolver, rechazar) =gt; {

request.post(

`/tcb/databasemigrateexport?access_token=${accessToken}`,

{

cuerpo: JSON.stringify({

env ,

file_path: `${date}.json`,

file_type: '1',

consulta: `db.collection("${collection }").get()`

})

},

(err, res, cuerpo) =gt; {

if (err ) {

rechazar(err

}

resolver(JSON.parse(cuerpo));

}

);

});

});

}

// Consultar trabajo de exportación. Estado

función asíncrona waitJobFinished(accessToken, jobId) {

return new Promise((resolve, rechazar) =gt; {

// Estado de la tarea de rotación

temporizador constante = setInterval(

() =gt; {

request.post(

`/tcb/databasemigratequeryinfo?access_token=${accessToken}`,

{

body.JSON.stringify({

env,

job_id: jobId

})

},

(err, res, cuerpo) =gt; {

if (err) {

rechazar

}

const { estado, file_url } = JSON.parse(body);

console.log('Consulta');

if (status === 'éxito'); ) {

clearInterval( temporizador

resolver(file_url

}

}

) ;

}, 500);

});

}

exportaciones.main = async (evento, contexto) = gt ; {

// Leer appid, secreto y recopilación de datos de las variables de entorno de funciones de la nube

const { appid, secret, backupColl, backupInfoColl } = process.env;

const db = cloud.database();

prueba {

// obtiene access_token

const { errmsg, access_token } = espera getAccessToken( appid, secret);

if (errmsg amp; errcode !== 0) {

throw new Error(`Error al obtener access_token: ${errmsg}` || 'Obtener access_token es null');

}

// Exportar la base de datos

const { errmsg: jobErrMsg, errcode: jobErrCode! código de error: jobErrCode, job_id } = await createExportJob(access_token, backupColl);

// Imprimir en el registro

console.log(job_id); jobErrCode ! == 0) {

throw new Error(`Error al crear el trabajo de copia de seguridad de la base de datos: ${jobErrMsg}`);

}

// Almacenar datos del trabajo en la base de datos

const res = await db.collection('db_back_info' ).add(

{

datos: {

fecha: nueva fecha(),

jobId: job_id

}

})

});

// Espera a que se complete la tarea

const fileUrl = await waitJobFinished(access_token, job_id);

console .log('Exportación exitosa', fileUrl);

// Almacenar en la base de datos

await db

.collection( backupInfoColl)

.doc(res._id)

.update({

datos: {

fileUrl

}

});

} catch (e) {

throw new Error(`Exportar excepción de base de datos: ${e.message}`); >

}

}

};