Skip to content

Instantly share code, notes, and snippets.

@sitano
Last active August 29, 2015 14:05
Show Gist options
  • Save sitano/ee045c02b59498dfaffd to your computer and use it in GitHub Desktop.
Save sitano/ee045c02b59498dfaffd to your computer and use it in GitHub Desktop.
JVM bootstrap script
#!/bin/bash
# The MIT License (MIT)
# Copyright (c) 2014 Ivan Prisyazhniy <[email protected]>
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Helpers
die() { echo "ERR: $@" 1>&2 ; exit 1; }
warn() { echo "WARN: $@" 1>&2 ; }
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" && cd $dir/..
argv=("$@")
# Validate params
[ `ulimit -n` -lt 10000 ] && warn "Process have very low file max limit = $(ulimit -n)"
# HOSTNAME=<full hostname of the server>
[ -z "${HOSTNAME}" ] && HOSTNAME=`hostname -f`
# INTERNAL_IP=internal ip address for binding api handlers to
if [ -z "${INTERNAL_IP}" ] ; then
warn "If you are in production INTERNAL_IP=0.0.0.0 var must be explicitly set"
INTERNAL_IP="0.0.0.0"
fi
[ -z "${MEMORY_START}" ] && MEMORY_START="2048M"
[ -z "${MEMORY_MAX}" ] && MEMORY_MAX="4096M"
# MASTER="{0/1}" is master server
[ -z "${MASTER}" ] && MASTER="0"
# Allow login to master???
[ -z "${MASTER_NO_LOGIN}" ] && MASTER_NO_LOGIN="1"
# NODE="{1,2,}" unique game server node index per physical server
[ -z "${NODE}" ] && NODE="1"
[ 1 -gt "${NODE}" ] && die "Node id must be greater than 0"
# Start chat service
[ -z "${CHAT}" ] && CHAT="${MASTER}"
# GAME_PLATFORM={web/...}
[ -z "${GAME_PLATFORM}" ] && GAME_PLATFORM=""
# HOST_ALIAS=${GAME_PLATFORM}[INDEX]
[ -z "${HOST_ALIAS}" ] && [ ! -z "${GAME_PLATFORM}" ] && HOST_ALIAS="${GAME_PLATFORM}"
[ -z "${JMXRMI_ENABLED}" ] && JMXRMI_ENABLED="1"
[ -z "${JMXRMI_PORT_BASE}" ] && JMXRMI_PORT_BASE=5000
[ -z "${JMXRMI_PORT}" ] && JMXRMI_PORT=$((${JMXRMI_PORT_BASE}+${NODE}-1))
[ -z "${DEBUG_ENABLED}" ] && DEBUG_ENABLED="0"
[ -z "${DEBUG_PORT_BASE}" ] && DEBUG_PORT_BASE=5005
[ -z "${DEBUG_PORT}" ] && DEBUG_PORT=$((${DEBUG_PORT_BASE}+${NODE}-1))
[ -z "${CLASS}" ] && CLASS="your.java.main.Class.by.default"
[ -z "${SERVER_PORT_BASE}" ] && SERVER_PORT_BASE=9339
[ -z "${SERVER_PORT}" ] && SERVER_PORT=$((${SERVER_PORT_BASE}+${NODE}-1))
# JVM configuration
jvm_param_common=(
-Dfile.encoding=UTF-8
-Djava.net.preferIPv4Stack=true
)
jvm_param_log=(
-Dnet.spy.log.LoggerImpl=net.spy.memcached.compat.log.SunLogger
)
if [ -z "${JVM_LOG_PROPS}" ] ; then
JVM_LOG_PROPS="etc/logging_${GAME_PLATFORM}.properties"
[ ! -f "${JVM_LOG_PROPS}" ] && JVM_LOG_PROPS="etc/logging.properties"
[ ! -f "${JVM_LOG_PROPS}" ] && die "Can't find log configuration for jvm at etc/logging.properties or etc/logging_${GAME_PLATFORM}.properties"
else
[ ! -f "${JVM_LOG_PROPS}" ] && die "Can't find log configuration for jvm at ${JVM_LOG_PROPS}"
fi
[ ! -z "${JVM_LOG_PROPS}" ] && jvm_param_log+=(
-Djava.util.logging.config.file="${JVM_LOG_PROPS}"
)
jvm_param_cpu=(
-d64
-server
)
jvm_param_memory=(
-Xms"${MEMORY_START}"
-Xmx"${MEMORY_MAX}"
-XX:+AlwaysPreTouch
-XX:MaxPermSize=160m
-XX:PermSize=160m
-XX:NewSize=256m
-XX:MaxTenuringThreshold=0
-XX:SurvivorRatio=16
)
jvm_param_gc=(
# -XX:+UseG1GC
# -XX:MaxGCPauseMillis=100
# http://docs.oracle.com/cd/E13209_01/wlcp/wlss30/configwlss/jvmgc.html
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+CMSScavengeBeforeRemark
-XX:+CMSParallelRemarkEnabled
-XX:+UseTLAB
-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled
-XX:-UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
)
jvm_param_debug_print=(
-verbose:gc
-verbose:sizes
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintTenuringDistribution
-XX:-PrintCompilation
-XX:-TraceClassLoading
-XX:-TraceClassUnloading
-Xloggc:log/${GAME_SERVER_ALIAS}-gc.log
)
jvm_param_ops=(
-XX:+AggressiveOpts
-XX:-OmitStackTraceInFastThrow
# http://bugs.java.com/view_bug.do?bug_id=6385687
-XX:-UseFastEmptyMethods
-XX:-UseFastAccessorMethods
# PermGen issue: do not make it less than the default value
# -XX:CompileThreshold=10000
# -XX:ReservedCodeCacheSize=64m
# http://www.ibm.com/developerworks/aix/library/j-nativememory-aix/index.html?ca=dat
# http://anshuiitk.blogspot.ru/2010/11/excessive-full-garbage-collection.html
# -Dsun.reflect.inflationThreshold=15
# -Dsun.reflect.noInflation=false
)
jvm_param_jmxrmi=()
if [ "${JMXRMI_ENABLED}" -eq 1 ] ; then
jvm_param_jmxrmi+=(
-javaagent:lib/jmxrmiagent.jar
-Djava.rmi.server.hostname="${HOSTNAME}"
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxrmi.port="${JMXRMI_PORT}"
-Dcom.sun.management.jmxrmi.host="${HOSTNAME}"
)
fi
jvm_param_game_bootstrap=()
jvm_param_game_hibernate=(
-Dhibernate.bytecode.use_reflection_optimizer=true
-Dhibernate.bytecode.provider=javassist
)
jvm_param_game_node=()
if [ "${DEBUG_ENABLED}" -eq 1 ] ; then
jvm_param_debug=(
-Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address="${DEBUG_PORT}"
# "-agentlib:jdwp=transport=dt_socket,server=n,address=192.168.1.1:${DEBUG_PORT},suspend=y"
)
fi
jvm_classpath=(
etc
lib
)
# Build JVM configuration set
# $1 - jvm array name
# $2 - lines to add
# $3 - lines to remove before
function extend_jvm() {
local jvmRef=$1[@]
[ ! -z "$3" ] && eval "local _$1=\${$jvmRef/*$3*/};$1=(\"\${_$1[@]}\")"
[ ! -z "$2" ] && eval "$1+=(\"\$2\")"
}
# Delele conf line from conf set
# $1 - jvm array name
# $2 - lines to remove before
function disable_jvm() {
local jvmRef=$1[@]
[ ! -z "$2" ] && eval "local _$1=\${$jvmRef/*$2*/};$1=(\"\${_$1[@]}\")"
}
# Build jvm_params
# [$1] optional - array list of config sets
function set_jvm_params {
if [ -z "$1" ]; then
local jvm_params_list=(`( set -o posix ; set ) | grep -E 'jvm_param_.*=\(' | sed 's/=.*//'`)
else
local ref=$1[@]
local jvm_params_list=("${!ref}")
fi
jvm_params=()
for pset in ${jvm_params_list[@]}; do
local jvm_ref=${pset}[@]
jvm_params+=("${!jvm_ref}")
done
}
# $1 - jvm params array
# $2 - jvm classpath array
function set_game_cmd {
local paramsRef=$1[@]
local cpRef=$2[@]
cmd="java ${!paramsRef} -cp ."
for cp in ${!cpRef} ; do
cmd="${cmd}:${cp}"
done
cmd="${cmd} ${CLASS} ServerPort=${SERVER_PORT}"
}
# $1 - jvm params array
# $2 - jvm classpath array
function set_tool_cmd {
disable_jvm $2 game-server-base
local paramsRef=$1[@]
local cpRef=$2[@]
cmd="java ${!paramsRef} -cp ."
for cp in ${!cpRef} ; do
cmd="${cmd}:${cp}"
done
cmd="${cmd} ${CLASS}"
[ "${AUTO_CONFIG_ARGV}" == "1" ] && cmd="${cmd} etc/game_${GAME_PLATFORM}.xml"
cmd="${cmd} ${argv[@]}"
}
function game_start {
set_jvm_params
set_game_cmd jvm_params jvm_classpath
echo ${cmd}
exec ${cmd}
}
function tool_start {
# disabled:
# jvm_param_debug jvm_param_debug_print jvm_param_game_bootstrap
# jvm_param_game_hibernate jvm_param_game_node jvm_param_jmxrmi
local jvm_params_list=(
jvm_param_common jvm_param_cpu jvm_param_gc jvm_param_log jvm_param_memory jvm_param_ops jvm_param_debug
)
set_jvm_params jvm_params_list
set_tool_cmd jvm_params jvm_classpath
echo ${cmd}
exec ${cmd}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment