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 } }