

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 將 Amazon RDS 資料庫執行個體新增至 Java Elastic Beanstalk 環境
<a name="java-rds"></a>

本主題提供了使用 Elastic Beanstalk 主控台建立 Amazon RDS 的說明。您可以使用 Amazon Relational Database Service (Amazon RDS) 資料庫執行個體存放由應用程式收集與修改的資料。資料庫可連接到您的環境並由 Elastic Beanstalk 管理，或者在外部建立與管理。

若您首次使用 Amazon RDS，請透過 Elastic Beanstalk 主控台將資料庫執行個體新增至測試環境，並確認您的應用程式是否可與其連接。

**欲將資料庫執行個體新增到您的環境**

1. 開啟 [Elastic Beanstalk 主控台](https://console.aws.amazon.com/elasticbeanstalk)，然後在**區域**清單中選取您的 AWS 區域。

1. 在導覽窗格中，選擇**環境**，然後在清單中選擇您環境的名稱。

1. 在導覽窗格中，選擇 **Configuration (組態)**。

1. 在 **Database (資料庫)** 組態類別中，選擇 **Edit (編輯)**。

1. 選擇資料庫引擎，並輸入使用者名稱和密碼。

1. 若要儲存變更，請選擇頁面底部的**儲存變更**。

新增資料庫執行個體約需要 10 分鐘。環境更新完成時，資料庫執行個體的主機名稱和其他連線資訊會透過下列環境屬性提供給您的應用程式：


| 屬性名稱 | 描述 | 屬性值 | 
| --- | --- | --- | 
|  `RDS_HOSTNAME`  |  資料庫執行個體的主機名稱。  |  在 Amazon RDS 主控台：**端點**的**連線能力和安全性**索引標籤上。  | 
|  `RDS_PORT`  |  資料庫執行個體接受連線的連接埠。預設值在不同資料庫引擎中有所差異。  |  在 Amazon RDS 主控台：**連接埠**的**連線能力和安全性**索引標籤上。  | 
|  `RDS_DB_NAME`  |  資料庫名稱，**ebdb**。  |  在 Amazon RDS 主控台：**資料庫名稱**的**組態**索引標籤上。  | 
|  `RDS_USERNAME`  |  您為資料庫設定的使用者名稱。  |  在 Amazon RDS 主控台：**主要使用者名稱**的**組態**索引標籤上。  | 
|  `RDS_PASSWORD`  |  您為資料庫設定的密碼。  |  無法在 Amazon RDS 主控台中提供參考。  | 

如需設定內部資料庫執行個體的詳細資訊，請參閱[將資料庫新增至您的 Elastic Beanstalk 環境](using-features.managing.db.md)。如需有關設定外部資料庫搭配 Elastic Beanstalk 使用的說明，請參閱[搭配 Amazon RDS 使用 Elastic Beanstalk](AWSHowTo.RDS.md)。

欲連接至資料庫，請於您的應用程式新增合適的驅動程式 JAR 檔案、下載您程式碼的驅動程式類別，並使用 Elastic Beanstalk 提供的環境屬性建立連線物件。

**Topics**
+ [下載 JDBC 驅動程式](#java-rds-drivers)
+ [連線至資料庫 (Java SE 平台)](#java-rds-javase)
+ [連線至資料庫 (Tomcat 平台)](#java-rds-tomcat)
+ [資料庫連線故障診斷](#create_deploy_Java.rds.troubleshooting)

## 下載 JDBC 驅動程式
<a name="java-rds-drivers"></a>

您將需要所選資料庫引擎的 JDBC 驅動程式 JAR 檔案。將 JAR 檔案儲存至您的原始碼，並在編譯會建立資料庫連結的類別時，將其納入 classpath。

您可於下列位置找到資料庫引擎最新的驅動程式：
+ **MySQL** – [MySQL 連接器/J](https://dev.mysql.com/downloads/connector/j/)
+ **Oracle SE-1** – [Oracle JDBC 驅動程式](http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html)
+ **Postgres** – [PostgreSQL JDBC 驅動程式](https://jdbc.postgresql.org/)
+ **SQL Server** – [Microsoft JDBC 驅動程式](https://msdn.microsoft.com/en-us/sqlserver/aa937724.aspx)

欲使用 JDBC 驅動程式，請呼叫 `Class.forName()` 來載入，之後再於程式碼中透過 `DriverManager.getConnection()` 建立連結。

JDBC 使用的連線字串格式如下：

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

您可從 Elastic Beanstalk 提供您應用程式的環境變數，擷取主機名稱、連接埠、資料庫名稱、使用者名稱和密碼。驅動程式名稱為您的資料庫類型和驅動程式版本專屬。下列為範例驅動程式名稱：
+ `mysql`適用於 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 平台)
<a name="java-rds-javase"></a>

在 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 平台)
<a name="java-rds-tomcat"></a>

在 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 檔案。此程式碼會連線至資料庫執行個體、建立資料表並寫入其中。

```
<%@ 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>
```

## 資料庫連線故障診斷
<a name="create_deploy_Java.rds.troubleshooting"></a>

**試用 Amazon Q Developer CLI 進行 AI 輔助故障診斷**  
 Amazon Q Developer CLI 可協助您快速疑難排解環境問題。Q CLI 透過檢查環境狀態、檢閱事件、分析日誌和詢問釐清問題來提供解決方案。如需詳細資訊和詳細的逐步解說，請參閱 AWS 部落格中的[使用 Amazon Q Developer CLI 疑難排解 Elastic Beanstalk 環境](https://aws.amazon.com/blogs/devops/troubleshooting-elastic-beanstalk-environments-with-amazon-q-developer-cli/)。

若您從應用程式建立資料庫連線出現問題，請檢視 Web 容器日誌和資料庫。

### 檢視日誌
<a name="create_deploy_Java.rds.troubleshooting.logs"></a>

您可於 Eclipse 內檢視 Elastic Beanstalk 環境的所有日誌。如果您沒有開啟 AWS Explorer 檢視，請選擇工具列中橘色 AWS 圖示旁的箭頭，然後選擇**顯示 AWS Explorer 檢視**。展開 **AWS Elastic Beanstalk** 以及您的環境名稱，然後開啟伺服器的內容選單 (按一下滑鼠右鍵)。選擇 **Open in WTP Server Editor (於 WTP 伺服器編輯器開啟)**。

 選擇 **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.
```

Web 應用程式傳送至標準輸出的所有資訊會顯示於 Web 容器日誌。在上述範例中，應用程式在每次載入頁面時都嘗試建立資料表。這導致第一次載入頁面後，每次載入頁面都會發現 SQL 例外狀況。

以範例而言，上述為可接受情況。但實際在應用程式中，請於結構描述物件中保存資料庫定義，在模型類別中執行交易，並與控制器 Servlet 協調請求。

### 連接到 RDS 資料庫執行個體
<a name="create_deploy_Java.rds.troubleshooting.connecting"></a>

 您可使用 MySQL 用戶端應用程式，直接連接至 Elastic Beanstalk 環境中的 RDS 資料庫執行個體。

 首先，請開放對 RDS 資料庫執行個體的安全群組，以允許來自您電腦的流量。

1. 開啟 [Elastic Beanstalk 主控台](https://console.aws.amazon.com/elasticbeanstalk)，然後在**區域**清單中選取您的 AWS 區域。

1. 在導覽窗格中，選擇**環境**，然後在清單中選擇您環境的名稱。

1. 在導覽窗格中，選擇 **Configuration (組態)**。

1. 在 **Database (資料庫)** 組態類別中，選擇 **Edit (編輯)**。

1. 在 **Endpoint (端點)** 旁，選擇 Amazon RDS 主控台連結。

1. 在 **RDS Dashboard (RDS 儀表板)** 執行個體詳細資訊頁面中的 **Security and Network (安全與網路)** 下，選擇 **Security Groups (安全群組)** 旁開頭為 *rds-* 的安全群組。
**注意**  
資料庫可能有多個項目均標示為 **Security Groups (安全群組)**。僅在您較舊的帳戶沒有預設 [Amazon Virtual Private Cloud](https://docs.aws.amazon.com/vpc/latest/userguide/) (Amazon VPC) 的情況下，才使用第一個項目 (開頭為 *awseb*)。

1. 在 **Security group details (安全群組詳細資訊)** 中，選擇 **Inbound (傳入)** 索引標籤，然後選擇 **Edit (編輯)**。

1. 新增 MySQL (連接埠 3306) 的規則，以允許來自您以 CIDR 格式指定的 IP 地址的流量。

1. 選擇 **Save** (儲存)。變更會立即生效。

 返回您環境的 Elastic Beanstalk 組態詳細資訊，並記下端點。您將使用該網域名稱連接至 RDS 資料庫執行個體。

 安裝 MySQL 用戶端並於連接埠 3306 啟動資料庫的連線。在 Windows 上，請自 MySQL 首頁安裝 MySQL Workbench，並依提示操作。

 在 Linux 上，請使用適用您的分發的套件管理工具，來安裝 MySQL 用戶端。下列範例運作於 Ubuntu 和其他 Debian 的衍生產品。

```
// 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)
```