英文:
How to deploy a spring boot app in google cloud?
问题
你遇到的问题可能是部署到Google Cloud时的一些配置或命令问题。以下是可能有问题的一些方面:
-
在
pom.xml
中,确保appengine-maven-plugin
和spring-boot-maven-plugin
的版本与你的项目兼容。你可以尝试更新它们的版本。 -
在
appengine/app.yaml
中,确保runtime
配置正确。你可以尝试仅使用runtime: java11
来看是否解决问题。 -
确保你的Google Cloud SDK 已正确安装和配置,并且已登录到你的 Google 帐户。
-
检查你的应用程序是否有足够的权限来进行部署操作。
-
检查你的项目设置,确保已正确选择了项目和用户。
-
尝试运行
mvn clean package appengine:deploy -e
来获取更详细的错误信息,这可能会帮助你找到问题所在。
如果以上步骤没有解决问题,你可能需要查看详细的错误日志或尝试与Google Cloud社区或支持团队联系以获取更多帮助。
英文:
I'm trying to deploy a Java Spring Boot app to Google Cloud and I have some problems.
I tried two methods:
- https://cloud.google.com/appengine/docs/flexible/java/quickstart
- https://www.baeldung.com/spring-boot-google-app-engine
This is the error i get with the first deployment method (gcloud app deploy):
ERROR: gcloud crashed (KeyError): None
This is the error i get with the second deployment method (maven deploy):
Failed to execute goal com.google.cloud.tools:appengine-maven-plugin:1.3.2:deploy (default-cli) on project server: Execution default-cli of goal com.google.cloud.tools:appengine-maven-plugin:1.3.2:deploy failed: Non zero exit: 1
I feel like I missed some deployment step - i don't know which though.
What I'm doing is:
- Create project from console.cloud.google.com.
- Open Google SDK Shell.
- Go to folder.
- 'google init' to select the project and user.
- 'google app create'.
- 'google app deploy' / deploy from maven with 'mvn clean package appengine:deploy -P cloud-gcp' or 'mvn clean -DskipTests appengine:deploy'.
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>server</groupId>
<artifactId>server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server</name>
<description>Description</description>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<servlet.version>4.0.0</servlet.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.9.60</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.10.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.10.5</version>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.humble/humble-video-all -->
<dependency>
<groupId>io.humble</groupId>
<artifactId>humble-video-all</artifactId>
<version>0.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.2</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
*db config*
spring.cloud.appId=*id*
spring.cloud.gcp.sql.instance-connection-name=*copied name from cloud*
spring.cloud.gcp.sql.database-name=*db name*
appengine/app.yaml
runtime: java11
env: flex
env_variables:
SPRING_PROFILES_ACTIVE: "gcp,mysql"
health_check:
enable_health_check: False
handlers:
- url: /.*
script: this field is required, but ignored
manual_scaling:
instances: 1
^ also tried only with:
runtime: java11
webapp/WEB-INF/appengine-web.xml
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<version>1</version>
<threadsafe>true</threadsafe>
<runtime>java11</runtime>
</appengine-web-app>
EDIT:
Running the maven deploy with the flag '-e' gave the following trace:
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.google.cloud.tools:appengine-maven-plugin:1.3.2:deploy (default-cli) on project server: Execution default-cli of goal com.g
oogle.cloud.tools:appengine-maven-plugin:1.3.2:deploy failed: Non zero exit: 1
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:566)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default-cli of goal com.google.cloud.tools:appengine-maven-plugin:1.3.2:deploy failed: Non zero exit: 1
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:566)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: com.google.cloud.tools.appengine.api.AppEngineException: Non zero exit: 1
at com.google.cloud.tools.appengine.cloudsdk.process.NonZeroExceptionExitListener.onExit (NonZeroExceptionExitListener.java:28)
at com.google.cloud.tools.appengine.cloudsdk.internal.process.DefaultProcessRunner.syncRun (DefaultProcessRunner.java:209)
at com.google.cloud.tools.appengine.cloudsdk.internal.process.DefaultProcessRunner.run (DefaultProcessRunner.java:137)
at com.google.cloud.tools.appengine.cloudsdk.CloudSdk.runGcloudCommand (CloudSdk.java:179)
at com.google.cloud.tools.appengine.cloudsdk.CloudSdk.runAppCommandInWorkingDirectory (CloudSdk.java:138)
at com.google.cloud.tools.appengine.cloudsdk.CloudSdkAppEngineDeployment.deploy (CloudSdkAppEngineDeployment.java:87)
at com.google.cloud.tools.maven.DeployMojo.execute (DeployMojo.java:107)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:566)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Does anyone have an idea what is wrong?
Thanks!
答案1
得分: 3
以下是您提供的代码部分的翻译:
-
GCP标准环境使用Jetty而不是Tomcat。
-
Google在插件的较新版本中已解决了
app.yaml
/appengine-web.xml
的问题。
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.3.0</version>
</plugin>
以及在您的<dependencyManagement/>
导入的末尾:
<!-- org.springframework.cloud:spring-cloud-gcp-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>1.2.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
并相应地在您的<dependencies/>
中利用更新的版本。
我建议您将应用程序打包到单独的JAR文件中,并在pom.xml
中包含依赖项,例如:
<dependency>
<groupId>GROUP</groupId>
<artifactId>ARTIFACT</artifactId>
<version>VERSION</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
其中GROUP:ARTIFACT:VERSION是您应用程序JAR的实际Maven坐标。
在WEB-INF
文件夹中,添加您的appengine-web.xml
(类似于以下内容):
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>GROUP</application>
<service>ARTIFACT</service>
<version>VERSION</version>
<runtime>java8</runtime>
<basic-scaling>
<max-instances>1</max-instances>
<idle-timeout>5m</idle-timeout>
</basic-scaling>
<instance-class>B1</instance-class>
<threadsafe>true</threadsafe>
<sessions-enabled>true</sessions-enabled>
<env-variables>
<env-var name="SPRING_PROFILES_ACTIVE" value="gcp,mysql"/>
</env-variables>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
其中GROUP、ARTIFACT和VERSION对应于您JAR的Maven artifact的groupId、artifactId和version。
更新插件后,我发现不再需要app.yaml
文件。您需要包含一个logging.properties
文件:
# 将所有记录器的默认记录级别设置为WARNING
.level = WARNING
最后,在POM中重新打包您的GROUP:ARTIFACT:VERSION JAR(请注意,${start-class}
必须为您的应用程序定义):
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>gcp</profile>
<profile>mysql</profile>
</profiles>
</configuration>
</plugin>
</plugins>
</build>
使用mvn clean package appengine:deploy
进行部署。此文章提供了更多详细信息。
英文:
There are a couple of challenges:
-
The GCP standard environment provides Jetty instead of Tomcat
-
Google has fixed the
app.yaml
/appengine-web.xml
issues in later versions of the plug-in
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.3.0</version>
</plugin>
and at the end of your <dependencyManagement/>
import:
<!-- org.springframework.cloud:spring-cloud-gcp-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>1.2.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
and take advantage of the updated versions in your <dependencies/>
accordingly.
I suggest you package your application in a separate JAR and include the dependency in your pom.xml
like:
<dependency>
<groupId>GROUP</groupId>
<artifactId>ARTIFACT</artifactId>
<version>VERSION</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Where GROUP:ARTIFACT:VERSION are your application JAR's actual Maven coordinates.
In the WEB-INF
folder, add your appengine-web.xml
(something like):
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>GROUP</application>
<service>ARTIFACT</service>
<version>VERSION</version>
<runtime>java8</runtime>
<basic-scaling>
<max-instances>1</max-instances>
<idle-timeout>5m</idle-timeout>
</basic-scaling>
<instance-class>B1</instance-class>
<threadsafe>true</threadsafe>
<sessions-enabled>true</sessions-enabled>
<env-variables>
<env-var name="SPRING_PROFILES_ACTIVE" value="gcp,mysql"/>
</env-variables>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
Where GROUP, ARTIFACT, and VERSION correspond to your JAR's Maven artifact groupId, artifactId, and version, respectively.
Once I updated the plug-in, I found I no longer needed to have an app.yaml
file. You'll need to include a logging.properties
:
# Set the default logging level for all loggers to WARNING
.level = WARNING
Finally, re-package your GROUP:ARTIFACT:VERSION jar in your POM (note that ${start-class}
must be defined for your application):
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>gcp</profile>
<profile>mysql</profile>
</profiles>
</configuration>
</plugin>
</plugins>
</build>
Use mvn clean package appengine:deploy
to deploy. This article has more details.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论