Java 部署選項
部署 Java 函式的做法有兩種:
- 來自來源。如要進一步瞭解這個主題,請參閱「部署 Cloud Functions」。
- 從預先封裝的 JAR 檔案。
從原始碼部署
函式的原始碼必須位於 Maven 專案的常用位置 (src/main/java)。本文件中的範例函式直接位於 src/main/java 中,.java 來源檔案中沒有套件宣告。對於非簡單的程式碼,您可能會引入套件。如果該套件是 com.example,則階層會如下所示:
myfunction/
├─ pom.xml
├─ src
├─main
├─ java
├─ com
├─ example
├─ MyFunction.java
請使用下列指令部署 HTTP 函式:
gcloud functions deploy $name --trigger-http --no-gen2 \
--entry-point $function_class --runtime java17
其中:
$name是任意的描述性名稱,會在部署後成為函式的名稱。$name只能包含英文字母、數字、底線和連字號。$function_class是類別的完整名稱 (例如com.example.MyFunction,如果您未使用套件,則為MyFunction)。
請使用下列指令部署事件驅動函式:
gcloud functions deploy $name --no-gen2 --entry-point $function_class \
--trigger-resource $resource_name \
--trigger-event $event_name \
--runtime java17
其中:
$name是任意描述性名稱,會在部署後成為函式的名稱。$function_class是類別的完整名稱 (例如com.example.MyFunction,如果您未使用套件,則為MyFunction)。$resource_name和$event_name是觸發函式的特定事件。支援的資源和事件範例包括 Google Cloud Pub/Sub 和 Google Cloud Storage。
從來源部署函式時,Google Cloud CLI 會將來源目錄 (以及其中的所有內容) 上傳至 Google Cloud 進行建構。為避免傳送不必要的檔案,您可以使用 .gcloudignore
file。編輯 .gcloudignore 檔案,忽略 .git 和 target/ 等常見目錄。例如,.gcloudignore 檔案可能包含下列內容:
.git
target
build
.idea
從 JAR 部署
您可以部署含有函式的預先建構 JAR。這項功能特別適用於您需要部署函式,而該函式會使用私人構件存放區的依附元件,且無法從 Google Cloud 的建構管道存取。JAR 可以是超級 JAR,其中包含函式類別及其所有依附元件類別,或是精簡 JAR,其中包含 META-INF/MANIFEST.MF 檔案中依附元件 JAR 的 Class-Path 項目。
建構及部署 Uber JAR
uber JAR 是包含函式類別及其所有依附元件的 JAR 檔案。您可以使用 Maven 和 Gradle 建構 uber JAR。如要部署 Uber JAR,該檔案必須是其目錄中唯一的 JAR 檔案,例如:
my-function-deployment/ ├─ my-function-with-all-dependencies.jar
您可以將檔案複製到這個目錄結構,也可以使用 Maven 和 Gradle 外掛程式產生正確的部署目錄。
Maven
使用 Maven Shade 外掛程式建構 uber JAR。使用 Shade 外掛程式設定 pom.xml:
<?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>
建構 uber JAR:
mvn package
然後使用下列指令進行部署:
gcloud functions deploy jar-example \
--entry-point=Example \
--no-gen2 \
--runtime=java17 \
--trigger-http \
--source=target/deployment
Gradle
使用 Gradle 的 Shadow 外掛程式。在 build.gradle 檔案中設定外掛程式:
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()
}
...
您現在可以使用 shadowJar 指令執行 Gradle:
gradle shadowJar
然後使用下列指令進行部署:
gcloud functions deploy jar-example \
--entry-point=Example \
--no-gen2 \
--runtime=java17 \
--trigger-http \
--source=build/libs
建構及部署含有外部依附元件的薄 JAR
您可以建構及部署精簡 JAR 檔案,而非 uber JAR。精簡 JAR 檔案是指只含有函式類別,而沒有在同一個 JAR 檔案中嵌入的依附元件的 JAR 檔案。由於部署作業仍需要依附元件,因此您需要按照下列方式進行設定:
- 依附元件必須位於要部署的 JAR 相關子目錄中。
- JAR 必須包含
META-INF/MANIFEST.MF檔案,其中包含Class-Path屬性,其值會列出必要的依附元件路徑。
舉例來說,您的 JAR 檔案 my-function.jar 包含 META-INF/MANIFEST.MF 檔案,而該檔案在 libs/ 目錄中含有 2 個依附元件 (以空格分隔的相對路徑清單):
Manifest-Version: 1.0
Class-Path: libs/dep1.jar libs/dep2.jar
部署目錄應包含主要函式 JAR 檔案,以及包含函式所依賴的兩個依附元件的子目錄:
function-deployment/
├─ my-function.jar
├─ libs
├─ dep1.jar
├─ dep2.jar
您可以使用 Maven 和 Gradle 建構精簡 JAR:
Maven
使用 Maven JAR 外掛程式,自動設定 MANIFEST.MF 與依附元件的路徑,然後使用 Maven 依附元件外掛程式複製依附元件。
<?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>
建構精簡 JAR:
mvn package
然後使用下列指令進行部署:
gcloud functions deploy jar-example \
--entry-point=Example \
--no-gen2 \
--runtime=java17 \
--trigger-http \
--source=target/deployment
Gradle
更新 build.gradle 專案檔案,新增可擷取依附元件的全新工作:
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
}
}