メニュー
AWS Elastic Beanstalk
開発者ガイド (API Version 2010-12-01)

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

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

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

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

  1. Elastic Beanstalk コンソールを開きます。

  2. お客様の環境の管理ページに移動します。

  3. [Configuration] を選択します。

  4. [Data Tier] で、[Create a new RDS database] を選択します。

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

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

  • RDS_HOSTNAME – DB インスタンスのホスト名。

    Amazon RDS コンソールラベル – [Endpoint] はホスト名です。

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

    Amazon RDS コンソールラベル – [ポート]

  • RDS_DB_NAME – データベース名、ebdb

    Amazon RDS コンソールラベル – [DB 名前]

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

    Amazon RDS コンソールラベル – [ユーザー名]

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

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

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

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

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

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

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

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

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

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

  • mysql for MySQL

  • postgresql(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 アイコンの横にある矢印を選択した後、[Show AWS Explorer View] を選択します。[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 コンソールを開きます。

  2. お客様の環境の管理ページに移動します。

  3. [Configuration] を選択します。

  4. [Network Tier] の [RDS] セクションで、 [Edit] (歯車アイコン)を選択します。

  5. [DB endpoint] の横の [View in RDS Console] を選択します。

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

    注記

    データベースには、[Security Groups] のラベルが付けられたエントリが複数ある場合があります。古い方のアカウントにデフォルトの 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)