Configuring the Server

预计阅读时间:10分钟

Ktor在外部配置文件中使用HOCON(人类优化配置对象表示法)格式. 在此文件中,您可以配置诸如要侦听的端口或要加载的模块之类的内容 . 该格式类似于JSON,但经过优化后可以由人类读取和写入,并支持环境变量替换等其他功能. 在这种情况下,您可以配置要与mainClassName指向特定EngineMain一起使用的服务器引擎.

Ktor还采用了类型化的DSL(领域特定语言)一组的lambda表达式使用时,需要配置应用程序和服务器引擎embeddedServer .

从Ktor 1.0.0-beta-2开始, DevelopmentEngine类已重命名为EngineMain ,对于较旧的版本,只需重命名即可.

目录:

The HOCON file

这是配置Ktor应用程序的首选方法,因为它使您可以轻松更改配置而无需重新编译应用程序.

当使用EngineMain启动Ktor或通过调用commandLineEnvironment启动Ktor时,它将尝试从应用程序资源中加载一个名为application.conf的HOCON文件. 您可以使用命令行参数来更改文件的位置.

您可以用作mainClassName可用开发引擎:

  • io.ktor.server.cio.EngineMain
  • io.ktor.server.tomcat.EngineMain
  • io.ktor.server.jetty.EngineMain
  • io.ktor.server.netty.EngineMain

Ktor仅要求您使用ktor.application.modules属性启动服务器时指定要加载的模块 . 所有其他属性都是可选的.

一个典型的,简单的Ktor HOCON文件( application.conf )如下所示:

ktor {
    deployment {
        port = 8080
    }

    application {
        modules = [ io.ktor.samples.metrics.MetricsApplicationKt.main ]
    }
}

Using dot notation it would be equivalent to:

ktor.deployment.port = 8080
ktor.application.modules = [ io.ktor.samples.metrics.MetricsApplicationKt.main ]

Ktor允许您配置更多:从其他核心配置到Ktor功能,甚至是应用程序的自定义配置:

ktor {
    deployment {
        environment = development
        port = 8080
        sslPort = 8443
        autoreload = true
        watch = [ httpbin ]
    }

    application {
        modules = [ io.ktor.samples.httpbin.HttpBinApplicationKt.main ]
    }

    security {
        ssl {
            keyStore = build/temporary.jks
            keyAlias = mykey
            keyStorePassword = changeit
            privateKeyPassword = changeit
        }
    }
}

jwt {
    domain = "https://jwt-provider-domain/"
    audience = "jwt-audience"
    realm = "ktor sample app"
}

youkube {
  session {
    cookie {
      key = 03e156f6058a13813816065
    }
  }
  upload {
    dir = ktor-samples/ktor-samples-youkube/.video
  }
}

本文档中列出了可用的核心配置 .

您可以使用HOCON 设置环境变量的属性 .

您可能需要安装HOCONIntelliJ插件 .

Command Line

使用commandLineEnvironment (任何EngineMain主组件)时,可以使用几个开关和配置参数来配置应用程序模块.

如果使用-config=anotherfile.conf从命令行启动应用程序,它将从特定的本地文件而不是从资源中加载配置文件.

使用开关,您可以例如通过执行以下操作来覆盖绑定的端口:

java -jar myapp-fatjar.jar -port=8080

本文档中有可用的命令行开关列表 .

Configuring the embeddedServer

EmbeddedServer是启动Ktor应用程序的简单方法. 您提供了自己的主要功能,而且更加明确,因此更容易理解确切发生的情况.

embeddedServer包含一个可选的参数configure ,该参数允许您设置第一个参数中指定的引擎的配置. 与所使用的引擎无关,您将具有一些可用的属性来配置:

embeddedServer(AnyEngine, configure = {
    // Size of the event group for accepting connections
    connectionGroupSize = parallelism / 2 + 1
    // Size of the event group for processing connections,
    // parsing messages and doing engine's internal work 
    workerGroupSize = parallelism / 2 + 1
    // Size of the event group for running application code 
    callGroupSize = parallelism 
}) {
    // ...
}.start(true)

Multiple connectors

可以使用applicationEngineEnvironment通过代码定义几个连接器.

applicationEngineEnvironment内部,您可以定义HTTP和HTTPS连接器:

定义HTTP连接器:

connector {
    host = "0.0.0.0"
    port = 9090
}

定义HTTPS连接器:

sslConnector(keyStore = keyStore, keyAlias = "mykey", keyStorePassword = { "changeit".toCharArray() }, privateKeyPassword = { "changeit".toCharArray() }) {
    port = 9091
    keyStorePath = keyStoreFile.absoluteFile
}

一个实际的例子:

fun main(args: Array<String>) {
    val env = applicationEngineEnvironment {
        module {
            main()
        }
        // Private API
        connector {
            host = "127.0.0.1"
            port = 9090
        }
        // Public API
        connector {
            host = "0.0.0.0"
            port = 8080
        }
    }
    embeddedServer(Netty, env).start(true)
}

该应用程序将处理所有连接. 您可以访问每个ApplicationCall的本地端口,因此可以根据本地端口决定要执行的操作:

fun Application.main() {
    routing {
        get("/") {
            if (call.request.local.port == 8080) {
                call.respondText("Connected to public api")
            } else {
                call.respondText("Connected to private api")
            }
        }
    }
}

您可以在ktor-samples / multiple-connectors中看到一个完整的示例.

Netty

使用Netty作为引擎时,除了常用属性外,还可以配置其他一些属性:

embeddedServer(Netty, configure = {
    // Size of the queue to store [ApplicationCall] instances that cannot be immediately processed
    requestQueueLimit = 16 
    // Do not create separate call event group and reuse worker group for processing calls
    shareWorkGroup = false 
    // User-provided function to configure Netty's [ServerBootstrap]
    configureBootstrap = {
        // ...
    } 
    // Timeout in seconds for sending responses to client
    responseWriteTimeoutSeconds = 10 
}) {
    // ...
}.start(true)

Jetty

使用Jetty作为引擎时,除了常用属性外,您还可以配置Jetty服务器.

embeddedServer(Jetty, configure = {
    // Property to provide a lambda that will be called during Jetty
    // server initialization with the server instance as an argument.
    configureServer = {
        // ...
    } 
}) {
    // ...
}.start(true)

CIO

使用CIO(协程I / O)作为引擎时,除了通用属性外,还可以配置connectionIdleTimeoutSeconds属性.

embeddedServer(CIO, configure = {
    // Number of seconds that the server will keep HTTP IDLE connections open.
    // A connection is IDLE if there are no active requests running.
    connectionIdleTimeoutSeconds = 45
}) {
    // ...
}.start(true)

Tomcat

使用Tomcat时,除了通用属性外,还可以配置Tomcat服务器.

embeddedServer(Tomcat, configure = {
    // Property to provide a lambda that will be called during Tomcat
    // server initialization with the server instance as argument.
    configureTomcat { // this: Tomcat ->
        // ...
    }
}) {
    // ...
}.start(true)

这些是为Ktor开发的官方引擎,但是也可以创建自己的引擎并为其提供自定义配置.

Available configuration parameters

Ktor提供了一系列可用的属性列表,您可以从命令行或HOCON文件中传递这些属性.

开关是指传递给应用程序的命令行参数,因此,例如,您可以通过以下方式更改绑定的端口:

java -jar myapp-fatjar.jar -port=8080

参数路径application.conf文件内部的路径:

ktor.deployment.port = 8080
ktor {
    deployment {
        port = 8080
    }
}

常规开关和参数:

