前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Serverless 最佳实践之数据库的连接和查询

Serverless 最佳实践之数据库的连接和查询

作者头像
朱峰
发布2019-10-21 10:28:30
2K0
发布2019-10-21 10:28:30
举报
文章被收录于专栏:寂静小站寂静小站

Serverless 最佳实践的第二讲来了,本讲将帮你 Get 以下技巧:

  • 利用云函数的生命周期来管理数据库连接,降低连接数并提升性能
  • 使用 Knex 简化 Sql 拼接,并与 TypeScript 结合提升代码质量
  • 适时分库提升数据库性能、降低耦合和避免过高的连接数

1. 利用云函数的生命周期来管理数据库连接

在第一讲云函数的生命周期中,我们已经提到了在云函数 Mount 阶段创建数据库连接带来的两方面好处:

  1. 有效降低数据库连接数(每个请求创建一个连接 -> 每个实例创建一个连接)
  2. 性能优化(每个请求创建一个连接 -> 多个请求复用实例的连接)

我们再回顾一下示例代码:

代码语言:javascript
复制
import { Func } from '@faasjs/func'; // FaasJS 的云函数类import { Sql } from '@faasjs/sql'; // FaasJS 的 Sql 插件
// 初始化数据库对象const sql = new Sql();
// 返回云函数实例export default new Func({  plugins: [sql], // 插件管理,FaasJS 将自动管理插件的生命周期  async handler(){ // 业务代码    return await sql.query('SELECT * FROM users WHERE id = ?', [1]);  }});

FaasJS 的 Sql 插件支持 Mysql、PostgreSql 和 Sqlite 及支持这三类数据库协议的数据库,且已经内部封装了基于云函数生命周期机制的最佳实践,开发者只需直接使用即可。

2. 使用 Knex、TypeScript 结合提升开发效率和质量

Knex 是一个 SQL 语句生成插件,并且可以与 TypeScript 结合,大幅简化开发者对数据库的操作。

我们直接看代码示例:

代码语言:javascript
复制
// user.func.tsimport { Func } from '@faasjs/func'; // FaasJS 的云函数类import { Sql } from '@faasjs/sql'; // FaasJS 的 Sql 插件import knex from 'knex';
// 使用 TypeScript 来定义用户表的结构interface User {  id: number;  name: string;}
// 初始化数据库对象const sql = new Sql();
// 返回云函数实例export default new Func({  plugins: [sql], // 插件管理,FaasJS 将自动管理插件的生命周期  async handler(){ // 业务代码    const users = knex<User>({        client: sql.adapterType      }) // 告诉 Knex 返回的数据类型和数据库的类型      .from('users') // 告诉 Knex 表名      .connection(sql.adapter!.pool); // 复用 sql 插件自动维护的数据库连接        return await users.where({ id: 1 }); // Knex 形式的数据库查询  }});

上面的代码中有两个要点:

  1. Knex 支持使用 TypeScript 的 interface 作为返回数据类型
  2. sql 插件需要把连接池注入到 Knex 中以利用云函数的生命周期来管理连接

按上面的写法,云函数本身的业务代码是没问题了,但 Knex 还支持建表之类的操作,对于自动化测试是非常有用的,所以我们再深入看一下自动化测试脚本怎么写更好:

代码语言:javascript
复制
// __tests__/user.test.tsimport { FuncWarpper } from '@faasjs/test'; // FaasJS 对云函数的测试用封装import { Sql } from '@faasjs/sql'; // 引入 Sql 插件import knex from 'knex'; // 引入 knex 插件
// FaasJS 使用 Jest 作为测试框架describe('user', function () {  let func: FuncWarpper;
  beforeEach(async function () {    // 生成云函数    func = new FuncWarpper(require.resolve('../user.func') as string);        // 为了便于测试脚本中对数据库各种操作,我们把 sql 插件实例放个快捷方式在 func 对象上    func.sql = func.plugins[0] as Sql;        // 由于数据库连接是在 mount 阶段生成的,因此这里先 mount 一下    await func.mountedHandler();        // 建表    await knex({      client: func.sql.adapterType    })      .schema      .connection(func.sql.adapter!.pool)      .dropTableIfExists('users')      .createTable('users', function (t) {        t.integer('id').notNullable();        t.string('name').notNullable();      });  });
  test('should work', async function () {    // 插入假数据    await knex({        client: func.sql.adapterType      })      .from('users')      .connection(func.sql.adapter!.pool)      .insert({        id: 1,        name: 'hi'      });        // 调用云函数    const res = await func.handler();        // 检查返回结果是否符合预期    expect(res.length).toEqual(1);    expect(res[0].id).toEqual(1);    expect(res[0].name).toEqual('hi');  }); });

这里留一个小问题:当多个云函数都需要调用这个数据表时,如何封装比较好呢?(答案见后文)

3. 适时分库,降低耦合

随着业务增长,必然会遇到数据种类和数量越来越多的情况,如果大量的云函数都连接到一个数据库,必然会对该数据库造成较大的压力,所以建议在开发到一定程度时,提前进行分库操作,对数据和代码进行解耦。

FaasJS 的文件夹结构天然支持分库,假设我们把 users 表和 orders 分拆为两个数据库,则只需将它们分别放在两个不同的文件夹里,每个文件夹里独自配置各自的 faas.yaml 即可。

具体示例可以点击下方的“阅读原文”,查看我在 Github 上写的示例代码,示例代码中包括了以下最佳实践示例:

  • 基于 Knex 和 TypeScript 定义共用数据表
  • 基于文件夹来分库分业务
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 寂静小站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档