§配置 Pekko HTTP 服务器后端
默认情况下,Play 使用 Pekko HTTP 服务器后端。
与 Play 的其他部分一样,Pekko HTTP 服务器后端使用 Typesafe Config 进行配置。
# Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
# Configuration for Play's PekkoHttpServer
play {
server {
# The server provider class name
provider = "play.core.server.PekkoHttpServerProvider"
pekko {
# How long to wait when binding to the listening socket
bindTimeout = 5 seconds
# How long a request takes until it times out. Set to null or "infinite" to disable the timeout.
requestTimeout = infinite
# Enables/disables automatic handling of HEAD requests.
# If this setting is enabled the server dispatches HEAD requests as GET
# requests to the application and automatically strips off all message
# bodies from outgoing responses.
# Note that, even when this setting is off the server will never send
# out message bodies on responses to HEAD requests.
# For Play to work correctly with WebSockets, you should avoid setting this config to "on",
# see https://github.com/playframework/playframework/pull/7060
transparent-head-requests = off
# If this setting is empty the server only accepts requests that carry a
# non-empty `Host` header. Otherwise it responds with `400 Bad Request`.
# Set to a non-empty value to be used in lieu of a missing or empty `Host`
# header to make the server accept such requests.
# Note that the server will never accept HTTP/1.1 request without a `Host`
# header, i.e. this setting only affects HTTP/1.1 requests with an empty
# `Host` header as well as HTTP/1.0 requests.
# Examples: `www.spray.io` or `example.com:8080`
default-host-header = ""
# The default value of the `Server` header to produce if no
# explicit `Server`-header was included in a response.
# If this value is null and no header was included in
# the request, no `Server` header will be rendered at all.
server-header = null
server-header = ${?play.server.server-header}
# Configures the processing mode when encountering illegal characters in
# header value of response.
#
# Supported mode:
# `error` : default mode, throw an ParsingException and terminate the processing
# `warn` : ignore the illegal characters in response header value and log a warning message
# `ignore` : just ignore the illegal characters in response header value
illegal-response-header-value-processing-mode = warn
# Enables/disables inclusion of an Tls-Session-Info header in parsed
# messages over Tls transports (i.e., HttpRequest on server side and
# HttpResponse on client side).
#
# See Pekko HTTP `pekko.http.server.parsing.tls-session-info-header` for
# more information about how this works.
tls-session-info-header = on
# The maximum number of requests that are accepted (and dispatched to
# the application) on one single connection before the first request
# has to be completed.
# Incoming requests that would cause the pipelining limit to be exceeded
# are not read from the connections socket so as to build up "back-pressure"
# to the client via TCP flow control.
# A setting of 1 disables HTTP pipelining, since only one request per
# connection can be "open" (i.e. being processed by the application) at any time.
# This value must be > 0 and <= 1024.
# ATTENTION:
# Only enable HTTP pipelining if you _really_ know what you are doing. Nowadays, HTTP pipelining
# is mostly used for benchmarks anyway. Basically all web browser and most common clients (like curl)
# removed support for HTTP pipelining, since most client and server implementations were error prone.
# Also the implemention used by Play can cause unexpected behaviour, e.g. see
# https://github.com/playframework/playframework/issues/12351
pipelining-limit = 1
}
}
}
上面的配置特定于 Pekko HTTP 服务器后端,但其他更通用的配置也可用
# Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
play {
server {
# The root directory for the Play server instance. This value can
# be set by providing a path as the first argument to the Play server
# launcher script. See `ServerConfig.loadConfiguration`.
dir = ${?user.dir}
# HTTP configuration
http {
# The HTTP port of the server. Use a value of "disabled" if the server
# shouldn't bind an HTTP port.
port = 9000
port = ${?PLAY_HTTP_PORT}
port = ${?http.port}
# The interface address to bind to.
address = "0.0.0.0"
address = ${?PLAY_HTTP_ADDRESS}
address = ${?http.address}
# The idle timeout for an open connection after which it will be closed
# Set to null or "infinite" to disable the timeout, but notice that this
# is not encouraged since timeout are important mechanisms to protect your
# servers from malicious attacks or programming mistakes.
idleTimeout = 75 seconds
}
# HTTPS configuration
https {
# The HTTPS port of the server.
port = ${?PLAY_HTTPS_PORT}
port = ${?https.port}
# The interface address to bind to
address = "0.0.0.0"
address = ${?PLAY_HTTPS_ADDRESS}
address = ${?https.address}
# The idle timeout for an open connection after which it will be closed
# Set to null or "infinite" to disable the timeout, but notice that this
# is not encouraged since timeout are important mechanisms to protect your
# servers from malicious attacks or programming mistakes.
idleTimeout = ${play.server.http.idleTimeout}
# The SSL engine provider
engineProvider = "play.core.server.ssl.DefaultSSLEngineProvider"
engineProvider = ${?play.http.sslengineprovider}
# HTTPS keystore configuration, used by the default SSL engine provider
keyStore {
# The path to the keystore
path = ${?https.keyStore}
# The type of the keystore
type = "JKS"
type = ${?https.keyStoreType}
# The password for the keystore
password = ""
password = ${?https.keyStorePassword}
# The algorithm to use. If not set, uses the platform default algorithm.
algorithm = ${?https.keyStoreAlgorithm}
}
# HTTPS truststore configuration
trustStore {
# If true, does not do CA verification on client side certificates
noCaVerification = false
}
# Whether JSSE want client auth mode should be used. This means, the server
# will request a client certificate, but won't fail if one isn't provided.
wantClientAuth = false
# Whether JSSE need client auth mode should be used. This means, the server
# will request a client certificate, and will fail and terminate the session
# if one isn't provided.
needClientAuth = false
}
# The path to the process id file created by the server when it runs.
# If set to "/dev/null" then no pid file will be created.
pidfile.path = ${play.server.dir}/RUNNING_PID
pidfile.path = ${?pidfile.path}
websocket {
# Maximum allowable frame payload length. Setting this value to your application's
# requirement may reduce denial of service attacks using long data frames.
frame.maxLength = 64k
frame.maxLength = ${?websocket.frame.maxLength}
# Periodic keep alive may be implemented using by sending Ping frames
# upon which the other side is expected to reply with a Pong frame,
# or by sending a Pong frame, which serves as unidirectional heartbeat.
# Valid values:
# ping - default, for bi-directional ping/pong keep-alive heartbeating
# pong - for uni-directional pong keep-alive heartbeating
periodic-keep-alive-mode = ping
# Interval for sending periodic keep-alives
# If a client does not send a frame within this idle time, the server will sent the the keep-alive frame.
# The frame sent will be the one configured in play.server.websocket.periodic-keep-alive-mode
# `infinite` by default, or a duration that is the max idle interval after which an keep-alive frame should be sent
# The value `infinite` means that *no* keep-alive heartbeat will be sent, as: "the allowed idle time is infinite"
periodic-keep-alive-max-idle = infinite
}
debug {
# If set to true this will attach an attribute to each request containing debug information. If the application
# fails to load (e.g. due to a compile issue in dev mode), then this configuration value is ignored and the debug
# information is always attached.
#
# Note: This configuration option is not part of Play's public API and is subject to change without the usual
# deprecation cycle.
addDebugInfoToRequests = false
}
# The maximum length of the HTTP headers. The most common effect of this is a restriction in cookie length, including
# number of cookies and size of cookie values.
max-header-size = 8k
# If a request contains a Content-Length header it will be checked against this maximum value.
# If the value of a given Content-Length header exceeds this configured value, the request will not be processed
# further but instead the error handler will be called with Http status code 413 "Entity too large".
# If set to infinite or if no Content-Length header exists then no check will take place at all
# and the request will continue to be processed.
# Play uses the concept of a `BodyParser` to enforce this limit, so we set it to infinite.
max-content-length = infinite
# Timeout after which all requests and connections shall be forcefully terminated
# when shutting down the server. When this timeout gets applied, already the server is not bound to ports
# and therefore not accepting new connections anymore. It will default to Coordinated Shutdown service-requests-done
# phase timeout. Because of that default, Play will trigger the timeout 100 milliseconds earlier than actually configured
# via this config to make sure it fires before the service-requests-done phase ends.
# Value must be a duration, for example:
# play.server.terminationTimeout = 5 seconds
# This should be less than or equal to the value for `pekko.coordinated-shutdown.phases.service-requests-done.timeout`
# to prevent early server terminations by the underlying Pekko Coordinated Shutdown system.
terminationTimeout = null
# The delay to wait before the server will shut down requests and connections via "graceful" termination. When
# this delay gets applied, already the server is not bound to ports and therefore not accepting new connections anymore.
# This config might help you do work around a bug which causes the pekko-http backend to not take response entity streams into account
# during graceful termination, giving those responses time to finish: https://github.com/akka/akka-http/issues/3209
# By default, no delay is applied.
# Value must be a duration, for example:
# play.server.waitBeforeTermination = 2 seconds
# Be aware that `waitBeforeTermination` and `terminationTimeout` both happen within the Coordinated Shutdown `service-requests-done` phase.
# Therefore, the total value of the two configs should not be longer than the total timeout of the `service-requests-done` phase.
waitBeforeTermination = 0
# If body parsing should happen before executing actions defined via action composition (default) or if it should
# be deferred to a later point in time.
# Depending on the used Play plugin (PlayScala or PlayJava), setting this config to true will behave slightly differently.
# Please see the docs for more details:
# PlayScala
# https://playframework.com/documentation/latest/ScalaActionsComposition#Action-composition-in-interaction-with-body-parsing
# PlayJava
# https://playframework.com/documentation/latest/JavaActionsComposition#Action-composition-in-interaction-with-body-parsing
deferBodyParsing = false
}
editor = ${?PLAY_EDITOR}
}
您可以在 Pekko HTTP 文档 中了解更多关于配置设置的信息。
注意:Pekko HTTP 有许多 超时配置,您可以使用它们来保护您的应用程序免受攻击或编程错误。Play 中的 Pekko HTTP 服务器将自动识别所有这些 Pekko 配置。例如,如果您有以下
idle-timeout
和request-timeout
配置pekko.http.server.idle-timeout = 30s pekko.http.server.request-timeout = 20s
它们将被自动识别。请记住,上面列出的 Play 配置将覆盖 Pekko 配置。
在设置 request-timeout 时,请确保它小于 idle-timeout。否则,idle-timeout 将首先生效并重置 TCP 连接,而不会有响应。
如果启用了 PekkoHttp2Support
插件,Pekko HTTP 中的 HTTP/2 支持也有一个单独的配置文件。
# Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
# Determines whether HTTP2 is enabled.
play.server.pekko.http2 {
enabled = true
enabled = ${?http2.enabled}
}
注意:在开发模式下,当您使用
run
命令时,您的application.conf
设置不会被服务器获取。这是因为在开发模式下,服务器在应用程序类路径可用之前启动。您需要使用其他几种 选项。
§直接 Pekko HTTP 配置
如果您需要直接访问 Pekko HTTP 的 ServerSettings
和 ParserSettings
对象,您可以通过扩展 Play 的 PekkoHttpServer
类来实现。PekkoHttpServer
类有几个受保护的方法,可以覆盖这些方法来更改 Play 配置其 Pekko HTTP 后端的方式。
请注意,编写自己的服务器类是高级用法。通常,您可以通过正常的配置设置完成所有需要的配置。
以下代码展示了一个自定义服务器的示例,该服务器修改了一些 Pekko HTTP 设置。服务器类下方是一个 ServerProvider
类,它充当自定义服务器的工厂。
package server
import java.util.Random
import org.apache.pekko.http.scaladsl.model.HttpMethod
import org.apache.pekko.http.scaladsl.settings.ParserSettings
import org.apache.pekko.http.scaladsl.settings.ServerSettings
import org.apache.pekko.http.scaladsl.ConnectionContext
import play.core.server.PekkoHttpServer
import play.core.server.PekkoHttpServerProvider
import play.core.server.ServerProvider
/** A custom Pekko HTTP server with advanced configuration. */
class CustomPekkoHttpServer(context: PekkoHttpServer.Context) extends PekkoHttpServer(context) {
protected override def createParserSettings(): ParserSettings = {
val defaultSettings: ParserSettings =
super.createParserSettings()
defaultSettings.withCustomMethods(HttpMethod.custom("TICKLE"))
}
protected override def createServerSettings(
port: Int,
connectionContext: ConnectionContext,
secure: Boolean
): ServerSettings = {
val defaultSettings: ServerSettings =
super.createServerSettings(port, connectionContext, secure)
defaultSettings.withWebsocketRandomFactory(() => new Random())
}
}
/** A factory that instantiates a CustomPekkoHttpServer. */
class CustomPekkoHttpServerProvider extends ServerProvider {
def createServer(context: ServerProvider.Context): CustomPekkoHttpServer = {
val serverContext = PekkoHttpServer.Context.fromServerProviderContext(context)
new CustomPekkoHttpServer(serverContext)
}
}
编写好自定义服务器和 ServerProvider
类后,您需要通过将 play.server.provider
配置选项设置为 ServerProvider
类的完整名称来告诉 Play 关于它们。
例如,将以下设置添加到您的 build.sbt
和 application.conf
中,将告诉 Play 在 sbt run
任务和应用程序部署时使用您的新服务器。
build.sbt
:
PlayKeys.devSettings += "play.server.provider" -> "server.CustomPekkoHttpServerProvider"
application.conf
:
play.server.provider = server.CustomPekkoHttpServerProvider
下一步: 配置 Netty 服务器后端
发现此文档中的错误?此页面的源代码可以在 此处 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区进行交流。