開發時 activator run 啟動的是 DEV mode,會一直檢查程式有沒有修改過,如果有修改,就會自動編譯並 reload,但這個功能會增加 overhead,在 PROD mode 就不需要了。另外 PROD 環境產生的 error page,也不需要像 DEV mode 一樣有太多錯誤的細節。
Production 相關設定
Play 需要一個 secret key 用來對 session cookie 簽章,還有內建的加密 utilities。
application.conf
play.crypto.secret = "newsecret"
該密碼預設為 "changeme",如果沒有修改這個密碼,在 PROD mode 就會發生錯誤,但在 DEV mode 就沒有檢查。
如果想要在 DEV 跟 PROD mode 使用不同的設定檔,可以在 conf 目錄中增加一個 prod-application.conf 新的設定檔,在啟動 PROD mode 時,加上設定檔的附加參數。
準備一個新的 prod-application.conf,內容為
include "application.conf"
play.crypto.secret = "newsecret"
另外同時準備一個 prod-logback.xml,新的 logback 設定檔,將 slick db sql statement 的 log 隱藏掉。
修改 build.sbt ,增加 JavaServerAppPackaging plugin,以及一些 production package 的設定
lazy val root = (project in file(".")).enablePlugins(PlayScala, JavaServerAppPackaging)
// production settings
maintainer := "charley <charley@maxkit.com.tw>"
packageSummary := "Play Slick Sample"
packageDescription := """A fun package description of our software,
with multiple lines."""
// RPM SETTINGS
rpmVendor := "maxkit"
//rpmLicense := Some("BSD")
rpmChangelogFile := Some("changelog.txt")
Play 預設是使用 Netty,Netty 提供了一些參數可以調整,我們可以在 application.conf 中,調整這些參數。
play.server {
# The server provider class name
provider = "play.core.server.NettyServerProvider"
netty {
# 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
# 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 the HTTP headers. The most common effect of this is a restriction in cookie length, including
# number of cookies and size of cookie values.
maxHeaderSize = 8192
# 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:
#
# http://netty.io/4.0/api/io/netty/channel/ChannelOption.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
}
}
}
}
activator 常用指令
ex: activator clean
- clean: 刪除 target 目錄中的編譯結果
- update: 下載的 libraries
- compile: 編譯專案,產生到 target 目錄中
- eclipse: 產生 eclipse 專案 project file,使用前要先執行 compile
- run: 啟動 project,也可以用 activator "run 8888" 啟動到 TCP Port 8888
- publish: 產生專案的 jar,發佈到 build.sbt 中設定的 repository
- publish-local: 發佈到本機的 repository/local 目錄
- stage: 產生 production 專案的 script,通常放在 target/universal/stage 目錄中
產生 stage project
activator stage
完整地產生新的 stage project 要執行
activator clean update compile stage
產生 production project tar.gz file
activator universal:packageZipTarball
PROD mode
以下兩種方式可以啟動 Production Mode
-Dconfig.resource 的部分,會在 class path 尋找設定檔 -Dconfig.file 則是依照 file system 尋找設定檔
-J-Xms512M -J-Xmx1G -J-server 這幾個是啟動 application 的 JVM 參數
target/universal/stage/bin/test6 -Dconfig.resource=prod-application.conf -Dlogger.resource=prod-logback.xml -Dhttp.port=9000 -J-Xms512M -J-Xmx1G -J-server
target/universal/stage/bin/test6 -Dconfig.file=conf/prod-application.conf -Dlogger.file=conf/prod-logback.xml -Dhttp.port=9000 -J-Xms512M -J-Xmx1G -J-server
啟動後,會在 target/universal/stage/RUNNING_PID 產生 process ID 的檔案
如果希望在背景執行 application,就要搭配 nohup 啟動 server
nohup target/universal/stage/bin/test6 -Dconfig.resource=prod-application.conf -Dlogger.resource=prod-logback.xml -Dhttp.port=9000 -J-Xms512M -J-Xmx1G -J-server < /dev/null > /dev/null 2>&1 &
可以用 kill 的方式關掉背景執行的 server
kill -SIGTERM `cat target/universal/stage/RUNNING_PID`
kill -SIGKILL `cat target/universal/stage/RUNNING_PID`
start.sh stop.sh scripts
為了方便,我們把上面的啟動方式,做成一個 script,放在 conf 目錄中,這樣就會在 activator stage 時,同時複製到 target/universal/stage
conf/start.sh
#!/bin/bash
#export JAVA_OPTS=""
#export JAVA_OPTS="$JAVA_OPTS -Xms512M -Xmx1G -server"
console() {
target/universal/stage/bin/test6 -Dconfig.resource=prod-application.conf -Dlogger.resource=prod-logback.xml -Dhttp.port=9000 -J-Xms512M -J-Xmx1G -J-server
}
server() {
nohup target/universal/stage/bin/test6 -Dconfig.resource=prod-application.conf -Dlogger.resource=prod-logback.xml -Dhttp.port=9000 -J-Xms512M -J-Xmx1G -J-server < /dev/null > /dev/null 2>&1 &
}
case "$1" in
console)
console
;;
server)
server
;;
*)
echo "Usage: $0 {console|server}"
;;
esac
exit 0
conf/stop.sh
#!/bin/bash
kill -SIGTERM `cat target/universal/stage/RUNNING_PID`
# kill -SIGKILL `cat target/universal/stage/RUNNING_PID`
然後就能用這樣的方式,啟動或停止 server
target/universal/stage/conf/start.sh server
target/universal/stage/conf/stop.sh
SSL
如果要讓 server 可以支援 HTTPS,我們需要做以下設定
Property | Purpose | Default Value |
---|---|---|
https.port | https port number | |
https.keyStore | 儲存 private key 及 certificate 的檔案路徑 | |
https.keyStoreType | key store type | JavaKeyStore(JKS) |
https.keyStorePassword | password | blank password |
https.keyStoreAlgorithm | key store algorithm | platform's default algorithm |
也可以自己實作 SSLEngine,參考 Configuring HTTPS,製作新的 class CustomSSLEngineProvider(appProvider: ApplicationProvider) extends SSLEngineProvider 。