§生產環境組態
在生產環境中,您可以組態許多不同類型的組態。三種類型的主要組態為
每種類型都有不同的方法來組態它們。
§一般組態
Play 有許多可設定的設定。你可以設定資料庫連線 URL、應用程式密碼、HTTP 埠、SSL 組態等等。
Play 的大多數組態都定義在不同的 .conf
檔案中,這些檔案使用 HOCON 格式。你將會使用的主要組態檔案是 application.conf
檔案。你可以在專案中的 conf/application.conf
中找到此檔案。application.conf
檔案會在執行階段從類別路徑載入(或你可以覆寫它載入的位置)。每個專案只能有一個 application.conf
。
其他 .conf
檔案也會載入。函式庫在 reference.conf
檔案中定義預設設定。這些檔案儲存在函式庫的 JAR 中,每個 JAR 有一个 reference.conf
,並在執行階段彙整在一起。reference.conf
檔案提供預設值;它們會被 application.conf
檔案中定義的任何設定覆寫。
Play 的組態也可以使用系統屬性和環境變數定義。當設定在不同環境之間變更時,這會很方便;你可以將 application.conf
用於一般設定,但使用系統屬性和環境變數來變更設定,當你在不同環境中執行應用程式時。
系統屬性會覆寫 application.conf
中的設定,而 application.conf
會覆寫不同 reference.conf
檔案中的預設設定。
你可以透過多種方式覆寫執行階段組態。當設定在不同環境之間變更時,這會很方便;你可以動態變更每個環境的組態。以下是執行階段組態的選項
- 使用備用的
application.conf
檔案。 - 使用系統屬性覆寫個別設定。
- 使用環境變數注入設定值。
§指定備用設定檔
預設會從類別路徑載入 application.conf
檔。必要時,您可以指定備用設定檔
§使用 -Dconfig.resource
這會在應用程式類別路徑中搜尋備用設定檔(您通常會在封裝前將這些備用設定檔提供給應用程式的 conf/
目錄)。Play 會查看 conf/
,因此您不必新增 conf/
。
$ /path/to/bin/<project-name> -Dconfig.resource=prod.conf
§使用 -Dconfig.file
您也可以指定未封裝到應用程式成品中的另一個本機設定檔
$ /path/to/bin/<project-name> -Dconfig.file=/opt/conf/prod.conf
請注意,您始終可以使用
include
指令在新的prod.conf
檔中參照原始設定檔,例如include "application.conf" key.to.override=blah
§使用系統屬性覆寫設定
有時您不想指定另一個完整的設定檔,而只是覆寫一堆特定金鑰。您可以透過將它們指定為 Java 系統屬性來執行此操作
$ /path/to/bin/<project-name> -Dplay.http.secret.key=ad31779d4ee49d5ad5162bf1429c32e2e9933f3b -Ddb.default.password=toto
§使用系統屬性指定 HTTP 伺服器地址和埠
您可以使用系統屬性輕鬆提供 HTTP 埠和地址。預設會在 0.0.0.0
地址(所有地址)的 9000
埠上監聽。
$ /path/to/bin/<project-name> -Dhttp.port=1234 -Dhttp.address=127.0.0.1
§使用環境變數指定 HTTP 伺服器地址和埠
您可以使用環境變數輕鬆提供 HTTP 埠和地址,例如在 Linux 中使用 Bash 時
export PLAY_HTTP_PORT=1234
export PLAY_HTTPS_PORT=1235
export PLAY_HTTP_ADDRESS=127.0.0.1
這些變數會在最後選取,表示在 application.conf
或透過系統屬性中已定義的任何埠或地址都會覆寫這些環境變數。
§變更 RUNNING_PID 的路徑
可以變更包含已啟動應用程式程序 ID 的檔案路徑。通常此檔案會放置在 Play 專案的根目錄中,但建議您將它放在重新啟動時會自動清除的地方,例如 /var/run
$ /path/to/bin/<project-name> -Dpidfile.path=/var/run/play.pid
請確認目錄存在,且執行 Play 應用程式的使用者具有寫入權限。
使用此檔案,您可以使用 kill
指令停止應用程式,例如
$ kill $(cat /var/run/play.pid)
若要防止 Play 建立自己的 PID,您可以在 application.conf
檔案中將路徑設定為 /dev/null
pidfile.path = "/dev/null"
§使用環境變數
您也可以從 application.conf
檔案參照環境變數
my.key = defaultvalue
my.key = ${?MY_KEY_ENV}
在此,覆寫欄位 my.key = ${?MY_KEY_ENV}
如果沒有 MY_KEY_ENV
的值,就會消失,但如果您設定環境變數 MY_KEY_ENV
,它就會被使用。
§伺服器組態選項
Play 的預設 HTTP 伺服器實作是 Pekko HTTP,它提供了許多調整和組態伺服器的方法,包括剖析器緩衝區的大小、是否使用保持連線等。
可以在這裡看到伺服器組態選項的完整清單,包括預設值
# 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
}
}
}
您也可以使用 Netty 作為 HTTP 伺服器,它也提供了自己的組態。可以在下面看到 Netty 伺服器組態的完整清單,包括預設值
# Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
play.server {
# The server provider class name
provider = "play.core.server.NettyServerProvider"
netty {
# The default value of the `Server` header to produce if no explicit `Server`-header was included in a response.
# If this value is the 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}
# The number of event loop threads. 0 means let Netty decide, which by default will select 2 times the number of
# available processors.
eventLoopThreads = 0
# When Netty shuts down, it ensures that no tasks (requests) are submitted for 'the quiet period' before it finally shuts down.
# If a task is submitted during the quiet period, it is guaranteed to be accepted and the quiet period will start over.
#
# For more details see:
# https://netty.dev.org.tw/4.1/api/io/netty/util/concurrent/EventExecutorGroup.html#shutdownGracefully-long-long-java.util.concurrent.TimeUnit-
#
# Play keeps using Netty's default of 2 seconds:
# https://github.com/netty/netty/blob/netty-4.1.92.Final/common/src/main/java/io/netty/util/concurrent/AbstractEventExecutor.java#L40
shutdownQuietPeriod = 2 seconds
# The maximum length of the initial line. This effectively restricts the maximum length of a URL that the server will
# accept, the initial line consists of the method (3-7 characters), the URL, and the HTTP version (8 characters),
# including typical whitespace, the maximum URL length will be this number - 18.
maxInitialLineLength = 4096
# The maximum length of body bytes that Netty will read into memory at a time.
# This is used in many ways. Note that this setting has no relation to HTTP chunked transfer encoding - Netty will
# read "chunks", that is, byte buffers worth of content at a time and pass it to Play, regardless of whether the body
# is using HTTP chunked transfer encoding. A single HTTP chunk could span multiple Netty chunks if it exceeds this.
# A body that is not HTTP chunked will span multiple Netty chunks if it exceeds this or if no content length is
# specified. This only controls the maximum length of the Netty chunk byte buffers.
maxChunkSize = 8192
# Whether the Netty wire should be logged
log.wire = false
# The transport to use, either jdk or native.
# Native socket transport has higher performance and produces less garbage but are only available on linux
transport = "jdk"
# Netty options. Possible keys here are defined by:
#
# https://netty.dev.org.tw/4.1/api/io/netty/channel/ChannelOption.html
# For native socket transport:
# https://netty.dev.org.tw/4.1/api/io/netty/channel/unix/UnixChannelOption.html
# https://netty.dev.org.tw/4.1/api/io/netty/channel/epoll/EpollChannelOption.html
#
# Options that pertain to the listening server socket are defined at the top level, options for the sockets associated
# with received client connections are prefixed with child.*
option {
# Set the size of the backlog of TCP connections. The default and exact meaning of this parameter is JDK specific.
# SO_BACKLOG = 100
child {
# Set whether connections should use TCP keep alive
# SO_KEEPALIVE = false
# Set whether the TCP no delay flag is set
# TCP_NODELAY = false
# Example how to set native socket transport options
# (Full qualified class name + "#" + option)
# "io.netty.channel.unix.UnixChannelOption#SO_REUSEPORT" = true
# "io.netty.channel.ChannelOption#TCP_FASTOPEN" = 1
}
}
}
}
注意:Netty 伺服器後端在 2.6.x 中不是預設值,因此必須 特別啟用。
上述組態是特定於 Pekko HTTP 和 Netty 伺服器後端的,但也有其他更通用的組態可用
# 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}
}
§記錄設定
記錄可透過建立 logback 設定檔進行設定。您的應用程式可透過下列方式使用此設定檔
§將自訂 logback 設定檔與您的應用程式綑綁
建立稱為 logback.xml
的替代 logback 設定檔,並將其複製到 <app>/conf
您也可以透過系統屬性指定另一個 logback 設定檔。請注意,如果未指定設定檔,play 會在生產模式下使用 play 附帶的預設 logback.xml
。這表示 application.conf
檔中的任何記錄層級設定都將被覆寫。建議您始終指定您的 logback.xml
。
§使用 -Dlogger.resource
指定要從類別路徑載入的另一個 logback 設定檔
$ /path/to/bin/<project-name> -Dlogger.resource=prod-logger.xml
§使用 -Dlogger.file
指定要從檔案系統載入的另一個 logback 設定檔
$ /path/to/bin/<project-name> -Dlogger.file=/opt/prod/prod-logger.xml
§使用 -Dlogger.url
指定要從 URL 載入的另一個 logback 設定檔
$ /path/to/bin/<project-name> -Dlogger.url=http://conf.mycompany.com/logger.xml
注意:若要查看正在使用的檔案,您可以設定系統屬性來進行偵錯:
-Dlogback.debug=true
。
§JVM 設定
您可以為應用程式啟動指令碼指定任何 JVM 引數。否則,將使用預設 JVM 設定
$ /path/to/bin/<project-name> -J-Xms128M -J-Xmx512m -J-server
下一頁:設定前端 HTTP 伺服器
在這個文件中發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時貢獻一個 pull request。有問題或建議要分享嗎?前往 我們的社群論壇 與社群展開對話。