Function Compute では、実行インスタンスはステートレスです。データベースを使用して、構造化データを永続化し、状態を共有できます。Function Compute からクラウドデータベースにアクセスすることで、データクエリや挿入などの操作を実行できます。このトピックでは、Python 関数を例に、同じ VPC 内または異なる VPC やリージョンから ApsaraDB RDS for MySQL インスタンスにアクセスする方法について説明します。
前提条件
-
このトピックの `index.py` サンプルコードは、`users` という名前のテーブルからすべてのデータをクエリします。必要に応じてテーブル名を変更できますが、テーブルに少なくとも 1 つのレコードが含まれていることを確認してください。
操作手順
ステップ 1:データベースのホワイトリストの設定
シナリオ 1:同じ VPC
同じ VPC 内のデータベースにアクセスする場合、データベースインスタンスと関数が同じリージョンにあることを確認してください。Function Compute がサポートするゾーンにデータベースインスタンスを作成することを推奨します。詳細については、「Function Compute がサポートするゾーン」をご参照ください。ご利用のデータベースインスタンスがサポートされているゾーンにない場合は、関数と同じゾーンに vSwitch を作成し、その ID を関数の VPC 設定で指定できます。同じ VPC 内の vSwitch はプライベートネットワークを介して相互に通信できるため、関数はこの vSwitch を使用して VPC の他のゾーンのリソースにアクセスできます。詳細については、「「vSwitch is in unsupported zone」というエラーが表示された場合の対処方法」をご参照ください。
-
Function Compute コンソールにログインし、Python Web 関数を作成します。関数詳細ページで、設定 タブを選択し、詳細設定 セクションの 変更 をクリックします。詳細設定 パネルで ネットワーク セクションを見つけ、関数の VPC アクセスを有効にし、送信先の VPC リソースを設定します。
説明関数に設定された VPC が、データベースインスタンスがバインドされている VPC と同じであることを確認してください。
VPC、vSwitch、セキュリティグループを設定できます。Function Compute のマルチゾーンディザスタリカバリ機能を最大限に活用し、サービスの可用性を高めるために、2 つ以上のゾーンに vSwitch をデプロイすることを推奨します。現在のリージョンでサポートされているゾーンは、中国 (杭州) の h、i、j、k、f、g、b です。
-
関数詳細ページの 設定 タブに移動します。ネットワーク セクションで、関数に設定されている vSwitch の CIDR ブロックを取得します。
-
前のステップで取得した vSwitch の CIDR ブロックをデータベースのアクセスホワイトリストに追加します。
重要セキュリティグループではなく、IP アドレスホワイトリストを使用して関数のアクセスを承認することを推奨します。セキュリティグループを使用すると、断続的な接続障害が発生し、サービスに影響を与える可能性があります。
-
RDS インスタンスリストに移動し、リージョンを選択して、ターゲットインスタンスの ID をクリックします。
-
左側のナビゲーションウィンドウで、ホワイトリストとセキュリティグループ をクリックします。
ホワイトリストの設定 ページで、現在の IP ホワイトリストモードを確認できます。
説明古いインスタンスは高セキュリティモードで動作する場合があります。すべての新しいインスタンスは標準のホワイトリストモードを使用します。
-
default グループの右側にある 変更 をクリックします。グループを変更する ダイアログボックスで、ステップ 2 で取得した vSwitch の IPv4 CIDR ブロックをホワイトリストに追加し、OK をクリックします。
設定が完了すると、関数は内部エンドポイントを介して RDS データベースにアクセスできるようになります。
-
シナリオ 2:異なる VPC またはリージョン間
VPC とリージョンは論理的に分離されています。デフォルトでは、異なる VPC またはリージョン間でデータベースにアクセスすることはできません。これを有効にするには、関数に固定パブリック IP アドレスを設定します。システムは関数の VPC にパブリック NAT ゲートウェイを作成し、関数がパブリック IP アドレスを使用してインターネット経由でデータベースにアクセスできるようにします。
-
Function Compute コンソールにログインします。左側のナビゲーションウィンドウで、[関数] をクリックします。リージョンを選択し、プロンプトに従って関数を作成します。
-
関数詳細ページで、設定 タブをクリックします。詳細設定 セクションで、変更 をクリックします。詳細設定 パネルで、ネットワーク セクションを見つけます。固定パブリック IP を有効にするには、固定パブリック IP アドレス を有効にし、関数がデフォルトで NIC のインターネットアクセスを許可する を無効にします。その後、デプロイ をクリックします。
-
関数詳細ページの 設定 タブに移動します。ネットワーク セクションで、関数に設定されている Elastic IP アドレス (EIP) を取得します。
-
前のステップで取得した EIP をデータベースのアクセスホワイトリストに追加します。
重要セキュリティグループではなく、IP アドレスホワイトリストを使用して関数のアクセスを承認することを推奨します。セキュリティグループを使用すると、断続的な接続障害が発生し、サービスに影響を与える可能性があります。
-
RDS インスタンスリストに移動し、リージョンを選択して、ターゲットインスタンスの ID をクリックします。
-
左側のナビゲーションウィンドウで、ホワイトリストとセキュリティグループ をクリックします。
ホワイトリストの設定 ページで、現在の IP ホワイトリストモードを確認できます。
説明古いインスタンスは高セキュリティモードで動作する場合があります。すべての新しいインスタンスは標準のホワイトリストモードを使用します。
-
default グループの右側にある 変更 をクリックします。グループを変更する ダイアログボックスで、ステップ 3 で取得した固定パブリック IP アドレスをホワイトリストに追加し、OK をクリックします。
ホワイトリストには、
192.168.0.1のような特定の IP アドレスや、192.168.0.0/24のような CIDR ブロックを含めることができます。複数のエントリはカンマで区切ります。注意:ホワイトリストを0.0.0.0/0に設定すると、パブリックインターネットからのアクセスが許可され、127.0.0.1に設定すると、すべての外部アクセスがブロックされます。新しいホワイトリストは約 1 分で有効になります。
設定が完了すると、関数はパブリックエンドポイントを介して RDS データベースにアクセスできるようになります。
-
ステップ 2:関数から RDS へのアクセス
-
Function Compute コンソールにログインします。関数リストでターゲット関数を見つけます。その詳細ページで、コード タブをクリックし、エディターに次のサンプルコードを入力します。
from flask import Flask, jsonify import pymysql import os from datetime import datetime import logging app = Flask(__name__) # シングルトンの MySQL 接続を格納するグローバル変数 _mysql_connection = None # データベース接続の作成 (シングルトンパターン) def getConnection(): global _mysql_connection try: # 接続が存在し、アクティブな場合はそれを返す if _mysql_connection is not None: try: # 簡単なクエリで接続が有効かテストする with _mysql_connection.cursor() as cursor: cursor.execute("SELECT 1") # 接続ステータスをテストするための簡単なクエリ result = cursor.fetchone() if result and result[0] == 1: return _mysql_connection except pymysql.OperationalError: # 接続が切れている場合はリセットする _mysql_connection = None # 接続が存在しないか切れている場合は、新しい接続を作成する _mysql_connection = pymysql.connect( host=os.environ['MYSQL_HOST'], port=int(os.environ['MYSQL_PORT']), user=os.environ['MYSQL_USER'], password=os.environ['MYSQL_PASSWORD'], db=os.environ['MYSQL_DBNAME'] ) return _mysql_connection except Exception as e: logging.error(f"データベース接続中にエラーが発生しました: {e}") raise @app.route('/', defaults={'path': ''}) @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE']) def hello_world(path): conn = getConnection() try: with conn.cursor() as cursor: # users テーブルからすべてのレコードをクエリします。「users」を実際のテーブル名に変更する必要があります。 sql = "SELECT * FROM users" cursor.execute(sql) result = cursor.fetchall() columns = [desc[0] for desc in cursor.description] # 列名のリストを取得 # クエリ結果を辞書のリストに変換 users = [] for row in result: user = {} for idx, column_name in enumerate(columns): value = row[idx] if isinstance(value, datetime): # datetime フィールドの処理 user[column_name] = value.strftime('%Y-%m-%d %H:%M:%S') else: user[column_name] = value users.append(user) if users: # すべてのユーザーを含む JSON レスポンスを返す return jsonify(users), 200 else: # ユーザーが見つからない場合は 404 エラーを返す return jsonify({'error': 'ユーザーが見つかりません'}), 404 except Exception as e: logging.error(f"データベース操作中にエラーが発生しました: {e}") return jsonify({'error': 'データベースエラー'}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=9000) -
関数詳細ページで、設定 タブを選択し、詳細設定 を見つけ、その右側にある 変更 をクリックします。詳細設定 パネルで、環境変数 セクションを見つけ、次の環境変数を設定し、デプロイ をクリックします。
パラメーター
値
説明
MYSQL_HOST
rm-bp19u8e76ae****.mysql.rds.aliyuncs.com
RDS インスタンスのエンドポイント。
-
同じ VPC 内の RDS データベースにアクセスする場合は、この環境変数をデータベースの内部エンドポイントに設定します。
-
異なる VPC またはリージョン間で RDS データベースにアクセスする場合は、この環境変数をデータベースのパブリックエンドポイントに設定します。
RDS インスタンスリストで、ターゲット RDS インスタンスの ID をクリックします。左側のナビゲーションウィンドウで、データベースの接続 をクリックします。データベースの接続 ページで、データベースの内部またはパブリックエンドポイントを取得できます。
MYSQL_DBNAME
db_test
RDS インスタンスで作成されたデータベースの名前。
MYSQL_PASSWORD
*****
データベースのパスワード。
MYSQL_PORT
3306
データベースインスタンスのプライベートポート。
MYSQL_USER
dms_user_****
RDS インスタンスで作成されたアカウントの名前。
-
-
関数詳細ページで、コード タブをクリックし、関数のテスト をクリックします。関数が正常に実行された後、返された結果を確認してクエリが完了したことを確認します。
返された JSON データには、
id、username、email、password_hash、created_at、updated_atなどのフィールドを持つユーザーレコードが含まれています。
関連情報
-
ApsaraDB RDS for MySQL データベースへのアクセスのその他の例については、「Function Compute Python accessing MySQL database」をご参照ください。
-
データベースにアクセスできない場合は、症状に基づいて問題をトラブルシューティングしてください。詳細については、「データベースアクセス失敗の一般的な原因」をご参照ください。
-
ApsaraDB RDS は、MySQL、SQL Server、PostgreSQL、MariaDB データベースエンジンをサポートしています。詳細については、「ApsaraDB RDS の概要」をご参照ください。
-
Serverless Devs コマンドラインツールを使用して関数を作成し、ApsaraDB RDS for MySQL データベースにアクセスするには、次の手順に従います。