Java アプリケーション環境に Amazon RDS DB インスタンスを追加する - AWS Elastic Beanstalk

Java アプリケーション環境に Amazon RDS DB インスタンスを追加する

アプリケーションで収集または変更したデータを保存するには、Amazon Relational Database Service (Amazon RDS) DB インスタンスを使用します。データベースは、Elastic Beanstalk でお客様の環境にアタッチして管理したり、外部で作成して管理したりできます。

初めて Amazon RDS を使用する場合は、Elastic Beanstalk コンソールを使用してテスト環境に DB インスタンスを追加し、そのインスタンスにアプリケーションから接続できることを確認します。

お客様の環境に DB インスタンスを追加するには

  1. Elastic Beanstalk コンソールを開き、[リージョン] リストで AWS リージョンを選択します。

  2. ナビゲーションペインで、[環境] を選択し、リストから環境の名前を選択します。

    注記

    環境が多数ある場合は、検索バーを使用して環境リストをフィルタリングします。

  3. ナビゲーションペインで、[設定] を選択します。

  4. [データベース] 設定カテゴリで、[編集] を選択します。

  5. DB エンジンを選択して、ユーザー名とパスワードを入力します。

  6. [Apply] を選択します。

DB インスタンスの追加には約 10 分かかります。環境の更新が完了すると、DB インスタンスのホスト名とその他の接続情報は以下の環境プロパティを通じてアプリケーションに使用できるようになります。

プロパティ名 説明 プロパティ値

RDS_HOSTNAME

DB インスタンスのホスト名。

Amazon RDS コンソールの [Connectivity & security (接続とセキュリティ)] タブ: [Endpoint (エンドポイント)]。

RDS_PORT

DB インスタンスが接続を許可するポート。デフォルト値は DB エンジンによって異なります。

Amazon RDS コンソールの [Connectivity & security (接続とセキュリティ)] タブ: [Port (ポート)]。

RDS_DB_NAME

データベース名 ebdb

Amazon RDS コンソールの [Configuration (設定)] タブ: [DB Name (DB 名)]。

RDS_USERNAME

お客様のデータベース用に設定したユーザー名。

Amazon RDS コンソールの [Configuration (設定)] タブ: [Master username (マスターユーザー名)]。

RDS_PASSWORD

お客様のデータベース用に設定したパスワード。

Amazon RDS コンソールでは参照できません。

内部 DB インスタンスの設定の詳細については、「」を参照してくださいElastic Beanstalk 環境にデータベースを追加する astic Beanstalk で使用する外部データベースを設定する手順については、「」を参照してくださいAmazon RDS で Elastic Beanstalk を使用する

データベースに接続するには、適切なドライバーの JAR ファイルをアプリケーションに追加して、コードにドライバークラスをロードし、Elastic Beanstalk で提供される環境プロパティを使用して接続オブジェクトを作成します。

JDBC ドライバーのダウンロード

選択した DB エンジン用の JDBC ドライバーの JAR ファイルが必要になります。JAR ファイルをソースコードに保存し、データベースへの接続を作成するクラスをコンパイルするときのクラスパスに含めます。

以下の場所で DB エンジン用の最新のドライバが見つかります。

JDBC ドライバーを使用するには、コード内で Class.forName() により接続を作成する前に、DriverManager.getConnection() を呼び出してそのドライバーをロードします。

JDBC では次の形式の接続文字列が使用されます:

jdbc:driver://hostname:port/dbName?user=userName&password=password

ホスト名、ポート、データベース名、ユーザー名、パスワードは、Elastic Beanstalk からアプリケーションに提供される環境変数から取得できます。ドライバ名は、データベースタイプとドライババージョンによって異なります。以下はドライバー名の一例です。

  • mysql for MySQL

  • postgresql for PostgreSQL

  • oracle:thin(Oracle Thin)

  • oracle:oci(Oracle OCI)

  • oracle:oci8(Oracle OCI 8)

  • oracle:kprb(Oracle KPRB)

  • sqlserver(SQL Server)

データベースへの接続 (Java SE プラットフォーム)

Java SE 環境では、System.getenv() を使用して環境から接続変数を読み取ります。以下のコード例では、PostgreSQL データベースへの接続を作成するクラスを示しています。

