Spring Boot REST on Google App Engine throws 502

2k Views Asked by At

I have been struggling with this for about a week and nothing I have seen on SO has worked for me. I have a REST API built on Spring Boot that I am trying to deploy to the Google App Engine. Running locally is fine and when I run it on the GAE emulator it works fine as well; however, once I deploy using mvn appengine:deploy I get a successful build but when trying the endpoints I only get a 502. I'm not sure where the logs are so this is really kicking my butt.

My 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.mycompany.admin</groupId>
  <artifactId>admin-api</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <!-- Exclude this for deployment only -->
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </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>
    </dependency>

    <!-- other project dependencies -->
    <dependency>
        <groupId>com.google.firebase</groupId>
        <artifactId>firebase-admin</artifactId>
        <version>5.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.10.2</version>
    </dependency>
    <!-- end other project specific dependencies -->

    <!-- Dependencies provided during deployment -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jul-to-slf4j</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <!-- End dependencies for deployment -->

    <!-- Dependencies for local -->
    <!--        <dependency> -->
    <!--            <groupId>org.springframework.boot</groupId> -->
    <!--            <artifactId>spring-boot-starter-tomcat</artifactId> -->
    <!--            <scope>provided</scope> -->
    <!--        </dependency> -->
    <!-- End dependencies for local -->
  </dependencies>

  <build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>1.3.1</version>
            <configuration>
                <project>project-id-from-GAE-here</project
            </configuration>
        </plugin>
    </plugins>
  </build>
</project>

My application class is a simple annotated @SpringBootApplication class. I have 2 controllers with annotation of @RestController and simple @RequestMapping methods. One of the REST controllers is for the /_ah/health endpoint that returns 200 since one post mentioned constant restarts being triggered by the lack of a healthcheck endpoint.

I have a simple application.yml for my value injections and created an app.yaml file placed in src/main/appengine

runtime: java
env: flexible
threadsafe: true
manual_scaling:
  instances: 1
handlers:
- url: /.*
  script: this field is required, but ignored
runtime_config:
  jdk: openjdk8

I am at a complete loss on this. It is my first GAE deployment with hopefully more to go. (I also am not using Docker yet since I am on a Windows 10 machine that breaks when I load Docker on it.)

UPDATE I did notice that I had forgotten to put my project id under the maven plugin. Once I did that I got errors about not finding the app.yaml. I realized that since I am using a flexible environment, I did not need the appengine-web.xml and I had my file misnamed as app.yml rather than app.yaml. I updated my question with this and I am still getting a 502 after a successful deployment.

1

There are 1 best solutions below

1
On BEST ANSWER

I realized my trial period with GAE included tech support so I contacted them. The asked for my pom and app.yaml. Their response was to add the following to my app.yaml "Since Java is known for consuming high memory usage, there is an overhead process consumed more than the approximate 0.4GB value"

resources:
  cpu: 2
  memory_gb: 2.3
  disk_size_gb: 10
  volumes:
  - name: ramdisk1
    volume_type: tmpfs
    size_gb: 0.5

They also provided this link for reference: https://cloud.google.com/appengine/docs/flexible/java/configuring-your-app-with-app-yaml#resource-settings

Once I did this, my application started working just fine.

EDIT

If you have a simple application, set cpu:1 since you get billed on CPU hours and your daily quota is 28 and with 2 CPUs you end up with 48 CPU hours. I burned through the free $300 credit in 1 month because their tutorials setup a RDB ($80) that doesn't get used and doesn't show to kill the project. Also make sure when deploying something new you delete the old versions or you will be charged for every version that is up.