首页 > 解决方案 > Ktor App 部署到 AppEngine 时未调用 Main 方法

问题描述

问题

Ktor 应用程序的main方法在部署到 AppEngine 时不会被调用。应用程序的主要方法是基于Timer从 API 请求中检索内容并将该信息保存到客户端使用的 Firestore 数据库的逻辑。

此逻辑当前在将Jar部署到 AppEngine 时有效。但是,如果需要端点,使用Ktor实现这一点将节省部署时间并有助于将来证明后端服务。

预期的

一旦将应用程序部署到 AppEngine,就会调用Ktor 应用程序的main方法,类似于在 IntelliJ 中运行应用程序的 main 方法时的调用方式。

实际的

仅在调用应用程序的托管路由后才调用main方法。

IE:https://[yourProjectName].appspot.com

设置

主要方法

import io.ktor.application.Application
fun Application.main() {
    // App logic here.
}

构建.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>

标签: google-app-enginekotlinktor

解决方案


感谢Kotlin Slack上的 Gabriel Machado回答这个问题。

Gabriel 建议使用Cron Job而不是Timer Task ,因为基于缩放类型的Timer线程可能存在问题。


推荐阅读