在java 21运行时使用App Engine实例时如何连接云sql?

问题描述 投票:0回答:1

我有一个 java ee 8 应用程序,我已将其迁移到 jakarta 10 应用程序。我使用谷歌应用程序引擎标准服务器。我最近将其迁移到 java 17 运行时,它正在连接到云 sql 数据库,一切运行良好。这是我的 pom.xml 文件

   <?xml version="1.0" encoding="UTF-8"?>
   <project xmlns="http://maven.apache.org/POM/4.0.0"   
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.figjaminc</groupId>
<artifactId>XXXXX</artifactId>
<version>1.0</version>
<packaging>war</packaging>

<name>XXXX</name>

<properties>
    <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>libraries-bom</artifactId>
            <version>26.30.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.core</artifactId>
        <version>4.0.0</version>
    </dependency>

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>4.0.0</version>
    </dependency>

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa</artifactId>
        <version>4.0.0</version>
    </dependency>

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.json</artifactId>
        <version>4.0.0</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.16.1</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.16.1</version>
    </dependency>


    <dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-api-1.0-sdk</artifactId>
        <version>2.0.12</version>
        <type>jar</type>
    </dependency>

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>com.sendgrid</groupId>
        <artifactId>java-http-client</artifactId>
        <version>4.3.6</version>
        <type>jar</type>
    </dependency>
    <!-- https://mvnrepository.com/artifact/jakarta.platform/jakarta.jakartaee-api -->
    <dependency>
        <groupId>jakarta.platform</groupId>
        <artifactId>jakarta.jakartaee-api</artifactId>
        <version>10.0.0</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>3.1.5</version> <!-- Use the latest version available -->
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>3.1.5</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.inject</groupId>
        <artifactId>jersey-hk2</artifactId>
        <version>3.1.5</version> <!-- Use the latest version available -->
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.3.0</version>
    </dependency>

    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20231013</version>
    </dependency>


    <dependency> 
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.5</version>
    </dependency>
    
        
    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>google-cloud-core</artifactId>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/com.sendgrid/sendgrid-java -->
    <dependency>
        <groupId>com.sendgrid</groupId>
        <artifactId>sendgrid-java</artifactId>
        <version>4.7.2</version>
        <type>jar</type>
    </dependency>
    
    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>google-cloud-storage</artifactId>
    </dependency>

    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>google-cloud-tasks</artifactId>
    </dependency>


    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-csv -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-csv</artifactId>
        <version>1.9.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.google.cloud.sql/mysql-socket-factory-connector-j-8 -->
    <dependency>
        <groupId>com.google.cloud.sql</groupId>
        <artifactId>mysql-socket-factory-connector-j-8</artifactId>
        <version>1.17.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.30</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>





</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>2.2.0</version>
            <configuration>                    
                <promote>false</promote>
                 

                <projectId>XXXXX</projectId>
                <version>9</version>
         <!--                                     
               <projectId>XXXXX</projectId>
                <version>9</version>                            
                               -->              

               

            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>17</source>
                <target>17</target>
                <compilerArguments>
                    <endorseddirs>${endorsed.dir}</endorseddirs>
                </compilerArguments>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.3.2</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>

    </plugins>
</build>

这就是我设置 appengine-web.xml 的方式

    <?xml version="1.0" encoding="utf-8"?>
    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java21</runtime>
<app-engine-apis>true</app-engine-apis>
<sessions-enabled>true</sessions-enabled>
<staging>
    <enable-jar-classes>true</enable-jar-classes>
</staging>
<instance-class>F2</instance-class>

