Java 배포 옵션
자바 함수를 배포하는 데는 2가지 방법이 있습니다.
- 소스에서 배포 이 주제에 관한 일반적인 설명은 Cloud 함수 배포를 참고하세요.
- 사전 패키징된 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 파일을 사용하면 됩니다. .gcloudignore 파일을 수정하여 .git 및 target/과 같은 일반 디렉터리를 무시합니다. 예를 들어 .gcloudignore 파일에 다음이 포함될 수 있습니다.
.git
target
build
.idea
JAR에서 배포
함수가 포함된 사전 빌드된 JAR을 배포할 수 있습니다. 이는 소스에서 빌드할 때 Google Cloud의 빌드 파이프라인에서 액세스할 수 없는 비공개 아티팩트 스토리지의 종속 항목을 사용하는 함수를 배포해야 하는 경우에 유용합니다. JAR은 함수 클래스와 모든 종속 항목 클래스를 포함하는 Uber JAR이거나 META-INF/MANIFEST.MF 파일에 종속 항목 JAR에 대한 Class-Path 항목이 있는 씬 JAR일 수 있습니다.
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 빌드 및 배포
Uber JAR이 아닌 씬 JAR 파일을 빌드하고 배포할 수 있습니다. 씬 JAR은 동일한 JAR 파일에 삽입된 종속 항목 없이 함수 클래스만 포함된 JAR 파일입니다. 배포에는 여전히 종속 항목이 필요하므로 다음과 같이 설정해야 합니다.
- 배포할 JAR보다 한 수준 낮은 하위 디렉터리에 종속 항목이 있어야 합니다.
- JAR에는 값에 필수 종속 항목 경로가 나열된
Class-Path속성이 포함된META-INF/MANIFEST.MF파일이 있어야 합니다.
예를 들어 JAR 파일 my-function.jar에는 libs/ 디렉터리에 2개의 종속 항목이 있는 META-INF/MANIFEST.MF 파일이 있습니다(공백으로 구분된 상대 경로 목록).
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
}
}