์ด ํ์ด์ง์์๋ App Engine ํ์ค ํ๊ฒฝ์์ ์ง์๋๋ ์ต์ Java ๋ฒ์ ์ผ๋ก ๋ฒ๋ค ์๋น์ค๋ฅผ ์ค์นํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค. ์ฑ์ App Engine API JAR์ ํตํด ๋ฒ๋ค ์๋น์ค์ ์ก์ธ์คํ ์ ์์ต๋๋ค.
์์ํ๊ธฐ ์ ์
์ง์๋๋ ์ต์ Java ๋ฒ์ ์์ ํธ์ถํ ์ ์๋ ๊ธฐ์กด ๋ฒ๋ค ์๋น์ค API ๋ชฉ๋ก์ ์ฐธ์กฐํ์ธ์.
์ด ํ์ด์ง์์ ์ฑ์ ์ง์๋๋ Java ๋ฒ์ ์ ์คํํด์ผ ํฉ๋๋ค. 1์ธ๋ ๋ฐํ์์์ 2์ธ๋ ๋ฐํ์์ผ๋ก ์ฑ์ ๋ง์ด๊ทธ๋ ์ด์ ํ๋ ค๋ฉด Java 8์์ ์ต์ Java ๋ฐํ์์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์ ๊ณ ๋ ค์ฌํญ ์น์ ์ ์ฐธ๊ณ ํ์ธ์.
๊ธฐ์กด ๋ฒ๋ค ์๋น์ค๋ฅผ ์ฌ์ฉํ๊ณ ์๋ฐ 21๋ก ์ ๊ทธ๋ ์ด๋ํ๋ ค๋ ๊ฒฝ์ฐ ๊ตฌ์ฑ ์ต์ ์ ๋ํ ์์ธํ ๋ด์ฉ์ ๊ธฐ์กด ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ทธ๋ ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
App Engine API JAR ์ค์น
์ง์๋๋ ์ต์ Java ์ฑ์์ ๊ธฐ์กด ๋ฒ๋ค ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด app.yaml
ํ์ผ ๋์ appengine-web.xml
ํ์ผ์ ์ฌ์ฉํ์ฌ ์ฑ์ ๊ตฌ์ฑํด์ผ ํฉ๋๋ค.
๋ค์ ์์์์๋ EE10 ๋ฒ์ 21 ์ด์(๊ธฐ๋ณธ๊ฐ), EE8 ๋ฒ์ 21 ๋ฐ ๋ฒ์ 17 ์ดํ์ appengine-web.xml
์ ๊ตฌ์ฑ ์ค์ ์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ ์ค๋๋ค. ๊ธฐ๋ณธ ๊ตฌ์ฑ์์ ์ง์๋๋ ์ต์ ๋ฒ์ ์ ์ฌ์ฉํ๋ ค๋ฉด Jakarta
๋ค์์คํ์ด์ค๋ฅผ ํฌํจํ๋๋ก ์ ํ๋ฆฌ์ผ์ด์
์๋ธ๋ฆฟ ๋ฐ ์ข
์ ํญ๋ชฉ์ ์
๋ฐ์ดํธํด์ผ ํฉ๋๋ค. ๊ตฌ์ฑ ์ต์
์ ๋ํ ์์ธํ ๋ด์ฉ์ ๊ธฐ์กด ์ ํ๋ฆฌ์ผ์ด์
์
๊ทธ๋ ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
Java ๋ฒ์ ์ ๋ฐ๋ผ appengine-web.xml
ํ์ผ์ ๋ค์ ์ค์ ์ ์ถ๊ฐํฉ๋๋ค.
v21 ์ด์(EE10)
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java21</runtime> <!-- or another supported version -->
<app-engine-apis>true</app-engine-apis>
</appengine-web-app>
v21(EE8)
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java21</runtime>
<system-properties> <!-- run your apps on EE8 -->
<property name="appengine.use.EE8" value="true"/>
</system-properties>
<app-engine-apis>true</app-engine-apis>
</appengine-web-app>
v17 ์ดํ
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java17</runtime> <!-- or another supported version -->
<app-engine-apis>true</app-engine-apis>
</appengine-web-app>
๊ธฐ์กด ๋ฒ๋ค ์๋น์ค๋ฅผ ์ข
์ ํญ๋ชฉ์ผ๋ก ์ง์ ํ๋ ค๋ฉด pom.xml
ํ์ผ์ ๋ค์ ์ค์ ์ถ๊ฐํฉ๋๋ค.
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>2.0.31</version> <!-- or later-->
</dependency>
์ฑ์์ web.xml
ํ์ผ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ <app-engine-apis>
์์๋ฅผ ์ถ๊ฐํ๊ณ ์ด๋ฅผ true
๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
<app-engine-apis>true</app-engine-apis>
Java 21 ์ฑ์ ๋ฐฐํฌํ๋ ค๋ฉด ์ปดํ์ผ๋๊ณ ์คํ
์ด์ง๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์์ mvn appengine:deploy
๋ช
๋ น์ด ๋๋ gcloud app deploy ~/my_app/WEB-INF/appengine-web.xml
๋ช
๋ น์ด๋ฅผ ์คํํฉ๋๋ค.
Java 21์ ์ฌ์ฉ๋๋ ๊ธฐ๋ณธ ์ง์ ์
Java 21 ์ฑ์ ์น ์ฑ์ฉ JVM์ ์์ํ ๋ ์ถ๊ฐ ์ฌ์ฉ์ ๊ตฌ์ฑ์ ์ด์ฉํ ์ ์์ต๋๋ค.
JVM ๋ถํ
์ ์ฌ์ฉ๋๋ ๊ธฐ๋ณธ ์ง์
์ ์ App Engine ๋น๋ ํฉ์ผ๋ก ์์ฑ๋ฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก appengine-web.xml
ํ์ผ์์ ์ด ์ง์
์ ์ ์ ์ํ๋ ๊ฒ์ ๋์ผํฉ๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
java --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED -showversion -Xms32M -Xmx204M -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+PrintCommandLineFlags -Dclasspath.runtimebase=/base/java_runtime -Djava.class.path=/base/java_runtime/runtime-main.jar -Djava.library.path=/base/java_runtime: com/google/apphosting/runtime/JavaRuntimeMainWithDefaults --fixed_application_path=/workspace /base/java_runtime
๋ฉ๋ชจ๋ฆฌ ์ค์ ์ ์ธ์คํด์ค ์ ํ(F1, F2, F4) ๋ฐ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ณ์ฐ๋๋ฏ๋ก ์ด ๊ธฐ๋ณธ ์ง์ ์ ์ ๋ณ๊ฒฝํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED
๋ฅผ ์ฌ์ฉํ์ฌ ํ์ํ JDK API๋ฅผ ์ฝ๋๋ค.
์ง์ ์ ๊ธฐ๋ฅ
appengine-web.xml
๊ตฌ์ฑ ํ์ผ์ ์ถ๊ฐ๋ ์ฌ์ฉ์ ์ ์๋ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ 2์ธ๋ Java ๋ฒ์ ์ ์ง์
์ ์ ๋ง์ถค์ค์ ํ ์ ์์ต๋๋ค.
๋ค์ ํ์์๋ ๊ธฐ๋ฅ์ ์ฌ์ฉ ์ค์ /์ฌ์ฉ ์ค์ง/๊ตฌ์ฑํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ํ๊ฒฝ ๋ณ์์ ๊ธฐ๋ณธ๊ฐ์ด ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ์ ๊ธฐ๋ณธ๊ฐ์ ๋ํ๋ ๋๋ค.
ํ๊ฒฝ ๋ณ์ | ์ค๋ช | ์ ํ | ๊ธฐ๋ณธ๊ฐ |
---|---|---|---|
CPROF_ENABLE |
Stackdriver Profiler | ๋ถ์ธ | false |
GAE_MEMORY_MB |
์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ | ํฌ๊ธฐ | App Engine ๋๋ /proc/meminfo -400M์์ ์ค์ |
HEAP_SIZE_RATIO |
ํ์ฉ ๋ฉ๋ชจ๋ฆฌ | ํผ์ผํธ | 80 |
HEAP_SIZE_MB |
์ฌ์ฉ ๊ฐ๋ฅํ ํ | ํฌ๊ธฐ | ${GAE_MEMORY_MB} ์ ${HEAP_SIZE_RATIO} % |
JAVA_HEAP_OPTS |
JVM ํ ์ธ์ | JVM ์ธ์ | -Xms${HEAP_SIZE_MB}M -Xmx${HEAP_SIZE_MB}M |
JAVA_GC_OPTS |
JVM GC ์ธ์ | JVM ์ธ์ | -XX:+UseG1GC ๋ฐ ๊ตฌ์ฑ |
JAVA_USER_OPTS |
JVM ๊ธฐํ ์ธ์ | JVM ์ธ์ | |
JAVA_OPTS |
JVM ์ธ์ | JVM ์ธ์ | ์๋ ์ฐธ์กฐ |
JAVA_OPTS
๋ฅผ ๋ช
์์ ์ผ๋ก ์ค์ ํ์ง ์์ผ๋ฉด ๋ค์ ๊ธฐ๋ณธ๊ฐ์ด ์ ์ฉ๋ฉ๋๋ค.
JAVA_OPTS:=-showversion \
$JAVA_HEAP_OPTS \
$JAVA_GC_OPTS \
$JAVA_USER_OPTS
CPROF_ENABLE
์ด true์ด๋ฉด ๊ธฐ๋ณธ ์ง์
์ ์ด PROFILER_AGENT
๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐํฉ๋๋ค.
-agentpath:/opt/cprof/profiler_java_agent.so=--logtostderr
์๋ฅผ ๋ค์ด ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋์ -add-opens
ํ๋๊ทธ๊ฐ ๋ ํ์ํ๋ฉด appengine-web.xml
ํ์ผ์ ์ ์๋ JAVA_USER_OPTS
ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
<env-variables>
<env-var name="JAVA_USER_OPTS" value="--add-opens java.base/java.util=ALL-UNNAMED" />
</env-variables>
๋ง์ด๊ทธ๋ ์ด์ ๊ณ ๋ ค์ฌํญ
2์ธ๋ Java ๋ฐํ์์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ๋ ๊ทธ๋ฆฌ๊ณ ์ฑ์ ๊ธฐ์กด ๋ฒ๋ค ์๋น์ค๊ฐ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ์๋ ๋ค์ ๊ณ ๋ ค์ฌํญ์ ์ฃผ์ํด์ผ ํฉ๋๋ค.s:
- 2์ธ๋ Java ์ฑ์์ ๊ธฐ์กด ๋ฒ๋ค ์๋น์ค ๊ธฐ๋ฅ์ ํ ์คํธํ๋ ค๋ฉด ๋ก์ปฌ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
- Java 8 ๋ฐํ์๊ณผ ๋ฌ๋ฆฌ 2์ธ๋ Java ๋ฐํ์์๋ JVM์ด ์ธ์คํด์ค ๋ฉ๋ชจ๋ฆฌ์ ์ผ๋ถ๋ก ํฌํจ๋ฉ๋๋ค. ๋ก๊ทธ์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ จ ์ค๋ฅ๊ฐ ํ์๋๋ฉด
appengine-web.xml
ํ์ผ์์ ์ธ์คํด์ค ํด๋์ค ํฌ๊ธฐ๋ฅผ ๋๋ฆฌ๋ ๊ฒ์ด ์ข์ต๋๋ค. - 2์ธ๋ Java ๋ฐํ์์์ ์ฌ์ฉ ์ค์ ๋์ง ์์ API๋ฅผ ์ ํ๋ฆฌ์ผ์ด์
์์ ํธ์ถํ๋ ค๊ณ ํ๋ฉด
com.google.apphosting.api.ApiProxy$FeatureNotEnabledException
์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. - ๋ชจ๋ ์ฑ์ 2์ธ๋ Java ๋ฐํ์์์ ์ค๋ ๋ ์์ ์ผ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค. Java 8์์ ์ต์ Java ๋ฐํ์์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ ๋
app.yaml
๋๋appengine-web.xml
ํ์ผ์์threadsafe
์์๋ฅผ ์ญ์ ํด์ผ ํฉ๋๋ค.
์์(Datastore)
Datastore ๋ชจ๋(Datastore)์์ Firestore๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ Java 11์ฉ ๊ธฐ์กด ๋ฒ๋ค ์๋น์ค์ ๋ํ GitHub ์ฝ๋ ์ํ์ ์ฐธ์กฐํ์ธ์.