google-app-engine - 部署到 AppEngine 时未调用 Ktor 应用程序的 Main 方法

标签 google-app-engine kotlin ktor

问题

部署到 AppEngine 时,不会调用 Ktor 应用程序的 ma​​in 方法。应用程序的主要方法中的逻辑是根据计时器从 API 请求中检索内容,并将该信息保存到客户端使用的 Firestore 数据库中。

此逻辑目前在部署到 AppEngine 的 Jar 中时有效。但是,使用 Ktor 实现这一点将节省部署时间,并有助于在需要端点时对后端服务进行 future 验证。

预期

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

实际

仅在调用应用的托管路由后才会调用 ma​​in 方法。

即: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>

最佳答案

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

Gabriel 建议使用 Cron Job计时器任务相反,因为基于scaling type计时器线程可能存在问题。 。

关于google-app-engine - 部署到 AppEngine 时未调用 Ktor 应用程序的 Main 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53575270/

相关文章:

kotlin - 函数是否需要可变数量的类型的args和具有相同数量的类型的args的闭包?

eclipse - GAE+Objectify - 不支持参数化类型 com.googlecode.objectify.Ref

java - 您会在 App Engine 中使用 "Future"做什么?

google-app-engine - 将应用引擎接口(interface)的上传大小限制到云存储

javascript - 服务器错误直接使用 Javascript 发布 MIME Multipart 数据

kotlin - 使用 Ktor 的 HTML 生成器时,如何将部分代码提取到 Kotlin 中的局部变量中?

带条件的 Kotlin 复制函数

java - 为什么 WebhookResponse 构建器在 json 中创建错误的 key ?

kotlin - 如果路由参数无效,则捕获 Ktor 位置中的异常

kotlin - Ktor - 使用协程发布未处理的错误