Switch 参数路径 Default Description
-jar=     JAR文件的路径
-config=     配置文件的路径(而不是资源中的application.conf
-host= ktor.deployment.host 0.0.0.0 绑定主机
-port= ktor.deployment.port 80 绑定端口
-watch= ktor.deployment.watch [] 包路径,请注意重新加载
  ktor.application.id Application 用于记录的应用程序标识符
  ktor.deployment.callGroupSize parallelism 事件组大小正在运行的应用程序代码
  ktor.deployment.connectionGroupSize parallelism / 2 + 1 事件组大小接受连接
  ktor.deployment.workerGroupSize parallelism / 2 + 1 事件组大小,用于处理连接,解析消息和执行引擎的内部工作
  ktor.deployment.shutdown.url   定义时关闭应用程序的URL. 内部使用ShutDownUrl功能

定义SSL端口时必需:

Switch 参数路径 Default Description
-sslPort= ktor.deployment.sslPort null SSL端口
-sslKeyStore= ktor.security.ssl.keyStore null SSL密钥库
  ktor.security.ssl.keyAlias mykey SSL密钥存储的别名
  ktor.security.ssl.keyStorePassword null SSL密钥库的密码
  ktor.security.ssl.privateKeyPassword null SSL私钥的密码

您可以使用-P:来指定没有特定开关的参数. 例如: -P:ktor.deployment.callGroupSize=7 .

Reading the configuration from code

如果使用EngineMain而不是embeddedServer ,则会加载HOCON文件,并且可以访问其配置属性.

您还可以定义任意属性路径来配置应用程序.

val port: String = application.environment.config
    .propertyOrNull("ktor.deployment.port")?.getString()
    ?: "80"

通过使用带有commandLineEnvironment的自定义主目录,也可以访问HOCON application.conf配置:

embeddedServer(Netty, commandLineEnvironment(args + arrayOf("-port=8080"))).start(true)

或通过将其重定向到特定的EngineMain.main

val moduleName = Application::module.javaMethod!!.let { "${it.declaringClass.name}.${it.name}" }
io.ktor.server.netty.main(args + arrayOf("-port=8080", "-PL:ktor.application.modules=$moduleName"))

或使用自定义applicationEngineEnvironment

embeddedServer(Netty, applicationEngineEnvironment {
    log = LoggerFactory.getLogger("ktor.application")
    config = HoconApplicationConfig(ConfigFactory.load()) // Provide a Hocon config file

    module {
        routing {
            get("/") {
                call.respondText("HELLO")
            }
        }
    }

    connector {
        port = 8080
        host = "127.0.0.1"
    }
}).start(true)

您还可以通过手动加载默认配置文件application.conf来访问配置属性:

val config = HoconApplicationConfig(ConfigFactory.load())

Using environment variables

对于HOCON ,如果要使用环境变量配置某些参数,则可以使用${ENV}语法使用环境替换. 例如:

ktor {
    deployment {
        port = ${PORT}
    }
}

这将查找PORT环境变量,如果找不到,将引发异常:

Exception in thread "main" com.typesafe.config.ConfigException$UnresolvedSubstitution: application.conf @ file:/path/to/application.conf: 3: Could not resolve substitution to a value: ${PORT}

如果由于环境不存在而要为属性提供默认值,则可以使用默认值设置属性,然后使用${?ENV}语法再次设置它:

ktor {
    deployment {
        port = 8080
        port = ${?PORT}
    }
}

如果您使用的是embeddedServer ,则仍可以使用Java中的System.getenv . 例如:

val port = System.getenv("PORT")?.toInt() ?: 8080

Custom configuration systems

Ktor提供了一个可在其中实现配置的接口,该接口可从application.environment.config . 您可以在applicationEngineEnvironment内部构造和设置配置属性.

interface ApplicationConfig {
    fun property(path: String): ApplicationConfigValue
    fun propertyOrNull(path: String): ApplicationConfigValue?
    fun config(path: String): ApplicationConfig
    fun configList(path: String): List<ApplicationConfig>
}

interface ApplicationConfigValue {
    fun getString(): String
    fun getList(): List<String>
}

class ApplicationConfigurationException(message: String) : Exception(message)

Ktor提供了两种实现. 一种基于地图( MapApplicationConfig ),另一种基于HOCON( HoconApplicationConfig ).

您可以创建和组合配置实现,并在applicationEngineEnvironment设置它们,以便所有应用程序组件都可以使用它.

by  ICOPY.SITE