private static Connection getRemoteConnection() { if (System.getenv("RDS_HOSTNAME") != null) { try { Class.forName("org.postgresql.Driver"); String dbName = System.getenv("RDS_DB_NAME"); String userName = System.getenv("RDS_USERNAME"); String password = System.getenv("RDS_PASSWORD"); String hostname = System.getenv("RDS_HOSTNAME"); String port = System.getenv("RDS_PORT"); String jdbcUrl = "jdbc:postgresql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName + "&password=" + password; logger.trace("Getting remote connection with connection string from environment variables."); Connection con = DriverManager.getConnection(jdbcUrl); logger.info("Remote connection successful."); return con; } catch (ClassNotFoundException e) { logger.warn(e.toString());} catch (SQLException e) { logger.warn(e.toString());} } return null; }

データベースへの接続 (Tomcat プラットフォーム)

Tomcat 環境では、環境プロパティは、System.getProperty() でアクセス可能なシステムプロパティとして用意されています。

以下のコード例では、PostgreSQL データベースへの接続を作成するクラスを示しています。

private static Connection getRemoteConnection() { if (System.getProperty("RDS_HOSTNAME") != null) { try { Class.forName("org.postgresql.Driver"); String dbName = System.getProperty("RDS_DB_NAME"); String userName = System.getProperty("RDS_USERNAME"); String password = System.getProperty("RDS_PASSWORD"); String hostname = System.getProperty("RDS_HOSTNAME"); String port = System.getProperty("RDS_PORT"); String jdbcUrl = "jdbc:postgresql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName + "&password=" + password; logger.trace("Getting remote connection with connection string from environment variables."); Connection con = DriverManager.getConnection(jdbcUrl); logger.info("Remote connection successful."); return con; } catch (ClassNotFoundException e) { logger.warn(e.toString());} catch (SQLException e) { logger.warn(e.toString());} } return null; }

接続の取得時や SQL ステートメントの実行時に問題が発生する場合は、JSP ファイルに以下のコードを追加してみることができます。このコードは、DB インスタンスに接続し、テーブルを作成して、そのテーブルに書き込みます。

<%@ page import="java.sql.*" %> <% // Read RDS connection information from the environment String dbName = System.getProperty("RDS_DB_NAME"); String userName = System.getProperty("RDS_USERNAME"); String password = System.getProperty("RDS_PASSWORD"); String hostname = System.getProperty("RDS_HOSTNAME"); String port = System.getProperty("RDS_PORT"); String jdbcUrl = "jdbc:mysql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName + "&password=" + password; // Load the JDBC driver try { System.out.println("Loading driver..."); Class.forName("com.mysql.jdbc.Driver"); System.out.println("Driver loaded!"); } catch (ClassNotFoundException e) { throw new RuntimeException("Cannot find the driver in the classpath!", e); } Connection conn = null; Statement setupStatement = null; Statement readStatement = null; ResultSet resultSet = null; String results = ""; int numresults = 0; String statement = null; try { // Create connection to RDS DB instance conn = DriverManager.getConnection(jdbcUrl); // Create a table and write two rows setupStatement = conn.createStatement(); String createTable = "CREATE TABLE Beanstalk (Resource char(50));"; String insertRow1 = "INSERT INTO Beanstalk (Resource) VALUES ('EC2 Instance');"; String insertRow2 = "INSERT INTO Beanstalk (Resource) VALUES ('RDS Instance');"; setupStatement.addBatch(createTable); setupStatement.addBatch(insertRow1); setupStatement.addBatch(insertRow2); setupStatement.executeBatch(); setupStatement.close(); } catch (SQLException ex) { // Handle any errors System.out.println("SQLException: " + ex.getMessage()); System.out.println("SQLState: " + ex.getSQLState()); System.out.println("VendorError: " + ex.getErrorCode()); } finally { System.out.println("Closing the connection."); if (conn != null) try { conn.close(); } catch (SQLException ignore) {} } try { conn = DriverManager.getConnection(jdbcUrl); readStatement = conn.createStatement(); resultSet = readStatement.executeQuery("SELECT Resource FROM Beanstalk;"); resultSet.first(); results = resultSet.getString("Resource"); resultSet.next(); results += ", " + resultSet.getString("Resource"); resultSet.close(); readStatement.close(); conn.close(); } catch (SQLException ex) { // Handle any errors System.out.println("SQLException: " + ex.getMessage()); System.out.println("SQLState: " + ex.getSQLState()); System.out.println("VendorError: " + ex.getErrorCode()); } finally { System.out.println("Closing the connection."); if (conn != null) try { conn.close(); } catch (SQLException ignore) {} } %>

結果を表示するには、JSP ファイルの HTML 部分の本文に次のコードを挿入します。

<p>Established connection to RDS. Read first two rows: <%= results %></p>

データベース接続のトラブルシューティング

アプリケーションからデータベースへの接続で問題が発生する場合は、ウェブコンテナのログとデータベースを確認します。

ログを確認する

Elastic Beanstalk 環境のすべてのログは、Eclipse 内から表示できます。AWS Explorer ビューが開いていない場合は、ツールバーのオレンジ色の [AWS] アイコンの横にある矢印を選択した後、[AWS エクスプローラービューの表示] を選択します。[AWS Elastic Beanstalk] および環境名を展開し、サーバーのコンテキストメニューを開きます (右クリック)。[Open in WTP Server Editor] を選択します。

[Server] ビューの [Log] タブを選択し、環境の集計ログを表示します。最新のログを開くには、ページ右上の [Refresh] ボタンを選択します。

下にスクロールし、/var/log/tomcat7/catalina.out 内の Tomcat ログを探します。これまでの例で何回かウェブページを読み込んだ場合は、次のように表示されることがあります。

------------------------------------- /var/log/tomcat7/catalina.out ------------------------------------- INFO: Server startup in 9285 ms Loading driver... Driver loaded! SQLException: Table 'Beanstalk' already exists SQLState: 42S01 VendorError: 1050 Closing the connection. Closing the connection.

ウェブアプリケーションが標準出力に送信するすべての情報は、ウェブコンテナのログに表示されます。前の例では、アプリケーションは、ページが読み込まれるたびにテーブルを作成しようとします。これにより、最初のページ以降のすべてのページのロード時に SQL 例外が捕捉されます。

上記は例としては問題ありません。ただし、実際のアプリケーションでは、データベース定義をスキーマオブジェクトに保持して、モデルクラス内からトランザクションを実行し、コントローラーサーブレットによってリクエストを調整します。

RDS DB インスタンスに接続する

MySQL クライアントアプリケーションを使用すると、Elastic Beanstalk 環境内の RDS DB インスタンスに直接接続できます。

最初に、RDS DB インスタンスからセキュリティグループにアクセスできるようにして、コンピュータからのトラフィックを許可します。

  1. Elastic Beanstalk コンソールを開き、[リージョン] リストで AWS リージョンを選択します。

  2. ナビゲーションペインで、[環境] を選択し、リストから環境の名前を選択します。

    注記

    環境が多数ある場合は、検索バーを使用して環境リストをフィルタリングします。

  3. ナビゲーションペインで、[設定] を選択します。

  4. [データベース] 設定カテゴリで、[編集] を選択します。

  5. [エンドポイント] の横にある Amazon RDS コンソールリンクを選択します。

  6. [RDS Dashboard] のインスタンスの詳細ページで、[Security and Network] の [Security Groups] から、rds- で始まるセキュリティグループを選択します。

    注記

    データベースには、[Security Groups] のラベルが付けられたエントリが複数ある場合があります。古い方のアカウントにデフォルトの Amazon Virtual Private Cloud (Amazon VPC) が設定されてない場合のみ、最初のエントリ (awseb で始まるもの) を使用します。

  7. [Security group details] で、[Inbound] タブ、[Edit] の順に選択します。

  8. MySQL (ポート 3306)に、CIDR 形式で指定した IP アドレスからのトラフィックを許可するルールを追加します。

  9. [Save] を選択します。変更はすぐに反映されます。

環境の Elastic Beanstalk 詳細設定に戻り、エンドポイントを書き留めます。RDS DB インスタンスに接続するには、ドメイン名を使用します。

MySQL クライアントをインストールし、ポート 3306 でデータベースへの接続を開始します。Windows の場合は、MySQL のホームページから MySQL Workbench をインストールし、プロンプトに従います。

Linux の場合は、お客様のディストリビューションに対応したパッケージマネージャを使用して、MySQL クライアントをインストールします。次の例は、Ubuntu および Debian から派生したその他の OS で利用できます。

// Install MySQL client $ sudo apt-get install mysql-client-5.5 ... // Connect to database $ mysql -h aas839jo2vwhwb.cnubrrfwfka8.us-west-2.rds.amazonaws.com -u username -ppassword ebdb Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 117 Server version: 5.5.40-log Source distribution ...

接続後、SQL コマンドを実行し、データベースのステータス、テーブルや行が作成されたかどうかなどの情報を確認できます。

mysql> SELECT Resource from Beanstalk; +--------------+ | Resource | +--------------+ | EC2 Instance | | RDS Instance | +--------------+ 2 rows in set (0.01 sec)