

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 部署 Java 应用程序
<a name="layers-java-deploy"></a>

**重要**  
该 AWS OpsWorks Stacks 服务于 2024 年 5 月 26 日终止，新客户和现有客户均已禁用。我们强烈建议客户尽快将其工作负载迁移到其他解决方案。如果您对迁移有疑问，请通过 re [AWS : Post 或通过 Pre](https://repost.aws/) mium Su [AWS pp](https://aws.amazon.com/support) ort 与 AWS 支持 团队联系。

以下主题介绍了如何将应用程序部署到 Java App Server 层的实例中。示例针对的都是 JSP 应用程序，但安装其他类型的 Java 应用程序时，您可以使用基本相同的安装过程。

您可以从任何受支持的存储库中部署 JSP 页面。如果你想部署 WAR 文件，请注意， OpsWorks Stacks 会自动提取从 Amazon S3 或 HTTP 存档中部署的 WAR 文件，而不是从 Git 或 Subversion 存储库中提取部署的 WAR 文件。如果您想要为 WAR 文件使用 Git 或 Subversion，您可以执行以下操作之一：
+ 将提取的存档存储在存储库中。
+ 将 WAR 文件存储到存储库中，并使用 Chef 部署挂钩提取存档，如下例中所述。

您可以在四个部署阶段的任一阶段使用 Chef 部署挂钩在实例上运行用户提供的 Ruby 应用程序。应用程序名称决定着阶段。以下是一个名为 `before_migrate.rb` 的 Ruby 应用程序的示例，该应用程序可从 Git 或 Subversion 存储库中提取已部署的 WAR 文件。名称将应用程序与 Checkout 部署挂钩关联起来，以便它在部署操作开始时 (检查代码之后，迁移之前) 运行。有关如何使用此示例的更多信息，请参阅[使用 Chef 部署挂钩](workingcookbook-extend-hooks.md)。

```
::Dir.glob(::File.join(release_path, '*.war')) do |archive_file|
  execute "unzip_#{archive_file}" do
    command "unzip #{archive_file}"
    cwd release_path
  end
end
```

**注意**  
当您为 JSP 应用程序部署更新时，Tomcat 可能无法识别该更新，而是继续运行现有的应用程序版本。在某些情况下，比如当您将您的应用程序作为仅包含一个 JSP 页面的 .zip 文件时，可能会发生这种情况。要确保 Tomcat 将运行最近部署的版本，项目的根目录应包含放置了 `web.xml` 文件的 WEB-INF 目录。`web.xml` 文件可包含各种内容，但以下内容足以确保 Tomcat 识别更新并运行当前部署的应用程序版本。您无需为每个更新更改版本。Tomcat 将识别更新，即使版本未发生更改。  

```
<context-param>
  <param-name>appVersion</param-name>
  <param-value>0.1</param-value>
</context-param>
```

**Topics**
+ [部署 JSP 应用程序](#layers-java-deploy-jsp)
+ [部署 JSP 应用程序附带后端数据库](#layers-java-deploy-jsp-db)

## 部署 JSP 应用程序
<a name="layers-java-deploy-jsp"></a>

要部署 JSP 应用程序，指定名称和存储库信息。您也可以选择性地指定域和 SSL 设置。有关如何创建应用程序的更多信息，请参阅[添加应用程序](workingapps-creating.md)。以下过程介绍了如何在公有 Amazon S3 存档中创建和部署一个简单的 JSP 页面。有关如何使用其他存储库类型 (包括私有 Amazon S3 存档) 的信息，请参阅 [应用程序源](workingapps-creating.md#workingapps-creating-source)。

以下示例显示了 JSP 页面，该页面仅显示某些系统信息。

```
<%@ page import="java.net.InetAddress" %>
<html>
<body>
<%
    java.util.Date date = new java.util.Date();
    InetAddress inetAddress = InetAddress.getLocalHost();
%>
The time is 
<%
    out.println( date );
    out.println("<br>Your server's hostname is "+inetAddress.getHostName());
%>
<br>
</body>
</html>
```

**注意**  
以下过程假定您已熟悉关于创建堆栈、将实例添加到层等的基础知识。如果你不熟悉 OpsWorks Stacks，你应该先看看[Chef 11 Linux 堆栈入门](gettingstarted.md)。

**从 Amazon S3 存档部署 JSP 页面**

1. [创建带有 Java App Server 层的堆栈](workingstacks-creating.md)，[将一个全天候实例添加](workinginstances-add.md)到层中，然后[启动实例](workinginstances-starting.md)。

1. 将代码复制到名为 `simplejsp.jsp` 的文件中，将该文件放到名为 `simplejsp` 的文件夹中，然后创建该文件夹的 `.zip` 存档。名称是任意的；您可以按照您的意愿使用任何文件或文件夹名称。您也可以使用其他类型的存档，包括 gzip、bzip2、tarball 或 Java WAR 文件。请注意， OpsWorks Stacks 不支持未压缩的压缩包。要部署多个 JSP 页面，将这些页面放到相同的存档中。

1. 将该存档上传到 Amazon S3 存储桶，并将该文件设置为公有。复制该文件的 URL 以备后用。有关如何创建存储桶和上传文件的更多信息，请转至 [Amazon Simple Storage Service 入门指南](https://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html)。

1. [将一个应用程序添加](workingapps-creating.md#workingapps-creating-general)到堆栈并指定以下设置：
   + **名称** – `SimpleJSP`
   + **App type** - `Java`
   + **Repository type** – `Http Archive`
   + **Repository URL** -存档文件的 Amazon S3 URL。

   对其余设置使用默认值，然后单击 **Add App** 创建应用程序。

1. [将应用程序部署](workingapps-deploying.md)到 Java App Server 实例。

现在，您可以转到应用程序的 URL 并查看应用程序。如果您未指定域，您可以使用实例的公有 IP 地址或其公有 DNS 名称构建一个 URL。要获取实例的公有 IP 地址或公有 DNS 名称，请转到 OpsWorks Stacks 控制台，然后在 “实例” 页面上单击该**实例**的名称以打开其详细信息页面。

网址的其余部分取决于应用程序的短名称，该名称是 OpsWorks Stacks 根据您在创建应用程序时指定的应用程序名称生成的小写名称。例如，SimpleJSP 的短名称是 simplejsp。您可以从应用程序的详细信息页面中获得应用程序的短名称。
+ 如果短名称为 `root`，您可以使用 `http://public_DNS/appname.jsp` 或 `http://public_IP/appname.jsp`。
+ 否则，您可以使用 `http://public_DNS/app_shortname/appname.jsp` 或 `http://public_IP/app_shortname/appname.jsp`。

如果您已经为应用程序指定了域，则 URL 为 `http://domain/appname.jsp`。

此示例中的 URL 将如下所示：`http://192.0.2.0/simplejsp/simplejsp.jsp`。

如果您希望将多个应用程序部署到同一个实例，则您不应当使用 `root` 作为短名称。这可能会导致 URL 冲突，从而妨碍应用程序正常运行。而应当为每个应用程序分配不同的域名。

## 部署 JSP 应用程序附带后端数据库
<a name="layers-java-deploy-jsp-db"></a>

JSP 页面可以使用 JDBC `DataSource` 对象连接到一个后端数据库。您可以通过上一部分中的步骤创建和部署此类应用程序，另外再执行一个设置连接的步骤即可。

以下 JSP 页面介绍如何连接到 `DataSource` 对象。

```
<html>
  <head>
    <title>DB Access</title>
  </head>
  <body>
    <%@ page language="java" import="java.sql.*,javax.naming.*,javax.sql.*" %>
    <%
      StringBuffer output = new StringBuffer();
      DataSource ds = null;
      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;
      try {
        Context initCtx = new InitialContext();
        ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/mydb");
        con = ds.getConnection();
        output.append("Databases found:<br>");
        stmt = con.createStatement();
        rs = stmt.executeQuery("show databases");
        while (rs.next()) {
          output.append(rs.getString(1));
          output.append("<br>");
        }
      }
      catch (Exception e) {
        output.append("Exception: ");
        output.append(e.getMessage());
        output.append("<br>");
      }
      finally {
        try {
          if (rs != null) {
            rs.close();
          }
          if (stmt != null) {
            stmt.close();
          }
          if (con != null) {
            con.close();
          }
        }
        catch (Exception e) {
          output.append("Exception (during close of connection): ");
          output.append(e.getMessage());
          output.append("<br>");
        }
      }
    %>
    <%= output.toString() %>
  </body>
</html>
```

OpsWorks Stacks 创建和初始化`DataSource`对象，将其绑定到逻辑名称，然后在 Java 命名和目录接口 (JNDI) 命名服务中注册该名称。完整的逻辑名称为 `java:comp/env/user-assigned-name`。您必须通过将自定义 JSON 属性添加到堆栈配置和部署属性定义 `['opsworks_java']['datasources']` 属性，来指定名称中用户分配的部分，如下所述。

**部署可连接到 MySQL 数据库的 JSP 页面**

1. [创建带有 Java App Server 层的堆栈](workingstacks-creating.md)，[将一个全天候实例添加](workinginstances-add.md)到每个层中，然后[启动实例](workinginstances-starting.md)。

1. 将一个数据库层添加到堆栈中。具体细节取决于您使用的数据库。

   要为示例使用 MySQL 实例，[添加 MySQL 层](workinglayers-db-mysql.md)到堆栈，[添加全天候实例](workinginstances-add.md)到该层，然后[启动实例](workinginstances-starting.md#workinginstances-starting-start)。

   要为示例使用 Amazon RDS (MySQL) 实例：
   + 为实例指定 MySQL 数据库引擎。
   + 将 **AWS OpsWorks-db-Master-Server () *security\$1group\$1id* 和 AWS--OpsWorks** **Java-App-S** erver () 安全组分配给实例。*security\$1group\$1id* OpsWorks 当您在该地区创建第一个堆栈时，Stacks 会为您创建这些安全组。
   + 创建一个名为 `simplejspdb` 的数据库。
   + 确保主用户名和密码不包含 `&` 或其他可能会导致 Tomcat 错误的符号。

     尤其是在启动期间，Tomcat 必须解析 Web 应用程序上下文文件，该文件是一个 XML 文件，其中包含主密码和用户名。如果任一字符串包含一个 `&` 字符，XML 分析器就会将其视为格式不正确的 XML 实体，并引发解析异常，从而阻止 Tomcat 启动。有关 Web 应用程序上下文文件的更多信息，请参阅[tomcat::context](create-custom-configure.md#create-custom-configure-context)。
   + [将一个 MySQL 驱动程序添加](workingapps-connectdb.md)到 Java App Server 层中。
   + [向您的堆栈注册 RDS 实例](workinglayers-db-rds.md#workinglayers-db-rds-register)。

   有关如何使用带有 OpsWorks 堆栈的 Amazon RDS 实例的更多信息，请参阅[Amazon RDS 服务层](workinglayers-db-rds.md)。

1. 将示例代码复制到名为 `simplejspdb.jsp` 的文件中，将该文件放到名为 `simplejspdb` 的文件夹中，然后创建该文件夹的 `.zip` 存档。名称是任意的；您可以按照您的意愿使用任何文件或文件夹名称。您还可以使用其他类型的存档，包括 gzip、bzip2 或 tarball。要部署多个 JSP 页面，将这些页面放到相同的存档中。有关如何部署其他存储库类型中的应用程序的信息，请参阅[应用程序源](workingapps-creating.md#workingapps-creating-source)。

1. 将该存档上传到 Amazon S3 存储桶，并将该文件设置为公有。复制该文件的 URL 以备后用。有关如何创建存储桶和上传文件的更多信息，请转至 [Amazon Simple Storage Service 入门指南](https://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html)。

1. [将一个应用程序添加](workingapps-creating.md#workingapps-creating-general)到堆栈并指定以下设置：
   + **名称** – `SimpleJSPDB`
   + **App type** - `Java`
   + **数据源类型** — **OpsWorks**（对于 MySQL 实例）或 **RDS**（对于 Amazon RDS 实例）。
   + **数据库实例** — 您之前创建的 MySQL 实例，通常命名为 **db-master1 (mysql)，或者命名为 (mysql)** 的 Amazon RDS 实例 ***DB\$1instance\$1name*(**mysql)。
   + **数据库名称** – `simplejspdb`。
   + **Repository type** – `Http Archive`
   + **Repository URL** -存档文件的 Amazon S3 URL。

   对其余设置使用默认值，然后单击 **Add App** 创建应用程序。

1. 将以下自定义 JSON 属性添加到堆栈配置属性，其中 simplejspdb 是应用程序的短名称。

   ```
   {
     "opsworks_java": {
       "datasources": {
         "simplejspdb": "jdbc/mydb" 
       }
     }
   }
   ```

   OpsWorks Stacks 使用此映射生成包含必要数据库信息的上下文文件。

   有关如何将自定义 JSON 属性添加到堆栈配置属性的更多信息，请参阅[使用自定义 JSON](workingstacks-json.md)。

1. [将应用程序部署](workingapps-deploying.md)到 Java App Server 实例。

现在，您可以使用应用程序的 URL 来查看应用程序。有关如何构建 URL 的介绍，请参阅[部署 JSP 应用程序](#layers-java-deploy-jsp)。

此示例中的 URL 将如下所示：`http://192.0.2.0/simplejspdb/simplejspdb.jsp`。

**注意**  
`datasources` 属性可以包含多个属性。每个属性都以应用程序短名称命名，并被设置为逻辑名称中适当的用户分配的部分。如果您有多个应用程序，您可以使用单独的逻辑名称，这需要一个类似于以下内容的自定义 JSON。  

```
{
  "opsworks_java": {
    "datasources": {
      "myjavaapp": "jdbc/myappdb",
      "simplejsp": "jdbc/myjspdb",
      ...
    }
  }
}
```