当前位置 博文首页 > weixin_34357436的博客:tomcat jsvc 调优及JMX监控

    weixin_34357436的博客:tomcat jsvc 调优及JMX监控

    作者:[db:作者] 时间:2021-07-29 09:38

    Tomcat ?jsvc 调优及JMX监控


    实验背景

    ======================================================

    系统版本:CentOS release 6.5 (Final)

    Tomcat版本: ? Apache-tomcat-7.0.54


    Tomcat介绍:

    Tomcat是Apache?软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。目前最新版本是8.0。

    ======================================================

    Tomcat?7最新版本下载链接:
    http://mirrors.cnnic.cn/apache/tomcat/tomcat-7/v7.0.56/bin/apache-tomcat-7.0.56.tar.gz
    Tomcat?安装:
    tar?zxvf?apache-tomcat-7.0.54.tar.gz?-C?/opt/
    jsvc编译及调优:
    cd??apache-tomcat-7.0.54/bin
    tar?zxvf?commons-daemon-native.tar.gz
    cd?commons-daemon-1.0.x-native-src/unix
    ./configure
    make?-j4
    cp?jsvc?../../
    cd?../../
    添加tomcat用户,后面用来启动tomcat进程:
    useradd?-s?/sbin/nologin?tomcat
    jsvc?help文件:
    #?export?JAVA_HOME=/opt/jdk1.7.0_60/
    #?./jsvc?--help
    Usage:?jsvc?[-options]?class?[args...]
    Where?options?include:
    ????-help?|?--help?|?-?
    ????????show?this?help?page?(implies?-nodetach)
    ????-jvm?<JVM?name>
    ????????use?a?specific?Java?Virtual?Machine.?Available?JVMs:
    ????????????'server'
    ????-client
    ????????use?a?client?Java?Virtual?Machine.
    ????-server
    ????????use?a?server?Java?Virtual?Machine.
    ????-cp?|?-classpath?<directories?and?zip/jar?files>
    ????????set?search?path?for?service?classes?and?resouces
    ????-java-home?|?-home?<directory>
    ????????set?the?path?of?your?JDK?or?JRE?installation?(or?set
    ????????the?JAVA_HOME?environment?variable)
    ????-version
    ????????show?the?current?Java?environment?version?(to?check
    ????????correctness?of?-home?and?-jvm.?Implies?-nodetach)
    ????-showversion
    ????????show?the?current?Java?environment?version?(to?check
    ????????correctness?of?-home?and?-jvm)?and?continue?execution.
    ????-nodetach
    ????????don't?detach?from?parent?process?and?become?a?daemon
    ????-debug
    ????????verbosely?print?debugging?information
    ????-check
    ????????only?check?service?(implies?-nodetach)
    ????-user?<user>
    ????????user?used?to?run?the?daemon?(defaults?to?current?user)
    ????-verbose[:class|gc|jni]
    ????????enable?verbose?output
    ????-cwd?</full/path>
    ????????set?working?directory?to?given?location?(defaults?to?/)
    ????-outfile?</full/path/to/file>
    ????????Location?for?output?from?stdout?(defaults?to?/dev/null)
    ????????Use?the?value?'&2'?to?simulate?'1>&2'
    ????-errfile?</full/path/to/file>
    ????????Location?for?output?from?stderr?(defaults?to?/dev/null)
    ????????Use?the?value?'&1'?to?simulate?'2>&1'
    ????-pidfile?</full/path/to/file>
    ????????Location?for?output?from?the?file?containing?the?pid?of?jsvc
    ????????(defaults?to?/var/run/jsvc.pid)
    ????-D<name>=<value>
    ????????set?a?Java?system?property
    ????-X<option>
    ????????set?Virtual?Machine?specific?option
    ????-ea[:<packagename>...|:<classname>]
    ????-enableassertions[:<packagename>...|:<classname>]
    ????????enable?assertions
    ????-da[:<packagename>...|:<classname>]
    ????-disableassertions[:<packagename>...|:<classname>]
    ????????disable?assertions
    ????-esa?|?-enablesystemassertions
    ????????enable?system?assertions
    ????-dsa?|?-disablesystemassertions
    ????????disable?system?assertions
    ????-agentlib:<libname>[=<options>]
    ????????load?native?agent?library?<libname>,?e.g.?-agentlib:hprof
    ????-agentpath:<pathname>[=<options>]
    ????????load?native?agent?library?by?full?pathname
    ????-javaagent:<jarpath>[=<options>]
    ????????load?Java?programming?language?agent,?see?java.lang.instrument
    ????-procname?<procname>
    ????????use?the?specified?process?name
    ????-wait?<waittime>
    ????????wait?waittime?seconds?for?the?service?to?start
    ????????waittime?should?multiple?of?10?(min=10)
    ????-stop
    ????????stop?the?service?using?the?file?given?in?the?-pidfile?option
    ????-keepstdin
    ????????does?not?redirect?stdin?to?/dev/null
    jsvc?(Apache?Commons?Daemon)?1.0.15-dev
    Copyright?(c)?1999-2013?Apache?Software?Foundation.

    =============================================================

    接下来是重点了!

    复制bin目录下的daemon.sh?生成初步service文件
    
    #?cp?./daemon.sh?/etc/init.d/tomcat
    #?chmod?+x?/etc/init.d/tomcat
    jsvc?调优参数:
    export?PATH=/bin:/sbin:/usr/bin:/usr/sbin
    export?JAVA_HOME=/opt/jdk1.7.0_60
    export?JRE_HOME=/opt/jdk1.7.0_60/jre
    export?CATALINA_BASE=/opt/apache-tomcat-7.0.54
    export?CATALINA_HOME=/opt/apache-tomcat-7.0.54
    export?CATALINA_PID=$CATALINA_BASE/logs/catalina-daemon.pid
    export?CATALINA_TMP=$CATALINA_BASE/temp
    export?TOMCAT_USER=tomcat
    export?CATALINA_OPTS="-server?-Xss512k?-Xms2048M?-Xmx2048M?-XX:MaxPermSize=256M?-XX:PermSize=128M?-XX:NewSize=128M?-XX:+CMSIncreme
    ntalMode?-XX:CMSInitiatingOccupancyFraction=80?-XX:+UseConcMarkSweepGC?-XX:+UseParNewGC?-XX:ParallelGCThreads=8?-Djavax.servlet.r
    equest.encoding=UTF-8?-Djavax.servlet.response.encoding=UTF-8?-Dfile.encoding=UTF-8?-Duser.timezone=Asia/Shanghai?-Dcom.sun.manage
    ment.jmxremote?-Dcom.sun.management.jmxremote.port=100861?-Dcom.sun.management.jmxremote.ssl=false?-Dcom.sun.management.jmxremote.a
    uthenticate=false?-Djava.rmi.server.hostname=192.168.3.5"
    -XX:+CMSIncrementalMode
    该标志将开启CMS收集器的增量模式。增量模式经常暂停CMS过程,以便对应用程序线程作出完全的让步。因此,收集器将花更长的时间完成整个收集周期。因此,只有通过测试后发现正常CMS周期对应用程序线程干扰太大时,才应该使用增量模式。由于现代服务器有足够的处理器来适应并发的垃圾收集,所以这种情况发生得很少。
    -XX:CMSInitiatingOccupancyFraction
    当堆满之后,并行收集器便开始进行垃圾收集,例如,当没有足够的空间来容纳新分配或提升的对象。对于CMS收集器,长时间等待是不可取的,因为在并发垃圾收集期间应用持续在运行(并且分配对象)。因此,为了在应用程序使用完内存之前完成垃圾收集周期,CMS收集器要比并行收集器更先启动。
    因为不同的应用会有不同对象分配模式,JVM会收集实际的对象分配(和释放)的运行时数据,并且分析这些数据,来决定什么时候启动一次CMS垃圾收集周期。为了引导这一过程,?JVM会在一开始执行CMS周期前作一些线索查找。该线索由?-XX:CMSInitiatingOccupancyFraction=<value>来设置,该值代表老年代堆空间的使用率。比如,value=75意味着第一次CMS垃圾收集会在老年代被占用75%时被触发。通常CMSInitiatingOccupancyFraction的默认值为68(之前很长时间的经历来决定的)。
    -XX:+UseConcMarkSweepGC
    该标志首先是激活CMS收集器。默认HotSpot?JVM使用的是并行收集器。
    -XX:UseParNewGC
    当使用CMS收集器时,该标志激活年轻代使用多线程并行执行垃圾回收。这令人很惊讶,我们不能简单在并行收集器中重用-XX:UserParNewGC标志,因为概念上年轻代用的算法是一样的。然而,对于CMS收集器,年轻代GC算法和老年代GC算法是不同的,因此年轻代GC有两种不同的实现,并且是两个不同的标志。
    注意最新的JVM版本,当使用-XX:+UseConcMarkSweepGC时,-XX:UseParNewGC会自动开启。因此,如果年轻代的并行GC不想开启,可以通过设置-XX:-UseParNewGC来关掉。
    XX:ConcGCThreads
    标志-XX:ConcGCThreads=<value>(早期JVM版本也叫-XX:ParallelCMSThreads)定义并发CMS过程运行时的线程数。比如value=4意味着CMS周期的所有阶段都以4个线程来执行。尽管更多的线程会加快并发CMS过程,但其也会带来额外的同步开销。因此,对于特定的应用程序,应该通过测试来判断增加CMS线程数是否真的能够带来性能的提升。
    如果还标志未设置,JVM会根据并行收集器中的-XX:ParallelGCThreads参数的值来计算出默认的并行CMS线程数。该公式是ConcGCThreads?=?(ParallelGCThreads?+?3)/4。因此,对于CMS收集器,?-XX:ParallelGCThreads标志不仅影响“stop-the-world”垃圾收集阶段,还影响并发阶段。
    总之,有不少方法可以配置CMS收集器的多线程执行。正是由于这个原因,建议第一次运行CMS收集器时使用其默认设置,?然后如果需要调优再进行测试。只有在生产系统中测量(或类生产测试系统)发现应用程序的暂停时间的目标没有达到?,?就可以通过这些标志应该进行GC调优。
    -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
    接下来这些参数?是针对于?JMX?远程监控的:
    -Dcom.sun.management.jmxremote?启用JMX远程监控
    -Dcom.sun.management.jmxremote.port=100861?使用端口100861
    -Dcom.sun.management.jmxremote.authenticate=false?远程连接不需要密码认证
    -Dcom.sun.management.jmxremote.ssl=false?不使用SSL
    -Dcom.sun.management.jmxremote.access.file=$CATALINA_HOME/conf/jmxremote.access?使用指定的JMX帐号授权文件
    -Dcom.sun.management.jmxremote.password.file=$CATALINA_HOME/conf/jmxremote.password?使用指定的JMX帐号文件


    =============================================================


    到这里为止 tomcat 针对jsvc 调优已经差不多了,下面启动tomcat 测试:

    #?/etc/init.d/tomcat?start
    #?ps?-ef?|grep?tomcat
    root?????12166?????1??0?16:09??????????00:00:00?jsvc.exec?-java-home?/opt/jdk1.7.0_60?-user?tomcat?-pidfile?/opt/apache-tomcat-7.0.54/logs/catalina-daemon.pid?-wait?10?-outfile?/opt/apache-tomcat-7.0.54/logs/catalina-daemon.out?-errfile?&1?-classpath?/opt/apache-tomcat-7.0.54/bin/bootstrap.jar:/opt/apache-tomcat-7.0.54/bin/commons-daemon.jar:/opt/apache-tomcat-7.0.54/bin/tomcat-juli.jar?-Djava.util.logging.config.file=/opt/apache-tomcat-7.0.54/conf/logging.properties?-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager?-server?-Xss512k?-Xms2048M?-Xmx2048M?-XX:MaxPermSize=256M?-XX:PermSize=128M?-XX:NewSize=128M?-XX:+CMSIncrementalMode?-XX:CMSInitiatingOccupancyFraction=80?-XX:+UseConcMarkSweepGC?-XX:+UseParNewGC?-XX:ParallelGCThreads=8?-Djavax.servlet.request.encoding=UTF-8?-Djavax.servlet.response.encoding=UTF-8?-Dfile.encoding=UTF-8?-Duser.timezone=Asia/Shanghai?-Dcom.sun.management.jmxremote?-Dcom.sun.management.jmxremote.port=10086?-Dcom.sun.management.jmxremote.ssl=false?-Dcom.sun.management.jmxremote.authenticate=false?-Djava.rmi.server.hostname=192.168.3.5?-Djava.endorsed.dirs=?-Dcatalina.base=/opt/apache-tomcat-7.0.54?-Dcatalina.home=/opt/apache-tomcat-7.0.54?-Djava.io.tmpdir=/opt/apache-tomcat-7.0.54/temp?org.apache.catalina.startup.Bootstrap
    tomcat???12167?12166?34?16:09??????????00:00:05?jsvc.exec?-java-home?/opt/jdk1.7.0_60?-user?tomcat?-pidfile?/opt/apache-tomcat-7.0.54/logs/catalina-daemon.pid?-wait?10?-outfile?/opt/apache-tomcat-7.0.54/logs/catalina-daemon.out?-errfile?&1?-classpath?/opt/apache-tomcat-7.0.54/bin/bootstrap.jar:/opt/apache-tomcat-7.0.54/bin/commons-daemon.jar:/opt/apache-tomcat-7.0.54/bin/tomcat-juli.jar?-Djava.util.logging.config.file=/opt/apache-tomcat-7.0.54/conf/logging.properties?-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager?-server?-Xss512k?-Xms2048M?-Xmx2048M?-XX:MaxPermSize=256M?-XX:PermSize=128M?-XX:NewSize=128M?-XX:+CMSIncrementalMode?-XX:CMSInitiatingOccupancyFraction=80?-XX:+UseConcMarkSweepGC?-XX:+UseParNewGC?-XX:ParallelGCThreads=8?-Djavax.servlet.request.encoding=UTF-8?-Djavax.servlet.response.encoding=UTF-8?-Dfile.encoding=UTF-8?-Duser.timezone=Asia/Shanghai?-Dcom.sun.management.jmxremote?-Dcom.sun.management.jmxremote.port=10086?-Dcom.sun.management.jmxremote.ssl=false?-Dcom.sun.management.jmxremote.authenticate=false?-Djava.rmi.server.hostname=192.168.3.5?-Djava.endorsed.dirs=?-Dcatalina.base=/opt/apache-tomcat-7.0.54?-Dcatalina.home=/opt/apache-tomcat-7.0.54?-Djava.io.tmpdir=/opt/apache-tomcat-7.0.54/temp?org.apache.catalina.startup.Bootstrap
    如果你的系统开起了iptables的话,这里需要开放针对jmx?和?tomcat?的端口:
    vim?/etc/sysconfig/iptables
    -A?INPUT?-p?tcp?-m?state?--state?NEW?-m?tcp?--dport?8080?-j?ACCEPT
    -A?INPUT?-p?tcp?-m?state?--state?NEW?-m?tcp?--dport?10086?-j?ACCEPT
    
    
    /etc/init.d/iptables?restart
    重启防火墙生效;
    接下来打开浏览器测试tomcat是否已经work;
    http://192.168.3.5:8080

    =============================================================

    这里我们验证一下JMX远程监控,推荐使用VisualVM监控;

    JDK中还藏着一个宝贝,它的名字叫做VisualVM。VisualVM是Sun的一个OpenJDK项目,其目的在于为Java应用创建一个整套的问题解决工具

    官网主页:
    http://visualvm.java.net/


    步骤如下:

    1)添加远程主机:

    wKiom1RhsRbAoVAgAAB7hq7sWJ0335.jpg


    2)添加jmx连接:

    wKioL1RhshigJWpUAAByaipSSEU073.jpg


    这里需要注意格式:主机+端口 ,另外下面勾选 不要求SSL连接;

    wKiom1RhsgmyK9xpAADNwgknWUc141.jpg


    3)添加完成之后打开查看tomcat 资源使用情况;


    添加成功之后下面有个jmx的主机连接:

    wKioL1RhstjBHe0GAAA_wsNwP3A861.jpg


    打开即可!

    wKiom1RhssaBcGMaAAQ0TgHyBUg489.jpg


    So Next ,Enjoy it!



    下面是一个优化后的tomcat启动脚本的范例,可以放置在/etc/init.d/下 使用, start 、 stop等进行启动 、关闭操作;

    #!/bin/sh
    #?Licensed?to?the?Apache?Software?Foundation?(ASF)?under?one?or?more
    #?contributor?license?agreements.??See?the?NOTICE?file?distributed?with
    #?this?work?for?additional?information?regarding?copyright?ownership.
    #?The?ASF?licenses?this?file?to?You?under?the?Apache?License,?Version?2.0
    #?(the?"License");?you?may?not?use?this?file?except?in?compliance?with
    #?the?License.??You?may?obtain?a?copy?of?the?License?at
    #
    #?????http://www.apache.org/licenses/LICENSE-2.0
    #
    #?Unless?required?by?applicable?law?or?agreed?to?in?writing,?software
    #?distributed?under?the?License?is?distributed?on?an?"AS?IS"?BASIS,
    #?WITHOUT?WARRANTIES?OR?CONDITIONS?OF?ANY?KIND,?either?express?or?implied.
    #?See?the?License?for?the?specific?language?governing?permissions?and
    #?limitations?under?the?License.
    #
    #?-----------------------------------------------------------------------------
    #?Scripts?for?tomcat?based?on?jsvc
    #?-----------------------------------------------------------------------------
    #
    #?resolve?links?-?$0?may?be?a?softlink
    export?PATH=/bin:/sbin:/usr/bin:/usr/sbin
    export?JAVA_HOME=/opt/jdk1.7.0_60
    export?JRE_HOME=/opt/jdk1.7.0_60/jre
    export?CATALINA_BASE=/opt/apache-tomcat-7.0.54
    export?CATALINA_HOME=/opt/apache-tomcat-7.0.54
    export?CATALINA_PID=$CATALINA_BASE/logs/catalina-daemon.pid
    export?CATALINA_TMP=$CATALINA_BASE/temp
    export?TOMCAT_USER=tomcat
    export?CATALINA_OPTS="-server?-Xss512k?-Xms2048M?-Xmx2048M?-XX:MaxPermSize=256M?-XX:PermSize=128M?-XX:NewSize=128M?-XX:+CMSIncrementalMode?-XX:CMSInitiatingOccupancyFraction=80?-XX:+UseConcMarkSweepGC?-XX:+UseParNewGC?-XX:ParallelGCThreads=8?-Djavax.servlet.request.encoding=UTF-8?-Djavax.servlet.response.encoding=UTF-8?-Dfile.encoding=UTF-8?-Duser.timezone=Asia/Shanghai?-Dcom.sun.management.jmxremote?-Dcom.sun.management.jmxremote.port=22222?-Dcom.sun.management.jmxremote.ssl=false?-Dcom.sun.management.jmxremote.authenticate=false?-Djava.rmi.server.hostname=192.168.3.5"
    ARG0="$0"
    while?[?-h?"$ARG0"?];?do
    ??ls=`ls?-ld?"$ARG0"`
    ??link=`expr?"$ls"?:?'.*->?\(.*\)$'`
    ??if?expr?"$link"?:?'/.*'?>?/dev/null;?then
    ????ARG0="$link"
    ??else
    ????ARG0="`dirname?$ARG0`/$link"
    ??fi
    done
    DIRNAME="`dirname?$ARG0`"
    PROGRAM="`basename?$ARG0`"
    while?[?".$1"?!=?.?]
    do
    ??case?"$1"?in
    ????--java-home?)
    ????????JAVA_HOME="$2"
    ????????shift;?shift;
    ????????continue
    ????;;
    ????--catalina-home?)
    ????????CATALINA_HOME="$2"
    ????????shift;?shift;
    ????????continue
    ????;;
    ????--catalina-base?)
    ????????CATALINA_BASE="$2"
    ????????shift;?shift;
    ????????continue
    ????;;
    ????--catalina-pid?)
    ????????CATALINA_PID="$2"
    ????????shift;?shift;
    ????????continue
    ????;;
    ????--tomcat-user?)
    ????????TOMCAT_USER="$2"
    ????????shift;?shift;
    ????????continue
    ????;;
    ????*?)
    ????????break
    ????;;
    ??esac
    done
    #?OS?specific?support?(must?be?'true'?or?'false').
    cygwin=false;
    darwin=false;
    case?"`uname`"?in
    ????CYGWIN*)
    ????????cygwin=true
    ????????;;
    ????Darwin*)
    ????????darwin=true
    ????????;;
    esac
    #?Use?the?maximum?available,?or?set?MAX_FD?!=?-1?to?use?that
    test?".$MAX_FD"?=?.?&&?MAX_FD="maximum"
    #?Setup?parameters?for?running?the?jsvc
    #
    test?".$TOMCAT_USER"?=?.?&&?TOMCAT_USER=tomcat
    #?Set?JAVA_HOME?to?working?JDK?or?JRE
    #?JAVA_HOME=/opt/jdk-1.6.0.22
    #?If?not?set?we'll?try?to?guess?the?JAVA_HOME
    #?from?java?binary?if?on?the?PATH
    #
    if?[?-z?"$JAVA_HOME"?];?then
    ????JAVA_BIN="`which?java?2>/dev/null?||?type?java?2>&1`"
    ????test?-x?"$JAVA_BIN"?&&?JAVA_HOME="`dirname?$JAVA_BIN`"
    ????test?".$JAVA_HOME"?!=?.?&&?JAVA_HOME=`cd?"$JAVA_HOME/.."?>/dev/null;?pwd`
    else
    ????JAVA_BIN="$JAVA_HOME/bin/java"
    fi
    #?Only?set?CATALINA_HOME?if?not?already?set
    test?".$CATALINA_HOME"?=?.?&&?CATALINA_HOME=`cd?"$DIRNAME/.."?>/dev/null;?pwd`
    test?".$CATALINA_BASE"?=?.?&&?CATALINA_BASE="$CATALINA_HOME"
    test?".$CATALINA_MAIN"?=?.?&&?CATALINA_MAIN=org.apache.catalina.startup.Bootstrap
    #?If?not?explicitly?set,?look?for?jsvc?in?CATALINA_BASE?first?then?CATALINA_HOME
    if?[?-z?$JSVC?];?then
    ????JSVC="$CATALINA_BASE/bin/jsvc"
    ????if?[?!?-x?$JSVC?];?then
    ????????JSVC="$CATALINA_HOME/bin/jsvc"
    ????fi
    fi
    #?Set?the?default?service-start?wait?time?if?necessary
    test?".$SERVICE_START_WAIT_TIME"?=?.?&&?SERVICE_START_WAIT_TIME=10
    #?Ensure?that?any?user?defined?CLASSPATH?variables?are?not?used?on?startup,
    #?but?allow?them?to?be?specified?in?setenv.sh,?in?rare?case?when?it?is?needed.
    CLASSPATH=
    JAVA_OPTS=
    if?[?-r?"$CATALINA_BASE/bin/setenv.sh"?];?then
    ??.?"$CATALINA_BASE/bin/setenv.sh"
    elif?[?-r?"$CATALINA_HOME/bin/setenv.sh"?];?then
    ??.?"$CATALINA_HOME/bin/setenv.sh"
    fi
    #?Add?on?extra?jar?files?to?CLASSPATH
    test?".$CLASSPATH"?!=?.?&&?CLASSPATH="${CLASSPATH}:"
    CLASSPATH="$CLASSPATH$CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/commons-daemon.jar"
    test?".$CATALINA_OUT"?=?.?&&?CATALINA_OUT="$CATALINA_BASE/logs/catalina-daemon.out"
    test?".$CATALINA_TMP"?=?.?&&?CATALINA_TMP="$CATALINA_BASE/temp"
    #?Add?tomcat-juli.jar?to?classpath
    #?tomcat-juli.jar?can?be?over-ridden?per?instance
    if?[?-r?"$CATALINA_BASE/bin/tomcat-juli.jar"?]?;?then
    ??CLASSPATH="$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar"
    else
    ??CLASSPATH="$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar"
    fi
    #?Set?juli?LogManager?config?file?if?it?is?present?and?an?override?has?not?been?issued
    if?[?-z?"$LOGGING_CONFIG"?];?then
    ??if?[?-r?"$CATALINA_BASE/conf/logging.properties"?];?then
    ????LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
    ??else
    ????#?Bugzilla?45585
    ????LOGGING_CONFIG="-Dnop"
    ??fi
    fi
    test?".$LOGGING_MANAGER"?=?.?&&?LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
    JAVA_OPTS="$JAVA_OPTS?$LOGGING_MANAGER"
    #?Set?-pidfile
    test?".$CATALINA_PID"?=?.?&&?CATALINA_PID="$CATALINA_BASE/logs/catalina-daemon.pid"
    #?Increase?the?maximum?file?descriptors?if?we?can
    if?[?"$cygwin"?=?"false"?];?then
    ????MAX_FD_LIMIT=`ulimit?-H?-n`
    ????if?[?"$?"?-eq?0?];?then
    ????????#?Darwin?does?not?allow?RLIMIT_INFINITY?on?file?soft?limit
    ????????if?[?"$darwin"?=?"true"?-a?"$MAX_FD_LIMIT"?=?"unlimited"?];?then
    ????????????MAX_FD_LIMIT=`/usr/sbin/sysctl?-n?kern.maxfilesperproc`
    ????????fi
    ????????test?".$MAX_FD"?=?".maximum"?&&?MAX_FD="$MAX_FD_LIMIT"
    ????????ulimit?-n?$MAX_FD
    ????????if?[?"$?"?-ne?0?];?then
    ????????????echo?"$PROGRAM:?Could?not?set?maximum?file?descriptor?limit:?$MAX_FD"
    ????????fi
    ????else
    ????????echo?"$PROGRAM:?Could?not?query?system?maximum?file?descriptor?limit:?$MAX_FD_LIMIT"
    ????fi
    fi
    #?-----?Execute?The?Requested?Command?-----------------------------------------
    case?"$1"?in
    ????run?????)
    ??????shift
    ??????"$JSVC"?$*?\
    ??????$JSVC_OPTS?\
    ??????-java-home?"$JAVA_HOME"?\
    ??????-pidfile?"$CATALINA_PID"?\
    ??????-wait?10?\
    ??????-nodetach?\
    ??????-outfile?"&1"?\
    ??????-errfile?"&2"?\
    ??????-classpath?"$CLASSPATH"?\
    ??????"$LOGGING_CONFIG"?$JAVA_OPTS?$CATALINA_OPTS?\
    ??????-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS"?\
    ??????-Dcatalina.base="$CATALINA_BASE"?\
    ??????-Dcatalina.home="$CATALINA_HOME"?\
    ??????-Djava.io.tmpdir="$CATALINA_TMP"?\
    ??????$CATALINA_MAIN
    ??????exit?$?
    ????;;
    ????start???)
    ??????"$JSVC"?$JSVC_OPTS?\
    ??????-java-home?"$JAVA_HOME"?\
    ??????-user?$TOMCAT_USER?\
    ??????-pidfile?"$CATALINA_PID"?\
    ??????-wait?10?\
    ??????-outfile?"$CATALINA_OUT"?\
    ??????-errfile?"&1"?\
    ??????-classpath?"$CLASSPATH"?\
    ??????"$LOGGING_CONFIG"?$JAVA_OPTS?$CATALINA_OPTS?\
    ??????-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS"?\
    ??????-Dcatalina.base="$CATALINA_BASE"?\
    ??????-Dcatalina.home="$CATALINA_HOME"?\
    ??????-Djava.io.tmpdir="$CATALINA_TMP"?\
    ??????$CATALINA_MAIN
    ??????exit?$?
    ????;;
    ????stop????)
    ??????"$JSVC"?$JSVC_OPTS?\
    ??????-stop?\
    ??????-pidfile?"$CATALINA_PID"?\
    ??????-classpath?"$CLASSPATH"?\
    ??????-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS"?\
    ??????-Dcatalina.base="$CATALINA_BASE"?\
    ??????-Dcatalina.home="$CATALINA_HOME"?\
    ??????-Djava.io.tmpdir="$CATALINA_TMP"?\
    ??????$CATALINA_MAIN
    ??????exit?$?
    ????;;
    ????version??)
    ??????"$JSVC"?\
    ??????-java-home?"$JAVA_HOME"?\
    ??????-pidfile?"$CATALINA_PID"?\
    ??????-classpath?"$CLASSPATH"?\
    ??????-errfile?"&2"?\
    ??????-version?\
    ??????-check?\
    ??????$CATALINA_MAIN
    ??????if?[?"$?"?=?0?];?then
    ????????"$JAVA_BIN"?\
    ????????-classpath?"$CATALINA_HOME/lib/catalina.jar"?\
    ????????org.apache.catalina.util.ServerInfo
    ??????fi
    ??????exit?$?
    ????;;
    ????*???????)
    ??????echo?"Unknown?command:?\`$1'"
    ??????echo?"Usage:?$PROGRAM?(?commands?...?)"
    ??????echo?"commands:"
    ??????echo?"??run???????????????Start?Tomcat?without?detaching?from?console"
    ??????echo?"??start?????????????Start?Tomcat"
    ??????echo?"??stop??????????????Stop?Tomcat"
    ??????echo?"??version???????????What?version?of?commons?daemon?and?Tomcat"
    ??????echo?"????????????????????are?you?running?"
    ??????exit?1
    ????;;
    esac



    =============================================================

    参考资料:
    http://tomcat.apache.org/tomcat-7.0-doc/setup.html#Unix_daemon
    http://tomcat.apache.org/tomcat-7.0-doc/RUNNING.txt
    https://svn.apache.org/repos/asf/tomcat/tc7.0.x/trunk/bin/daemon.sh
    http://ifeve.com/useful-jvm-flags-part-7-cms-collector/

    =========================================================


    cs