访问RDS MySQL最佳实践

更新时间:2025-03-20 10:42:55

函数计算中,不同的执行环境实例之间的状态是不共享的,通过数据库可以将结构化的数据持久化以实现状态共享。通过函数计算访问云上数据库,您可以进行数据查询和数据插入等操作。本文以Python函数为例,介绍如何同VPC或跨VPC跨地域访问云数据库 RDS MySQL 版

前提条件

操作步骤

步骤一:设置数据库白名单

场景一:访问同VPC内的RDS数据库
场景二:跨VPC或跨地域访问RDS数据库

如果您选择访问同VPC内数据库的场景,请确保数据库实例与函数处于同一地域。建议您在函数计算支持的可用区创建数据库实例。更多信息,请参见函数计算支持的可用区。如果您的数据库实例不在函数计算支持的可用区内,可以通过在您的VPC环境中创建一个与函数计算相同可用区的vSwitch,并在函数的VPC配置中设置此vSwitch ID。由于同一VPC内不同vSwitch之间私网互通,因此函数计算可以通过该vSwitch访问在其他可用区的VPC内的资源。具体步骤,请参见遇到vSwitch is in unsupported zone的错误怎么办?

  1. 登录函数计算控制台创建Python Web函数,为函数开通VPC访问能力,并配置目标VPC资源。

    说明

    请确保为函数配置的VPC与数据库实例绑定的VPC相同。

    image

  2. 在函数详情页,依次选择配置 > 网络,然后在网络页面获取函数配置中的交换机网段。

    image

  3. 将上一步获取的函数配置中交换机的网段添加到数据库访问白名单。

    重要

    请使用设置IP地址白名单方式授权函数访问数据库,请勿使用安全组方式。否则,可能导致函数偶尔连接不上数据库的情况,影响业务正常运行。

    1. 访问RDS实例列表,在上方选择地域,然后单击目标实例ID。

    2. 在左侧导航栏,单击白名单与安全组

      白名单设置页面,可查看当前的IP白名单模式。

      说明

      较早创建的实例可能采用高安全模式。新创建的实例都采用通用白名单模式。

    3. 单击default分组右侧的修改,在弹出的修改白名单分组对话框中,将步骤2获取的交换机IPv4网段配置在白名单中,然后单击确定

      image

    完成配置后,函数可以通过数据库内网地址访问RDS数据库。

不同VPC和不同地域之间属于完全的逻辑隔离,常规情况下不能跨VPC和跨地域访问数据库。如果需要跨VPC或跨地域访问数据库,可以通过为函数配置固定公网IP的方式,此时系统会在函数绑定的专有网络VPC内创建公网NAT网关,通过公网网关即可实现通过公网IP访问数据库。

  1. 登录函数计算控制台,在左侧导航栏,选择函数,选择地域,然后根据界面提示创建函数

  2. 在函数详情页,依次选择配置 > 网络,在网络面板,为函数配置固定公网IP,然后单击部署

    image

  3. 在弹出的固定公网IP配置对话框,勾选提示框,然后单击确定。配置完成后,将参数允许函数默认网卡访问公网设置为,使配置的固定公网IP生效。

  4. 在函数详情页,依次选择配置 > 网络,然后在网络页面获取函数配置的固定公网IP地址。

    image

  5. 将上一步获取的函数固定公网IP地址添加到数据库访问白名单。

    重要

    请使用设置IP地址白名单方式授权函数访问数据库,请勿使用安全组方式。否则,可能导致函数偶尔连接不上数据库的情况,影响业务正常运行。

    1. 访问RDS实例列表,在上方选择地域,然后单击目标实例ID。

    2. 在左侧导航栏,单击白名单与安全组

      白名单设置页面,可查看当前的IP白名单模式。

      说明

      较早创建的实例可能采用高安全模式。新创建的实例都采用通用白名单模式。

    3. 单击default分组右侧的修改,在弹出的修改白名单分组对话框中,将步骤2获取的交换机IPv4网段配置在白名单中,然后单击确定

      image

    完成配置后,函数可以通过数据库公网地址访问RDS数据库。

