你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Azure 应用服务中为 Tomcat、JBoss 或 Java SE 应用配置数据源

本文介绍如何在应用服务中配置 Java SE、Tomcat 或 JBoss 应用中的数据源。

Azure 应用服务在完全托管服务上以三种类型运行 Java Web 应用程序:

  • Java Standard Edition (SE)。 Java SE 可以运行部署为 Java 存档(JAR)包的应用,其中包含嵌入式服务器,例如 Spring Boot、Quarkus、Dropwizard 或具有嵌入式 Tomcat 或 Jetty 服务器的应用。
  • Tomcat。 内置的 Tomcat 服务器可以运行部署为 Web 应用程序存档 (WAR) 包的应用。
  • JBoss Enterprise 应用程序平台(EAP):内置的 JBoss EAP 服务器可以运行部署为 WAR 或企业存档(EAR)包的应用。 在一组定价层(包括免费、高级 v3 和独立 v2)中,Linux 应用支持此选项。

注释

应用服务上的 JBoss EAP 现在支持自带许可证(BYOL)计费。 BYOL 使现有 Red Hat 订阅的客户能够将这些许可证直接应用到 Azure 应用服务上的 JBoss EAP 部署。 有关详细信息,请参阅 JBoss EAP 应用服务的 BYOL 支持

配置数据源

若要连接 Spring Boot 中的数据源,我们建议创建连接字符串并将它们注入 application.properties 文件中。

  1. 在“应用服务”页的左窗格中,选择 “设置>环境变量”。 在 “连接字符串 ”选项卡上,选择“ 添加”。 设置字符串 的名称 ,将 JDBC 连接字符串粘贴到 “值 ”字段中,并将 类型 设置为 “自定义”。 可以将连接字符串可选地设置为插槽设置。

    应用程序可以将连接字符串作为名为 CUSTOMCONNSTR_<your-string-name> 的环境变量来访问。 例如 CUSTOMCONNSTR_exampledb

  2. application.properties 文件中,使用环境变量名称引用连接字符串。 对于前面的示例,你将使用此代码:

    app.datasource.url=${CUSTOMCONNSTR_exampledb}
    

有关详细信息,请参阅有关数据访问和外部化配置的Spring Boot 文档

提示

如果将环境变量设置为 WEBSITE_AUTOCONFIGURE_DATABASEtrue,Linux Tomcat 容器可以在 Tomcat 服务器中自动配置共享数据源。 唯一要做的就是将包含有效 JDBC 连接字符串的应用设置添加到 Oracle、SQL Server、PostgreSQL 或 MySQL 数据库(包括连接凭据)。 应用服务使用容器中可用的相应驱动程序自动将相应的共享数据库添加到 /usr/local/tomcat/conf/context.xml。 有关使用此方法的端到端方案,请参阅 教程:使用 Linux 和 MySQL 上的 Azure 应用服务构建 Tomcat Web 应用

这些说明适用于所有数据库连接。 需要将占位符替换为所选数据库的驱动程序类名称和 JAR 文件。 下表提供常见数据库的类名和驱动程序下载。

数据库 驱动程序类名称 JDBC 驱动程序
PostgreSQL org.postgresql.Driver 下载
MySQL com.mysql.jdbc.Driver 下载 (选择 平台独立。)
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver 下载

若要将 Tomcat 配置为使用 Java 数据库连接(JDBC)或 Java 持久性 API (JPA),请先自定义 CATALINA_OPTS 启动时 Tomcat 读取的环境变量。 在 应用服务 Maven 插件中使用应用设置设置此值:

<appSettings>
    <property>
        <name>CATALINA_OPTS</name>
        <value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
    </property>
</appSettings>

或在 Azure 门户中“设置环境变量”页的“>”选项卡上设置环境变量

接下来,确定数据源是否适用于一个应用程序或 Tomcat servlet 上运行的所有应用程序。

应用程序级的数据源

若要配置应用程序级数据源,请执行以下作:

  1. 在项目的 META-INF/ 目录中创建一个 context.xml 文件。 如果没有 META-INF/ 目录,请创建一个。

  2. context.xml 中,添加一个 Context 元素以将数据源链接到 JNDI 地址。 将 driverClassName 占位符替换为本文前面显示的表中驱动程序的类名。

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. 更新应用程序的 web.xml 以便在应用程序中使用该数据源。

    <resource-env-ref>
        <resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
    </resource-env-ref>
    

共享的服务器级资源

提示

Linux Tomcat 容器可以通过对复制到 /home/site/wwwroot的文件使用以下约定自动应用 XSLT 文件:如果 server.xml.xslserver.xml.xslt 存在,这些文件将应用于 Tomcat 的文件 server.xml。 如果 context.xml.xsl 存在或 context.xml.xslt 存在,这些文件将应用于 Tomcat 的 context.xml

添加共享的服务器级数据源需要编辑 Tomcat 的 server.xml。 由于目录外部 /home 的文件更改是临时的,因此需要以编程方式应用 Tomcat 配置文件的更改,如下所示:

  • 上传启动脚本,并在“设置配置”>中设置脚本的路径。“堆栈设置 ”选项卡上,在 “启动”命令 框中添加路径。 可以使用 FTP 上传启动脚本。

启动脚本将 XSL 转换server.xml 该文件,并将生成的 XML 文件输出到 /usr/local/tomcat/conf/server.xml。 启动脚本应安装 libxslt ,或者 xlstproc,具体取决于 Web 应用的 Tomcat 版本的分发 ,如以下示例脚本中的注释中所述。 可以使用 FTP 上传 XSL 文件和启动脚本。

# Install the libxslt package on Alpine-based images:
apk add --update libxslt

# Install the xsltproc package on Debian or Ubuntu-based images:
apt install xsltproc

# Also copy the transform file to /home/tomcat/conf/
# Usage: xsltproc --output output.xml style.xsl input.xml
xsltproc --output /home/tomcat/conf/server.xml /home/tomcat/conf/transform.xsl /usr/local/tomcat/conf/server.xml

以下示例 XSL 文件向 Tomcat server.xml 添加了一个新的连接器节点。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()" name="Copy">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@* | node()" mode="insertConnector">
    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template match="comment()[not(../Connector[@scheme = 'https']) and
                                 contains(., '&lt;Connector') and
                                 (contains(., 'scheme=&quot;https&quot;') or
                                  contains(., &quot;scheme='https'&quot;))]">
    <xsl:value-of select="." disable-output-escaping="yes" />
  </xsl:template>

  <xsl:template match="Service[not(Connector[@scheme = 'https'] or
                                   comment()[contains(., '&lt;Connector') and
                                             (contains(., 'scheme=&quot;https&quot;') or
                                              contains(., &quot;scheme='https'&quot;))]
                                  )]
                      ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" mode="insertConnector" />
    </xsl:copy>
  </xsl:template>

  <!-- Add the new connector after the last existing connector if there is one -->
  <xsl:template match="Connector[last()]" mode="insertConnector">
    <xsl:call-template name="Copy" />

    <xsl:call-template name="AddConnector" />
  </xsl:template>

  <!-- ... or before the first engine if there's no existing connector -->
  <xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
                mode="insertConnector">
    <xsl:call-template name="AddConnector" />

    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template name="AddConnector">
    <!-- Add new line -->
    <xsl:text>&#xa;</xsl:text>
    <!-- This is the new connector -->
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
               maxThreads="150" scheme="https" secure="true" 
               keystoreFile="${{user.home}}/.keystore" keystorePass="changeit"
               clientAuth="false" sslProtocol="TLS" />
  </xsl:template>

</xsl:stylesheet>

完成配置

最后,将驱动程序 JAR 放置在 Tomcat 类路径中并重启应用服务应用。

  • 将 JDBC 驱动程序文件放入 /home/site/lib 目录,确保它们可供 Tomcat 类加载器使用。 在 Cloud Shell 中,为每个驱动程序 JAR 运行 az webapp deploy --type=lib
az webapp deploy --resource-group <group-name> --name <app-name> --src-path <jar-name>.jar --type=lib --path <jar-name>.jar

如果你创建了服务器级数据源,请重启应用服务 Linux 应用程序。 Tomcat 会将 CATALINA_BASE 重置为 /home/tomcat 并使用更新的配置。

提示

默认情况下,Linux JBoss 容器可以在 JBoss 服务器中自动配置共享数据源。 唯一需要执行的操作是将包含有效 JDBC 连接字符串的应用设置添加到 Oracle、SQL Server、PostgreSQL 或 MySQL 数据库(包括连接凭据),并添加具有该值WEBSITE_AUTOCONFIGURE_DATABASE的应用设置/环境变量true。 还支持使用服务连接器创建的 JDBC 连接。 应用服务使用容器中可用的适当驱动程序自动添加相应的共享数据源(基于应用设置名称和后缀 _DS)。 有关使用此方法的端到端方案,请参阅 教程:使用 Linux 和 MySQL 上的 Azure 应用服务生成 JBoss Web 应用

使用 JBoss EAP 注册数据源有三个主要步骤:

  1. 上传 JDBC 驱动程序。
  2. 将 JDBC 驱动程序添加为模块。
  3. 使用模块添加数据源。

应用服务是无状态托管服务,因此,每次 JBoss 容器启动时,都需要将这些步骤放入启动脚本中并运行它。 下面是 PostgreSQL、MySQL 和 Azure SQL 数据库示例:

注释

应用服务上的 JBoss EAP 支持自带许可证(BYOL)计费。 BYOL 使现有 Red Hat 订阅的客户能够将这些许可证直接应用到 Azure 应用服务上的 JBoss EAP 部署。 有关详细信息,请参阅 BYOL 对 JBoss EAP 的支持

  1. 将 JBoss CLI 命令放入名为“jboss-cli-commands.cli”的文件中。 JBoss 命令必须添加模块,并将其注册为数据源。 以下示例演示了用于创建 JNDI 名称为 java:jboss/datasources/postgresDS 的 PostgreSQL 数据源的 JBoss CLI 命令。

    module add --name=org.postgresql --resources=/home/site/libs/postgresql-42.7.4.jar
    /subsystem=datasources/jdbc-driver=postgresql:add(driver-name="postgresql",driver-module-name="org.postgresql",driver-class-name="org.postgresql.Driver",driver-xa-datasource-class-name="org.postgresql.xa.PGXADataSource")
    data-source add --name=postgresql --driver-name="postgresql" --jndi-name="java:jboss/datasources/postgresDS" --connection-url="jdbc:postgresql://\${env.DB_HOST}:5432/postgres" --user-name="\${env.DB_USERNAME}" --password="\${env.DB_PASSWORD}" --enabled=true --use-java-context=true
    

    请注意,该 module add 命令使用了三个环境变量(DB_HOSTDB_USERNAMEDB_PASSWORD),在应用服务中,必须将其添加为应用设置。 该脚本在没有 --resolve-parameter-values 标志的情况下添加它们,以便 JBoss 不会以纯文本形式保存其值。

  2. 创建调用 JBoss CLI 命令的启动脚本 startup.sh。 以下示例演示如何调用 jboss-cli-commands.cli 文件。 稍后,将应用服务配置为在容器启动时运行此脚本。

    $JBOSS_HOME/bin/jboss-cli.sh --connect --file=/home/site/scripts/jboss-cli-commands.cli
    
  3. 使用所选的部署选项,将 JDBC 驱动程序、jboss-cli-commands.cli 和 startup.sh 上传到相应脚本中指定的路径。 将 startup.sh 作为启动文件上传。 例如:

    export RESOURCE_GROUP_NAME=<resource-group-name>
    export APP_NAME=<app-name>
    
    # The lib type uploads to /home/site/libs by default.
    az webapp deploy --resource-group $RESOURCE_GROUP_NAME --name $APP_NAME --src-path postgresql-42.7.4.jar --target-path postgresql-42.7.4.jar --type lib
    az webapp deploy --resource-group $RESOURCE_GROUP_NAME --name $APP_NAME --src-path jboss-cli-commands.cli --target-path /home/site/scripts/jboss-cli-commands.cli --type static
    # The startup type uploads to /home/site/scripts/startup.sh by default.
    az webapp deploy --resource-group $RESOURCE_GROUP_NAME --name $APP_NAME --src-path startup.sh --type startup
    

    有关详细信息,请参阅将文件部署到应用程序服务

若要确认数据源已添加到 JBoss 服务器,请通过 SSH 连接到 Web 应用并运行 $JBOSS_HOME/bin/jboss-cli.sh --connect。 连接到 JBoss 后,运行 /subsystem=datasources:read-resource 以打印数据源的列表。

根据 jboss-cli-commands.cli 中的定义,可以使用 JNDI 名称 java:jboss/datasources/postgresDS访问 PostgreSQL 连接。