当我的应用程序启动时,我可以创建一个entityManagerFactory

         package com.figjaminc.startup;

      import com.google.cloud.ServiceOptions;
      import jakarta.persistence.Persistence;
      import jakarta.servlet.ServletContextEvent;
      import jakarta.servlet.ServletContextListener;
      import java.util.HashMap;
      import java.util.Map;
      import java.util.logging.Logger;

     public class WebAppStartStop implements ServletContextListener {

private static final String class_name = "WebAppStartStop";

private static final Logger LOGGER = Logger.getLogger(WebAppStartStop.class.getName());



@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {

    String startupReport = "";

    startupReport += initializeEntityManager();
    LOGGER.info("WebAppStartStop startup_report:" + startupReport);
}

private String initializeEntityManager() {
    String projectId = ServiceOptions.getDefaultProjectId();

    Map<String, String> persistenceMap = new HashMap<String, String>();

    //set sandbox credentials
    if (projectId.equals("xxx-sandbox")) {
        persistenceMap.put("jakarta.persistence.jdbc.url", "jdbc:mysql://google/xxxdb?cloudSqlInstance=xxx:us-central1:xxxdb3&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false");
        persistenceMap.put("jakarta.persistence.jdbc.user", "xxxuser");
        persistenceMap.put("jakarta.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");

    }//if
    else if (projectId.equals("xxx")) {//set live credentials
        persistenceMap.put("jakarta.persistence.jdbc.url", "jdbc:mysql://google/xxxlivedb?cloudSqlInstance=xxx:us-central1:xxxdblive&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false");//changed for new demo
        persistenceMap.put("jakarta.persistence.jdbc.user", "xxxliveuser");
        persistenceMap.put("jakarta.persistence.jdbc.driver", "com.mysql.jdbc.Driver");
    }//else
    else {
        persistenceMap.put("jakarta.persistence.jdbc.url", "jdbc:mysql://localhost:3306/xxxdb?zeroDateTimeBehavior=CONVERT_TO_NULL");
        persistenceMap.put("jakarta.persistence.jdbc.user", System.getenv("db_username"));
        persistenceMap.put("jakarta.persistence.jdbc.password", System.getenv("db_password"));
        persistenceMap.put("jakarta.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
    }//else

    CommonDbMethods.factory = Persistence.createEntityManagerFactory("com.xxx_xxx_war_1.0PU", persistenceMap);
    return "Entity Manager initialized";
}

@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {

    LOGGER.info("Shutting Down");
}
   }
  • 我尝试过的一个可行的方案是从 appengine-web.xml 中删除 app-engine-api 并且我的应用程序进行连接。但我需要它,因为没有它,会话就无法工作。
  • 使用我设置的当前配置,应用程序无法连接到数据库。
java google-app-engine jakarta-ee eclipselink google-cloud-sql
1个回答
0
投票

安全限制阻止使用 Java 21 的 App Engine 连接到 Cloud SQL。

有两种可能的解决方案:

  1. Cloud SQL Proxy with Public IP:根据官方指南设置Cloud SQL Proxy,并在您的应用程序中配置环境变量。

  2. 无服务器 VPC 访问:如果您的 Cloud SQL 实例有私有 IP,请按照文档使用无服务器 VPC 访问来设置 VPC 连接器。

注意:验证代码中的 Cloud SQL 连接详细信息。

您还可以查看此说明(从App Engine标准环境连接)确保遵循最佳实践

更新:

  1. 确保

    app-engine-apis
    中的
    true
    设置为
    appengine-web.xml

  2. 验证您的 Cloud SQL 实例是否具有公共 IP(可能是默认 IP)。

  3. 仔细检查代码中的连接详细信息(URL、用户名、密码)。

  4. mysql-socket-factory-connector-j-8
    依赖项保留在
    pom.xml
    中。

如果连接失败,请检查 App Engine 日志并尝试暂时禁用

app-engine-apis
以隔离冲突。

  • 从 App Engine 标准环境连接

    • 本指南介绍了您可以使用的各种连接选项(包括 Cloud SQL 代理),具体取决于您的 App Engine 配置(标准或灵活)和 Cloud SQL 实例设置(公共 IP 或私有 IP)。
  • Java运行环境

    • 本页描述了 App Engine 标准的 Java 运行时环境,以及支持的 Java 版本和限制。虽然它没有专门介绍 Cloud SQL 连接,但它为您提供了有关您正在工作的环境的背景信息。

虽然具有公共 IP Cloud SQL 的 App Engine 标准可能并不绝对需要 Cloud SQL 代理,但这些文档可以让您更好地了解连接选项和各种场景下需要考虑的因素。

© www.soinside.com 2019 - 2024. All rights reserved.