Opsi Deployment Java

Anda memiliki dua pilihan untuk men-deploy fungsi Java:

Men-deploy dari sumber

Kode sumber fungsi Anda harus berada di tempat biasa untuk project Maven (src/main/java). Fungsi contoh dalam dokumen ini berada langsung di src/main/java, tanpa deklarasi paket di file sumber .java. Untuk kode yang tidak sederhana, Anda mungkin ingin menggunakan paket. Jika paket tersebut adalah com.example, hierarki Anda akan terlihat seperti ini:

myfunction/
├─ pom.xml
├─ src
    ├─main
        ├─ java
            ├─ com
                ├─ example
                    ├─ MyFunction.java

Gunakan perintah berikut untuk men-deploy fungsi HTTP:

gcloud functions deploy $name --trigger-http --no-gen2 \
    --entry-point $function_class --runtime java17

Dengan:

  • $name sebagai nama deskriptif arbitrer yang akan menjadi nama fungsi setelah di-deploy. $name hanya boleh berisi huruf, angka, garis bawah, dan tanda hubung.
  • $function_class sebagai nama class Anda yang sepenuhnya memenuhi syarat (misalnya, com.example.MyFunction atau hanya MyFunction jika Anda tidak menggunakan paket).

Gunakan perintah berikut untuk men-deploy fungsi berbasis peristiwa:

gcloud functions deploy $name --no-gen2 --entry-point $function_class \
    --trigger-resource $resource_name \
    --trigger-event $event_name \
    --runtime java17

Dengan:

  • $name sebagai nama deskriptif arbitrer yang akan menjadi nama fungsi setelah di-deploy.
  • $function_class sebagai nama class Anda yang sepenuhnya memenuhi syarat (misalnya, com.example.MyFunction atau hanya MyFunction jika Anda tidak menggunakan paket).
  • $resource_name dan $event_name bersifat spesifik untuk peristiwa yang memicu fungsi Anda. Contoh resource dan peristiwa yang didukung adalah Google Cloud Pub/Sub dan Google Cloud Storage.

Saat men-deploy fungsi dari sumber, Google Cloud CLI mengupload direktori sumber (dan semua yang ada di dalamnya) ke Google Cloud untuk dibangun. Untuk menghindari pengiriman file yang tidak perlu, Anda dapat menggunakan file .gcloudignore. Edit file .gcloudignore untuk mengabaikan direktori umum seperti .git dan target/. Misalnya, file .gcloudignore mungkin berisi:

.git
target
build
.idea

Men-deploy dari JAR

Anda dapat men-deploy JAR bawaan yang berisi fungsi tersebut. Hal ini berguna terutama jika Anda perlu men-deploy fungsi yang menggunakan dependensi dari repositori artefak pribadi yang tidak dapat diakses dari pipeline build Google Cloud saat membangun dari sumber. JAR dapat berupa uber JAR yang berisi class fungsi dan semua class dependensinya, atau thin JAR yang memiliki entri Class-Path untuk JAR dependensi dalam file META-INF/MANIFEST.MF.

Membangun dan men-deploy Uber JAR

Uber JAR adalah file JAR yang berisi class fungsi serta semua dependensinya. Anda bisa membangun uber JAR dengan Maven dan Gradle. Untuk men-deploy Uber JAR, file tersebut harus menjadi satu-satunya file JAR di direktorinya sendiri, misalnya:

my-function-deployment/
 ├─ my-function-with-all-dependencies.jar

Anda dapat menyalin file ke struktur direktori ini, atau menggunakan plugin Maven dan Gradle untuk membuat direktori deployment yang benar.

Maven

Gunakan plugin Maven Shade untuk membangun uber JAR. Konfigurasikan pom.xml Anda dengan plugin Shade:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...
  <build>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals><goal>shade</goal></goals>
            <configuration>
              <outputFile>${project.build.directory}/deployment/${build.finalName}.jar</outputFile>
              <transformers>
                <!-- This may be needed if you need to shade a signed JAR -->
                <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                  <resource>.SF</resource>
                  <resource>.DSA</resource>
                  <resource>.RSA</resource>
                </transformer>
                <!-- This is needed if you have dependencies that use Service Loader. Most Google Cloud client libraries does. -->
                <transformer implementation=
       "org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Bangun uber JAR:

mvn package

Kemudian, deploy dengan perintah berikut:

gcloud functions deploy jar-example \
    --entry-point=Example \
    --no-gen2 \
    --runtime=java17 \
    --trigger-http \
    --source=target/deployment

Gradle

Gunakan plugin Shadow untuk Gradle. Siapkan plugin di file build.gradle Anda:

buildscript {
   repositories {
       jcenter()
   }
   dependencies {
       ...
       classpath "com.github.jengelman.gradle.plugins:shadow:5.2.0"
   }
}

plugins {
   id 'java'
   ...
}
sourceCompatibility = '17.0'
targetCompatibility = '17.0'
apply plugin: 'com.github.johnrengelman.shadow'

shadowJar {
   mergeServiceFiles()
}
...

Sekarang Anda dapat menjalankan Gradle dengan perintah shadowJar:

gradle shadowJar

Kemudian, deploy dengan perintah berikut:

gcloud functions deploy jar-example \
   --entry-point=Example \
   --no-gen2 \
   --runtime=java17 \
   --trigger-http \
   --source=build/libs

Membangun dan men-deploy thin JAR dengan dependensi eksternal

Anda bisa membangun dan men-deploy file thin JAR daripada uber JAR. Thin JAR adalah file JAR yang hanya berisi class fungsi tanpa dependensi yang disematkan dalam file JAR yang sama. Karena dependensi masih diperlukan untuk deployment, Anda perlu menyiapkan beberapa hal berikut:

  • Dependensi harus berada dalam subdirektori yang sesuai dengan JAR yang akan di-deploy.
  • JAR harus memiliki file META-INF/MANIFEST.MF yang menyertakan atribut Class-Path yang nilainya mencantumkan jalur dependensi yang diperlukan.

Misalnya, file JAR my-function.jar memiliki file META-INF/MANIFEST.MF yang memiliki 2 dependensi di direktori libs/ (daftar jalur relatif yang dipisahkan spasi):

Manifest-Version: 1.0
Class-Path: libs/dep1.jar libs/dep2.jar

Direktori deployment Anda selanjutnya harus berisi file JAR fungsi utama, serta subdirektori dengan dua dependensi yang menjadi dependensi fungsi Anda:

function-deployment/
├─ my-function.jar
├─ libs
       ├─ dep1.jar
       ├─ dep2.jar

Anda bisa membangun thin JAR dengan Maven dan Gradle:

Maven

Gunakan plugin Maven JAR untuk mengonfigurasi MANIFEST.MF secara otomatis dengan jalur ke dependensi, lalu gunakan plugin Maven Dependency untuk menyalin dependensi.

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...
  <build>
    ...
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>libs/</classpathPrefix>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <overWriteReleases>false</overWriteReleases>
              <includeScope>runtime</includeScope>
              <outputDirectory>${project.build.directory}/libs</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>package</phase>
            <goals><goal>copy-resources</goal></goals>
            <configuration>
              <outputDirectory>${project.build.directory}/deployment</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.build.directory}</directory>
                  <includes>
                    <include>${build.finalName}.jar</include>
                    <include>libs/**</include>
                  </includes>
                  <filtering>false</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Bangun thin JAR:

mvn package

Kemudian, deploy dengan perintah berikut:

gcloud functions deploy jar-example \
    --entry-point=Example \
    --no-gen2 \
    --runtime=java17 \
    --trigger-http \
    --source=target/deployment

Gradle

Perbarui file project build.gradle Anda untuk menambahkan tugas baru guna mengambil dependensi:

dependencies {
   // API available at compilation only, but provided at runtime
   compileOnly 'com.google.cloud.functions:functions-framework-api:1.0.1'
   // dependencies needed by the function
   // ...
}

jar {
 manifest {
   attributes(
     "Class-Path": provider {
         configurations.runtimeClasspath
           .collect { "libs/${it.name}" }.join(' ')
     }
   )
 }
}

task prepareDeployment(type: Copy) {
 into("${buildDir}/deployment")
 into('.') {
   from jar
 }
 into('libs') {
   from configurations.runtimeClasspath
 }
}