操作场景
目前,腾讯云原生数据库 TDSQL-C 已支持 Serverless MySQL 版本,做到按实际使用的计算和存储量计费,按秒计量,按小时结算。Serverless Cloud Framework 的 CynosDB 组件也已经支持该类型数据库的创建。
本文以 Node.js 开发语言的函数,指导您快速创建 TDSQL-C Serverless MySQL 实例,并在云函数中进行调用。
操作步骤
操作步骤 | 操作说明 |
- | |
通过 Serverless Cloud Framework VPC 组件 创建 VPC 和 子网,支持云函数和数据库的网络打通和使用。 | |
通过 Serverless Cloud Framework Cynosdb 组件创建 MySQL 实例,为云函数项目提供数据库服务。 | |
通过 Serverless DB SDK 调用数据库,云函数支持直接调用 Serverless DB SDK,连接 PostgreSQL 数据库进行管理操作。 | |
通过 Serverless Cloud Framework 部署项目至云端,并通过云函数控制台进行测试。 | |
可通过 Serverless Cloud Framework 移除项目。 |
步骤1:配置环境变量
1. 在本地建立目录,用于存放代码及依赖模块。本文以
test-MySQL
文件夹为例。mkdir test-MySQL && cd test-MySQL
2. 由于目前 TDSQL-C Serverless 只支持
ap-beijing-3
,ap-guangzhou-4
,ap-shanghai-2
和 ap-nanjing-1
四个区域,所以这里还需要配置下,只需要在项目根目录下创建 .env
文件,然后配置 REGION
和 ZONE
两个环境变量:说明:
REGION:地域。表示资源所在的地域,每个地域包含一个或多个可用区。
ZONE:可用区。指腾讯云在同一地域内电力和网络互相独立的物理数据中心。目标是能够保证可用区之间故障相互隔离,不出现故障扩散,使得用户的业务持续在线服务。
# .envREGION=xxxZONE=xxx
步骤2:配置私有网络
1. 在
test-MySQL
目录下创建文件夹 VPC
。mkdir VPC && cd VPC
#serverless.ymlapp: mysql-appstage: devcomponent: vpc # (required) name of the component. In that case, it's vpc.name: mysql-app-vpc # (required) name of your vpc component instance.inputs:region: ${env:REGION}zone: ${env:ZONE}vpcName: serverless-mysqlsubnetName: serverless-mysql
步骤3:配置 Serverless DB
1. 在
test-MySQL
下创建文件夹 DB
。2. 在
DB
文件夹下新建 serverless.yml
文件,并输入以下内容,通过 Serverless Cloud Framework 组件完成云开发环境配置。
serverless.yml
示例内容如下(全量配置参考 产品文档):# serverless.ymlapp: mysql-appstage: devcomponent: cynosdbname: mysql-app-dbinputs:region: ${env:REGION}zone: ${env:ZONE}vpcConfig:vpcId: ${output:${stage}:${app}:mysql-app-vpc.vpcId}subnetId: ${output:${stage}:${app}:mysql-app-vpc.subnetId}
步骤4:编写业务代码与配置文件
1. 在
test-MySQL
下创建文件夹 src
,用于存放业务逻辑代码和相关依赖项。2. 在
src
文件夹下创建文件 index.js
,并输入如下示例代码。在函数中通过 SDK 连接数据库,并在其中完成 MySQL 数据库的调用。exports.main_handler = async (event, context, callback) => {var mysql = require('mysql2');var connection = mysql.createConnection({host : process.env.HOST,user : 'root',password : process.env.PASSWORD});connection.connect();connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {if (error) throw error;console.log('The solution is: ', results[0].solution);});connection.end();}
3. 安装所需依赖模块。
npm install mysql2@2.3.3
4. 完成业务代码编写和依赖安装后,创建
serverless.yml
文件,示例文件如下:app: mysql-appstage: devcomponent: scfname: mysql-app-scfinputs:src: ./functionName: ${name}region: ${env:REGION}runtime: Nodejs10.15timeout: 30vpcConfig:vpcId: ${output:${stage}:${app}:mysql-app-vpc.vpcId}subnetId: ${output:${stage}:${app}:mysql-app-vpc.subnetId}environment:variables:HOST: ${output:${stage}:${app}:mysql-app-db.connection.ip}PASSWORD: ${output:${stage}:${app}:mysql-app-db.adminPassword}
步骤5:快速部署
完成创建后,项目目录结构如下:
./test-MySQL├── vpc│ └── serverless.yml # vpc 配置文件├── db│ └── serverless.yml # db 配置文件├── src│ ├── serverless.yml # scf 组件配置文件│ ├── node_modules # 项目依赖文件│ └── index.js # 入口函数└── .env # 环境变量文件
1. 使用命令行在
test-MySQL
下,执行以下命令进行部署。scf deploy
返回结果如下所示,即为部署成功。
mysql-app-vpc:region: xxxzone: xxxvpcId: xxxx-xxx...mysql-app-db:dbMode: xxxxregion: xxxxzone: xxxx...mysql-app-scf:functionName: xxxxdescription: xxx...59s › test-MySQL › "deploy" ran for 3 apps successfully.
2. 部署成功后,您可通过 云函数控制台,查看并进行函数调试,测试成功如下图所示:


步骤6:移除项目(可选)
在
test-MySQL
目录下,执行以下命令可移除项目。scf remove
返回如下结果,即为成功移除。
serverless-cloud-framework4s › test-MySQL › Success
示例代码
Python
Python 可使用云函数环境已经内置的 pymysql 依赖包进行数据库连接。示例代码如下:
# -*- coding: utf8 -*-from os import getenvimport pymysqlfrom pymysql.err import OperationalErrormysql_conn = Nonedef __get_cursor():try:return mysql_conn.cursor()except OperationalError:mysql_conn.ping(reconnect=True)return mysql_conn.cursor()def main_handler(event, context):global mysql_connif not mysql_conn:mysql_conn = pymysql.connect(host = getenv('DB_HOST', '<YOUR DB HOST>'),user = getenv('DB_USER','<YOUR DB USER>'),password = getenv('DB_PASSWORD','<YOUR DB PASSWORD>'),db = getenv('DB_DATABASE','<YOUR DB DATABASE>'),port = int(getenv('DB_PORT','<YOUR DB PORT>')),charset = 'utf8mb4',autocommit = True)with __get_cursor() as cursor:cursor.execute('select * from employee')myresult = cursor.fetchall()print(myresult)for x in myresult:print(x)
Node.js
Node.js 支持使用连接池进行连接,连接池具备自动重连功能,可有效避免因云函数底层或者数据库释放连接造成的连接不可用情况。示例代码如下:
说明:
'use strict';const DB_HOST = process.env[`DB_HOST`]const DB_PORT = process.env[`DB_PORT`]const DB_DATABASE = process.env[`DB_DATABASE`]const DB_USER = process.env[`DB_USER`]const DB_PASSWORD = process.env[`DB_PASSWORD`]const promisePool = require('mysql2').createPool({host : DB_HOST,user : DB_USER,port : DB_PORT,password : DB_PASSWORD,database : DB_DATABASE,connectionLimit : 1}).promise();exports.main_handler = async (event, context, callback) => {let result = await promisePool.query('select * from employee');console.log(result);}
PHP
PHP 可使用 pdo_mysql 或 mysqli 依赖包进行数据连接。示例代码如下:
pdo_mysql
<?phpfunction handler($event, $context) {try{$pdo = new PDO('mysql:host= getenv("DB_HOST");dbname= getenv("DB_DATABASE"),getenv("DB_USER"),getenv("DB_PASSWORD")');$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);}catch(PDOException $e){echo '数据库连接失败: '.$e->getMessage();exit;}}
mysqli
<?phpfunction main_handler($event, $context) {$host = "";$username = "";$password = "";// 创建连接$conn = mysqli_connect($servername, $username, $password);// 检测连接if (!$conn) {die("Connection failed: " . mysqli_connect_error());}echo "连接成功";mysqli_close($conn);echo "断开连接";}?>
Java
1. 请参考 依赖安装,安装以下依赖。
<dependencies><dependency><groupId>com.tencentcloudapi</groupId><artifactId>scf-java-events</artifactId><version>0.0.2</version></dependency><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>3.2.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.11</version></dependency></dependencies>
2. 使用 Hikari 连接池进行连接,示例代码如下:
package example;import com.qcloud.scf.runtime.Context;import com.qcloud.services.scf.runtime.events.APIGatewayProxyRequestEvent;import com.qcloud.services.scf.runtime.events.APIGatewayProxyResponseEvent;import com.zaxxer.hikari.HikariConfig;import com.zaxxer.hikari.HikariDataSource;import javax.sql.DataSource;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.HashMap;import java.util.Map;public class Http {private DataSource dataSource;public Http() {HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://" + System.getenv("DB_HOST") + ":"+ System.getenv("DB_PORT") + "/" + System.getenv("DB_DATABASE"));config.setUsername(System.getenv("DB_USER"));config.setPassword(System.getenv("DB_PASSWORD"));config.setDriverClassName("com.mysql.jdbc.Driver");config.setMaximumPoolSize(1);dataSource = new HikariDataSource(config);}public String mainHandler(APIGatewayProxyRequestEvent requestEvent, Context context) {System.out.println("start main handler");System.out.println("requestEvent: " + requestEvent);System.out.println("context: " + context);try (Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement("SELECT * FROM employee")) {ResultSet rs = ps.executeQuery();while (rs.next()) {System.out.println(rs.getInt("id"));System.out.println(rs.getString("first_name"));System.out.println(rs.getString("last_name"));System.out.println(rs.getString("address"));System.out.println(rs.getString("city"));}} catch (SQLException e) {e.printStackTrace();}APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent = new APIGatewayProxyResponseEvent();apiGatewayProxyResponseEvent.setBody("API GW Test Success");apiGatewayProxyResponseEvent.setIsBase64Encoded(false);apiGatewayProxyResponseEvent.setStatusCode(200);Map<String, String> headers = new HashMap<>();headers.put("Content-Type", "text");headers.put("Access-Control-Allow-Origin", "*");apiGatewayProxyResponseEvent.setHeaders(headers);return apiGatewayProxyResponseEvent.toString();}}
SCF DB SDK for MySQL
为了方便使用,云函数团队将 Node.js 和 Python 连接池相关代码封装为 SCF DB SDK for MySQL,请参考 依赖安装 进行安装使用。通过该 SDK,您可以在云函数代码中连接 MySQL、TDSQL-C 或 TDSQL MySQL版 数据库,并实现对数据库的插入、查询等操作。
SCF DB SDK for MySQL 具备以下特点:
自动从环境变量初始化数据库客户端。
SDK 会在全局维护一个数据库长连接,并处理连接中断后的重连。
云函数团队会持续关注 issue,确保获得连接即可用,不需要关注数据库连接。
1. Node.js SDK
'use strict';const database = require('scf-nodejs-serverlessdb-sdk').database;exports.main_handler = async (event, context, callback) => {let pool = await database('TESTDB2').pool()pool.query('select * from coffee',(err,results)=>{console.log('db2 callback query result:',results)})// no need to release poolconsole.log('db2 query result:',result)}
说明:
2. Python SDK
from serverless_db_sdk import databasedef main_handler(event, context):print('Start Serverlsess DB SDK function')connection = database().connection(autocommit=False)cursor = connection.cursor()cursor.execute('SELECT * FROM name')myresult = cursor.fetchall()for x in myresult:print(x)