步骤二:在函数中访问RDS

  1. 登录函数计算控制台,在函数列表找到目标函数,在函数详情页,单击代码页签,在代码编辑器编写如下示例代码。

    from flask import Flask, jsonify
    import pymysql  
    import os
    import logging
    
    app = Flask(__name__)
    
    @app.route('/', defaults={'path': ''})
    @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
    def hello_world(path):
        # 获取RDS的连接信息,通常这些信息可以通过环境变量或者密钥管理服务(如KMS)获取
        db_host = os.environ['MYSQL_HOST']
        db_port = int(os.environ['MYSQL_PORT'])
        db_user = os.environ['MYSQL_USER']
        db_password = os.environ['MYSQL_PASSWORD']
        db_name = os.environ['MYSQL_DBNAME']
    
        # 创建数据库连接
        connection = pymysql.connect(host=db_host,
                                     port=db_port,
                                     user=db_user,
                                     password=db_password,
                                     db=db_name)
    
        try:
            with connection.cursor() as cursor:
                # 查询user表的所有记录
                sql = "SELECT * FROM users"
                cursor.execute(sql)
                result = cursor.fetchall()
                # 将查询结果转换为字典列表
                users = []
                for row in result:
                    user = {
                        'id': row[0],
                        'username': row[1],
                        'email': row[2],
                        'password_hash': row[3],
                        'created_at':  row[4].strftime('%Y-%m-%d %H:%M:%S'),
                        'updated_at': row[5].strftime('%Y-%m-%d %H:%M:%S')
                    }
                    users.append(user)
                        
                if users:
                    # 返回所有用户的 JSON 响应
                    return jsonify(users), 200
                else:
                    # 如果没有找到用户,返回 404 错误
                    return jsonify({'error': 'No users found'}), 404
    
        except Exception as e:
            logging.error(f"Error occurred during database operation: {e}")
      
        finally:
            # 关闭数据库连接
            connection.close()
    
    if __name__ == '__main__':
            app.run(host='0.0.0.0',port=9000)
    
  2. 在函数详情页,依次选择配置 > 环境变量,单击编辑,在环境变量面板配置以下环境变量。

    环境变量名称

    环境变量值

    说明

    环境变量名称

    环境变量值

    说明

    MYSQL_HOST

    rm-bp19u8e76ae****.mysql.rds.aliyuncs.com

    数据库实例的访问地址。

    • 如果您选择VPC内的RDS数据库的场景,请将此环境变量值设置为数据库的内网地址。

    • 如果您选择VPC或跨地域访问RDS数据库的场景,请将此环境变量值设置为数据库的外网地址。

    RDS实例列表,单击目标RDS实例ID,然后在左侧导航栏,选择数据库连接,在数据库连接页面获取数据库的内网地址或外网地址。

    MYSQL_DBNAME

    db_test

    RDS实例中创建的数据库名称。

    MYSQL_PASSWORD

    *****

    数据库密码。

    MYSQL_PORT

    3306

    数据库实例的私网端口。

    MYSQL_USER

    dms_user_****

    RDS实例中创建的账号名称。

  3. 在函数详情页,选择代码页签,单击测试函数,执行成功后查看返回结果,已成功完成查询表格操作。

    image

更多信息

  • 更多访问RDS MySQL数据库的示例,请参见函数计算Python访问MySQL数据库

  • 如果您的数据库访问失败,需要根据问题现象进行排查,详情请参见数据库访问失败的常见原因

  • RDS支持MySQL、SQL Server、PostgreSQLMariaDB引擎。更多信息,请参见云数据库RDS简介

  • 如果您希望使用Serverless Devs命令行工具创建函数并访问RDS MySQL数据库,请参见以下步骤。

    单击此处查看Serverless Devs操作步骤

    1. 安装Serverless DevsDocker,并添加密钥信息。具体操作,请参见快速入门

    2. 创建代码目录mycode,准备s.yaml文件和代码文件app.pys.yaml文件示例如下,示例代码请参见步骤二:在函数中访问RDS提供的示例代码。

      以下s.yaml示例适用于同VPC内访问RDS数据库的场景,如果需要跨VPC跨地域访问数据库,请参见场景二:跨VPC或跨地域访问RDS数据库

      # ------------------------------------
      #   官方手册: https://manual.serverless-devs.com/user-guide/aliyun/#fc3
      #   常见小贴士: https://manual.serverless-devs.com/user-guide/tips/
      #   有问题快来钉钉群问一下吧:33947367
      # ------------------------------------
      edition: 3.0.0
      name: hello-world-app
      access: "default"
      
      vars: # 全局变量
        region: "cn-hangzhou"  # 如果您选择同VPC内访问RDS数据库的场景,请确保函数部署在与RDS数据库相同的地域
      
      resources:
        hello_world:
          component: fc3 
          actions:       
            pre-${regex('deploy|local')}: 
              - component: fc3 build 
          props:
            region: ${vars.region}              
            functionName: "start-python-0t1m"
            runtime: custom.debian10
            description: 'hello world by serverless devs'
            timeout: 10
            memorySize: 512
            cpu: 0.5
            diskSize: 512
            code: ./code
            customRuntimeConfig:
              port: 9000
              command:
                - python3
                - app.py
            internetAccess: true
            vpcConfig:
             vpcId: vpc-bp1dxqii29fpkc8pw**** # 数据库实例所在的VPC ID
             securityGroupId: sg-bp12ly2ie92ixrfc**** # 安全组ID
             vSwitchIds: 
              - vsw-bp1ty76ijntee9z83**** # 请确保该vSwitch对应的网段已配置到数据库实例访问白名单中
            environmentVariables:
              PYTHONPATH: /code/python
              PATH: /code/python/bin:/var/fc/lang/python3.10/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin
              MYSQL_HOST: rm-bp1j1y7657640z5****.mysql.rds.aliyuncs.com  # 数据库实例的私网地址
              MYSQL_PORT: "3306"  # 数据库实例的私网端口
              MYSQL_USER: dms_user_****  # 数据库实例中创建的数据库
              MYSQL_PASSWORD: ****   # 数据库实例的密码
              MYSQL_DBNAME: db_test  # 数据库实例中创建的数据库名称
    3. 执行以下命令构建项目。

      sudo s build --use-docker
    4. 执行以下命令部署项目。

      sudo s deploy -y
    5. 执行以下命令调用函数。

      说明

      请确保您为函数配置的交换机网段或固定公网IP地址已添加到数据库实例访问白名单中。具体操作,请参见步骤3

      sudo s invoke -e "{}"

  • 本页导读 (1)
  • 前提条件
  • 操作步骤
  • 步骤一:设置数据库白名单
  • 步骤二:在函数中访问RDS
  • 更多信息
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等