Ktor App 部署到 AppEngine 时未调用 Main 方法
Posted
技术标签:
【中文标题】Ktor App 部署到 AppEngine 时未调用 Main 方法【英文标题】:Ktor App's Main Method Not Called When Deployed to AppEngine 【发布时间】:2019-05-03 15:44:45 【问题描述】:问题
部署到 AppEngine 时,不会调用 Ktor 应用程序的 main 方法。应用程序的主要方法是基于 Timer 从 API 请求中检索内容并将该信息保存到客户端使用的 Firestore 数据库的逻辑。
当部署到 AppEngine 的 Jar 中时,此逻辑当前有效。但是,如果需要端点,使用 Ktor 实现这一点将节省部署时间并有助于未来验证后端服务。
预期
一旦将应用程序部署到 AppEngine,就会调用 Ktor 应用程序的 main 方法,类似于在 IntelliJ 中运行应用程序的 main 方法时的调用方式。
实际
main 方法仅在调用应用程序的托管路由后才被调用。
即:https://[yourProjectName].appspot.com
设置
主要方法
import io.ktor.application.Application
fun Application.main()
// App logic here.
build.gradle
buildscript
ext.kotlin_version = '1.3.10'
ext.ktor_version = '1.0.0'
ext.appengine_version = '1.9.60'
ext.appengine_plugin_version = '1.3.4'
ext.junitJupiterVersion = '5.0.3'
repositories
jcenter()
mavenCentral()
dependencies
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.cloud.tools:appengine-gradle-plugin:$appengine_plugin_version"
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.3'
plugins
id 'org.jetbrains.kotlin.jvm' version '1.2.51'
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'war'
apply plugin: 'com.google.cloud.tools.appengine'
sourceSets
main.kotlin.srcDirs = [ 'src/main/kotlin' ]
sourceCompatibility = 1.8
repositories
jcenter()
mavenCentral()
maven url "https://kotlin.bintray.com/ktor"
dependencies
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "io.ktor:ktor-server-servlet:$ktor_version"
implementation "io.ktor:ktor-html-builder:$ktor_version"
providedCompile "com.google.appengine:appengine:$appengine_version"
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
implementation 'io.reactivex.rxjava2:rxjava:2.1.1'
implementation 'com.google.firebase:firebase-admin:6.3.0'
implementation 'com.google.apis:google-api-services-youtube:v3-rev204-1.23.0'
testCompile group: 'junit', name: 'junit', version: '4.12'
// JUnit Jupiter API and TestEngine implementation
testCompile("org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion")
testRuntime("org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion")
testCompile("org.assertj:assertj-core:3.10.0")
// To avoid compiler warnings about @API annotations in JUnit code
testCompileOnly('org.apiguardian:apiguardian-api:1.0.0')
kotlin.experimental.coroutines = 'enable'
compileKotlin
kotlinOptions.jvmTarget = "1.8"
compileTestKotlin
kotlinOptions.jvmTarget = "1.8"
task run(dependsOn: appengineRun)
appengine
deploy
version = 'media-staging-1201181257pm'
src/main/resources/application.conf
ktor
application
modules = [ InitializationKt.main ]
src/main/webapp/WEB-INF/
appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<threadsafe>true</threadsafe>
<runtime>java8</runtime>
</appengine-web-app>
web.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<servlet>
<display-name>KtorServlet</display-name>
<servlet-name>KtorServlet</servlet-name>
<servlet-class>io.ktor.server.servlet.ServletApplicationEngine</servlet-class>
<!-- path to application.conf file, required -->
<init-param>
<param-name>io.ktor.config</param-name>
<param-value>application.conf</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>KtorServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
【问题讨论】:
【参考方案1】:感谢Kotlin Slack 上的 Gabriel Machado 回答这个问题。
Gabriel 建议使用Cron Job 而不是Timer Task,因为基于scaling type 的Timer 线程可能存在问题。
【讨论】:
跟进问题,How to Run Cron Jobs in Kotlin Ktor?【参考方案2】:GAE 可能希望您的应用看起来像 Java 应用(例如,Java 风格的“main”,而不是 Kotlin 风格的“main”)。 有关如何执行此操作的更多信息,请查看此内容:How to run Kotlin class from the command line?
【讨论】:
以上是关于Ktor App 部署到 AppEngine 时未调用 Main 方法的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Google App Engine 上部署 Ktor 应用程序?
Firebase 身份验证不适用于 AppEngine 上的 Ktor 应用程序
CSS 文件在部署时未更新(Google AppEngine)
在 App Engine 上运行 Kotlin Ktor 应用程序时出错