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 \
--entry-point $function_class --runtime java21
각 항목의 의미는 다음과 같습니다.
$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 java21
각 항목의 의미는 다음과 같습니다.
$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 \
--runtime=java21 \
--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 \
--runtime=java21 \
--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 \
--runtime=java21 \
--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 } }