Dies ist eine alte Version des Dokuments!
Ubuntu 8.04, Debian Lenny:
sun-java6-jdk
Ubuntu 10.04:
openjdk-6-jdk
Aufgrund der geänderten Oracle Lizenzbestimmungen, wurden die Oracle
Java Packete aus den Standard-Repositories entfernt. non-free wird
für die bequeme Installation benötigt, /etc/apt/sources.list anpassen.
Debian 6 Squeeze:
deb http://ftp.de.debian.org/debian/ squeeze main non-free deb-src http://ftp.de.debian.org/debian/ squeeze main non-free
deb http://security.debian.org/ squeeze/updates main non-free deb-src http://security.debian.org/ squeeze/updates main non-free
# squeeze-updates, previously known as 'volatile' deb http://ftp.de.debian.org/debian/ squeeze-updates main non-free deb-src http://ftp.de.debian.org/debian/ squeeze-updates main non-free
Mint 13:
deb http://packages.linuxmint.com/ maya main upstream import non-free
Debian / Ubuntu:
update-alternatives --config java
java-6-sun
auswählen
java -version sudo apt-get purge openjdk* sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java7-installer java -version
sudo mkdir -p /usr/lib/jvm cd ~/Downloads sudo cp jdk-7u21-linux-i586.tar.gz /usr/lib/jvm cd /usr/lib/jvm sudo tar zxvf jdk-7u21-linux-i586.tar.gz sudo rm jdk-7u21-linux-i586.tar.gz ls -l #jdk1.7.0_21 sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.7.0_21/bin/javac" 1 sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.7.0_21/bin/java" 1 sudo update-alternatives --set "javac" "/usr/lib/jvm/jdk1.7.0_21/bin/javac" sudo update-alternatives --set "java" "/usr/lib/jvm/jdk1.7.0_21/bin/java"
sudo nano /etc/profile
/etc/profile
: ( anhängen )
JAVA_HOME=/usr/lib/jvm/jdk1.7.0_21 PATH=$PATH:$JAVA_HOME/bin export JAVA_HOME export PATH
. /etc/profile java –version java version 1.7.0_21 #Java(TM) SE Runtime Environment (build 1.7.0_21-b12) #Java HotSpot(TM) Client VM (build 23.21-b01, mixed mode) javac –version #javac 1.7.0_21
Tomcat 6: Linux .tar.gz runterladen von: http://tomcat.apache.org/download-60.cgi z.B.:
cd mkdir workshop cd workshop wget http://www.osnt.org/apache/tomcat/tomcat-6/v6.0.38/bin/apache-tomcat-6.0.38.tar.gz tar xzf apache-tomcat-6.0.38.tar.gz ln -s apache-tomcat-6.0.38 apache-tomcat
Tomcat 7: Linux .tar.gz runterladen von: http://tomcat.apache.org/download-70.cgi z.B.:
cd mkdir workshop cd workshop wget http://www.osnt.org/apache/tomcat/tomcat-7/v7.0.52/bin/apache-tomcat-7.0.52.tar.gz tar xzf apache-tomcat-7.0.52.tar.gz ln -s apache-tomcat-7.0.52 apache-tomcat
Tomcat 8: Linux .tar.gz runterladen von: http://tomcat.apache.org/download-80.cgi z.B.:
cd mkdir workshop cd workshop wget http://www.osnt.org/apache/tomcat/tomcat-8/v8.0.24/bin/apache-tomcat-8.0.24.tar.gz tar xzf apache-tomcat-8.0.24.tar.gz ln -s apache-tomcat-8.0.24 apache-tomcat
cd cd workshop mkdir node73 cd node73 mkdir bin conf webapps logs work temp # File server und JSP Support only! #cp ../apache-tomcat/conf/web.xml conf/
conf/server.xml
: ( komplett, kurze Version )
<?xml version='1.0' encoding='utf-8'?> <Server port="${port.prefix}05" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.core.JasperListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Service name="Catalina"> <Connector port="${port.prefix}80" protocol="HTTP/1.1" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="node${port.prefix}"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" > </Host> </Engine> </Service> </Server>
conf/server.xml
: ( Tomcat 8 )
<?xml version='1.0' encoding='utf-8'?> <Server port="${port.prefix}05" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Service name="Catalina"> <Connector port="${port.prefix}80" protocol="HTTP/1.1" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="node${port.prefix}"> <Host name="localhost" appBase="webapps"> </Host> </Engine> </Service> </Server>
bin/startup.sh
:
#!/bin/bash export CATALINA_HOME=~/workshop/apache-tomcat export CATALINA_BASE=~/workshop/node73 export JAVA_OPTS="-Dport.prefix=73" export CATALINA_OPTS="-Xmx128m" export CATALINA_PID="${CATALINA_BASE}/logs/tomcat.pid" ${CATALINA_HOME}/bin/catalina.sh start $@
bin/shutdown.sh
:
#!/bin/bash export CATALINA_HOME=~/workshop/apache-tomcat export CATALINA_BASE=~/workshop/node73 export JAVA_OPTS="-Dport.prefix=73" export CATALINA_PID="${CATALINA_BASE}/logs/tomcat.pid" ${CATALINA_HOME}/bin/catalina.sh stop $@
Startfähigkeit herstellen
chmod +x bin/startup.sh #cp -a bin/startup.sh bin/shutdown.sh chmod +x bin/shutdown.sh
Verzeichnisbaum nach dem Start
├── bin │ ├── shutdown.sh │ └── startup.sh ├── conf │ ├── Catalina │ │ └── localhost │ └── server.xml ├── logs │ ├── catalina.out │ └── tomcat.pid ├── temp ├── webapps └── work
Check der server.xml ab Apache Tomcat 7
bin/configtest.sh
:
#!/bin/bash export CATALINA_HOME=~/workshop/apache-tomcat export CATALINA_BASE=~/workshop/node73 export JAVA_OPTS="-Dport.prefix=73" ${CATALINA_HOME}/bin/catalina.sh configtest $@
conf/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
mkdir webapps/ROOT echo "hello" >webapps/ROOT/index.html
Ergebnis einer index.html Auslieferung
nutzer18@notebook18:~/workshop/node73/conf$ telnet 127.0.0.1 7380 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. GET /index.html HTTP/1.0 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Accept-Ranges: bytes ETag: W/"6-1394459464000" Last-Modified: Mon, 10 Mar 2014 13:51:04 GMT Content-Length: 6 Date: Mon, 10 Mar 2014 13:59:42 GMT Connection: close hello Connection closed by foreign host. nutzer18@notebook18:~/workshop/node73/conf$ pwd
Mimetypes
conf/web.xml
<web-app ....> ... <!-- Nach servlet-mapping --> <mime-mapping> <extension>css</extension> <mime-type>text/css</mime-type> </mime-mapping> <mime-mapping> <extension>ico</extension> <mime-type>image/x-icon</mime-type> </mime-mapping> <mime-mapping> <extension>html</extension> <mime-type>text/html</mime-type> </mime-mapping> <mime-mapping> <extension>jpg</extension> <mime-type>image/jpeg</mime-type> </mime-mapping> <mime-mapping> <extension>js</extension> <mime-type>application/javascript</mime-type> </mime-mapping> <mime-mapping> <extension>json</extension> <mime-type>application/json</mime-type> </mime-mapping> <mime-mapping> <extension>png</extension> <mime-type>image/png</mime-type> </mime-mapping> <mime-mapping> <extension>xml</extension> <mime-type>application/xml</mime-type> </mime-mapping> ... <web-app>
Der Connector Parameter „HTTP/1.1“ steht für den Alias
org.apache.coyote.http11.Http11Protocol
wenn kein APR Listener erfolgreich den APR Native Libs gefunden hat. Wenn das APR initialisiert werden konnte, wird der ProtokollHandler auf die Klasse
org.apache.coyote.http11.Http11AprProtocol
gesetzt. Ähnliches gilt für den AJP/1.3 Alias. Das Projekt Apache Portable Runtime ist ein C-Lib die es ermöglich unter verschiedenen Betriebssystemen Threads, IO, usw. zu nutzen. Für den Tomcat existiert mit dem Projekt tcnative eine Anbindung für Java.
Tomcat starten:
./bin/startup.sh
Prozesse sehen:
jps jps -v lsof -a -i -c java lsof -i | grep java lsof -i | grep $(cat ../logs/tomcat.pid)
Speicherbelegung der Prozesse:
jstat -gc $(cat logs/tomcat.pid)
Free Memory
jstat -gc $(cat logs/tomcat.pid) | tail -1 | awk '{print "free old memory:",($7-$8)/1024, "mb"}' jstat -gc $(cat logs/tomcat.pid) | tail -1 | awk '{print "free perm memory:",($9-$10)/1024, "mb"}'
Stacktrace ausgeben lassen:
kill -3 $(cat logs/tomcat.pid) less logs/catalina.out #stacktrace snapshot erzeugen jstack -l $(cat logs/tomcat.pid) >"logs/gc`date`"
firefox http://localhost:7380/
bin/restart.sh
: ( restart Tomcat)
#!/bin/bash ~/workshop/node73/bin/shutdown.sh -force ~/workshop/node73/bin/startup.sh
Links
Plugin API Nagios
RFC339
ISO_8601
if [ -f ~/workshop/node73/logs/tomcat.pid ]; then pid_no=`cat ~/workshop/node73/logs/tomcat.pid` DATE=`date --rfc-3339=ns` ps_pid=`ps aux |grep -c $pid_no` echo "$DATE - OK - pid ($pid_no) existiert" if [ $ps_pid -gt 1 ]; then echo "$DATE - Ok - Zugehoeriger Prozess existiert" else echo "$DATE - Err - Zugehoeriger Prozess existiert nicht" fi port_7380=`lsof -i | grep $pid_no | grep -q ':7380' && echo -n "Ok - 7380" || echo -n "Err - 7380"` port_7309=`lsof -i | grep $pid_no | grep -q ':7309' && echo -n "Ok - 7309" || echo -n "Err - 7309"` port_7305=`lsof -i | grep $pid_no | grep -q ':7305' && echo -n "Ok - 7305" || echo -n "Err - 7305"` for x in "$port_7380" "$port_7309" "$port_7305" ; do echo "$DATE - $x" done temp=`curl --silent http://localhost:7380/test1/test1_ok.jsp | grep -c 'Ok'` if [ $temp -eq 1 ]; then echo "$DATE - Ok - AliveCheck" else echo "$DATE - Err - AliveCheck" fi else echo "$DATE - Err: pid existiert nicht!" fi
Prüfen ob noch genügend freier Speicher vorhanden ist:
bin/check_jvmfreemem.sh
:
#!/bin/bash # resolve links - $0 may be a softlink case $0 in /*) PRG="$0" ;; *) PWD=`pwd` PRG="$PWD/$0" ;; esac while [ -h "$PRG" ]; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`/"$link" fi done cd "`dirname "$PRG"`" PWD=`pwd` PRGDIR=`dirname "$PWD"` PID=$(cat ${PRGDIR}/logs/tomcat.pid) DATE=`date --rfc-3339=ns` MEMOLDUSAGE=$(jstat -gc $PID | tail -1 | awk '{print $(8)}') PERFOLDDATA=$(jstat -gcoldcapacity $PID | tail -1 | awk -v usage=$MEMOLDUSAGE '{print "free old memory:",($2-usage)/1024, "mb ;", "percentage:",(($2-usage) * 100 / $2),"%" }') MEMPERMUSAGE=$(jstat -gc $PID | tail -1 | awk '{print $(10)}') PERFPERMDATA=$(jstat -gcpermcapacity $PID | tail -1 | awk -v usage=$MEMPERMUSAGE '{print "free perm memory:",($2-usage)/1024, "mb ;", "percentage:",(($2-usage) * 100 / $2),"%" }') VALUE=$(echo $PERFOLDDATA | awk '{print int($8)}') STATUS=OK if [ $VALUE -lt $1 ] ; then STATUS=WARNING elif [ $VALUE -lt $2 ] ; then STATUS=CRITICAL fi echo $STATUS if [ $STATUS != "CRITICAL" ] ; then VALUE=$(echo $PERFPERMDATA | awk '{print int($8)}') if [ $VALUE -lt $3 ] ; then STATUS=WARNING elif [ $VALUE -lt $4 ] ; then STATUS=CRITICAL fi fi echo "JVMFREEMEM $STATUS - $DATE | $PERFOLDDATA | $PERFPERMDATA" case $STATUS in OK) exit 0 ;; WARNING) exit 1 ;; CRTICAL) exit 2 ;; *) exit 3;; esac
Als Parameter benötigt das Skript den Pfad zur Logdatei.
bin/check_tomcatstartup.sh
:
#!/bin/bash OIFS=$IFS IFS=$' ' LOGFILE=$1 RESPONSE_CODE_OK=0 RESPONSE_CODE_WARNING=1 RESPONSE_CODE_CRITICAL=2 RESPONSE_CODE_UNKNOWN=3 WARN_COUNT=0 ERROR_COUNT=0 ANALYSE_STATE=0 if [ ! -f $LOGFILE ]; then IFS=$OIFS echo "File not found" exit $RESPONSE_CODE_UNKNOWN fi for x in $(tac $LOGFILE) ; do if [ `echo $x | grep 'Server startup in' ` ]; then ANALYSE_STATE=1 fi; if [ ${ANAlYSE_STATE}="1" ]; then if [ `echo $x | grep 'ERROR'` ]; then ERROR_COUNT=$(($ERROR_COUNT+1)) fi; if [ `echo $x | grep 'WARN' ` ]; then WARN_COUNT=$(($WARN_COUNT+1)) fi; if [ `echo $x | grep 'Starting service Catalina'` ]; then break fi; fi; done ; IFS=$OIFS if [ $ERROR_COUNT -ge "1" ]; then echo "TomcatStartupCheck - CRITICAL | " echo "WARN COUNT: $WARN_COUNT" echo "ERROR COUNT: $ERROR_COUNT | " exit $RESPONSE_CODE_CRITICAL fi if [ $WARN_COUNT -ge "1" ]; then echo "TomcatStartupCheck - WARNING | " echo "WARN COUNT: $WARN_COUNT" echo "ERROR COUNT: $ERROR_COUNT | " exit $RESPONSE_CODE_WARNING fi if [ ${ANAlYSE_STATE}="1" ]; then echo "TomcatStartupCheck - OK | " echo "WARN COUNT: $WARN_COUNT" echo "ERROR COUNT: $ERROR_COUNT | " exit $RESPONSE_CODE_OK else echo "TomcatStartupCheck - UNKNOWN | " echo "WARN COUNT: $WARN_COUNT" echo "ERROR COUNT: $ERROR_COUNT | " exit $RESPONSE_CODE_UNKNOWN fi
mkdir webapps/hello
webapps/hello/index.jsp
:
hello! <br> es ist <%=new java.util.Date() %> Uhr!
firefox http://localhost:7380/hello/
mkdir -p webapps/hello/WEB-INF/classes cd webapps/hello/WEB-INF/classes vi HelloWorld.java
webapps/hello/WEB-INF/classes/HelloWorld.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hello World!</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Hello World!</h1>"); out.println("</body>"); out.println("</html>"); } }
javac -cp ~/workshop/apache-tomcat/lib/servlet-api.jar HelloWorld.java cd .. vi web.xml
webapps/hello/WEB-INF/web.xml
<web-app> <servlet> <servlet-name>HelloWorld</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloWorld</servlet-name> <url-pattern>/world</url-pattern> </servlet-mapping> </web-app>
Restart des Servers
cd ~/workshop/node73 bin/shutdown.sh bin/startup.sh firefox http://localhost:7380/hello/world
Test mit telnet
nutzer20@notebook20:~/workshop/node73$ telnet 127.0.0.1 7380 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. GET /hello/world HTTP/1.0 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/html Content-Length: 103 Date: Thu, 08 Mar 2012 14:10:34 GMT Connection: close <html> <head> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> </body> </html> Connection closed by foreign host.
Autoreload auf WEB-INF/web.xml
node73/conf/context.xml
<Context> <WatchedResource>WEB-INF/web.xml</WatchedResource> </Context>
Autoreload für Änderungen von Klassen aller Anwendungen
node73/conf/context.xml
<Context reloadable="true"> <WatchedResource>WEB-INF/web.xml</WatchedResource> </Context>
Nun muss der Server ebenfalls nochmals restartet werden. Ab jetzt kann man Änderungen an der Java Quelle Datei vornehmen und nach jeder Übersetzung wird diese in der Laufenden Anwendung sichtbar.
Ab dem Apache Tomcat 7 mit dem Servlet API 3.0 lassen sich die Konfigurationen auch direkt in den Servlet Code schreiben:
Anlage der Anwendung world
cd ~/workshop/node73/webapps mkdir world mkdir world/WEB-INF mkdir world/WEB-INF/classes mkdir world/WEB-INF/classes/world cd world/WEB-INF/classes/world vi Hello.java javac -cp ~/workshop/apache-tomcat/lib/servlet-api.jar Hello.java # restart des Servers
package world; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.WebServlet ; @WebServlet("/hello") public class Hello extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hello World!</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Hello World!</h1>"); out.println("</body>"); out.println("</html>"); } }
mkdir /tmp/hello2
/tmp/hello2/index.jsp
:
hello2! <br> es ist <%=new java.util.Date() %> Uhr!
jar cf hello2.war -C /tmp/hello2/ index.jsp cp hello2.war webapps/
firefox http://localhost:7380/hello2/
Ubuntu Standard Tomcat Installation
sudo apt-get install tomcat6 sudo apt-get install tomcat6-admin
User Node Installation für Test
sudo apt-get install tomcat6-user tomcat6-instance-create node91 -p 9180 -c 9105 -w qwewqeiq879qewq node91/bin/startup.sh node91/bin/shutdown.sh
Application hello
mit Basic Authentication absichern
conf/server.xml
:
<Server ..> .. <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service ..> <Engine ..> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> .. </Engine> </Service> </Server>
conf/tomcat-users.xml
:
<tomcat-users> <user username="manager" password="tomcat" roles="manager-gui" /> </tomcat-users>
webapps/hello/WEB-INF/web.xml
:
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Hello World Application</display-name> <description> Tolle Hello World Application </description> <servlet> <servlet-name>HelloWorld</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloWorld</servlet-name> <url-pattern>/world</url-pattern> </servlet-mapping> <!-- Define a Security Constraint on this Application --> <security-constraint> <web-resource-collection> <web-resource-name>Hello</web-resource-name> <url-pattern>/index.jsp</url-pattern> <url-pattern>/world</url-pattern> <!-- <url-pattern>/html/*</url-pattern> --> </web-resource-collection> <auth-constraint> <!-- NOTE: This role is not present in the default users file --> <role-name>manager-gui</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>BASIC</auth-method> <realm-name>Hello World Application</realm-name> </login-config> <!-- Security roles referenced by this web application --> <security-role> <description> The role that is required to log in to the Hello Application </description> <role-name>manager-gui</role-name> </security-role> <error-page> <error-code>401</error-code> <location>/401.jsp</location> </error-page> </web-app>
Syntax Tomcat 6 Servlet Api 2.5 checken:
xmllint --noout --schema http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd webapps/hello/WEB-INF/web.xml
Syntax Tomcat 7 - Servlet API 3.0 checken:
xmllint --noout --schema http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd webapps/hello/WEB-INF/web.xml
webapps/hello/401.jsp
:
hello error 401
Setzen einer kontrollierten Fehlerreaktion für „File not found“ Status Code 404
webapps/hello/WEB-INF/web.xml
<web-app> .. <error-page> <error-code>404</error-code> <location>/404.jsp</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/exception.jsp</location> </error-page> .. </web-app>
Für Tomcat 7 ist das web-app Schema folgendes.
webapps/hello/WEB-INF/web.xml
:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> </web-app>
webapps/hello/404.jsp
:
<%@ page session="false" isErrorPage="true" %> <html> <head><title>404 Not Found</title></head> <body> <h1>404 Not Found</h1> The url <code>${requestScope["javax.servlet.error.request_uri"]}</code> was not found. </body> </html>
Verfügbare RequestScope Attribute
Attribute | Type |
javax.servlet.error.status_code | java.lang.Integer |
javax.servlet.error.message | java.lang.String |
javax.servlet.error.request_uri | java.lang.String |
javax.servlet.error.servlet_name | java.lang.String |
javax.servlet.error.exception | java.lang.Throwable |
javax.servlet.error.exception_type | java.lang.Class |
webapps/hello/my.jsp
:
<%@ page session="false" errorPage="exception.jsp" %> <html> <head><title>My World</title></head> <body> <h1>Yep</h1> <% if(true) { throw new RuntimeException("my world"); } %> </body> </html>
webapps/hello/exception.jsp
:
<%@ page session="false" isErrorPage="true" import="java.io.*" %> <html> <head> <title>Exceptional Even Occurred!</title> <style> body, p { font-family:Tahoma; font-size:10pt; padding-left:30; } pre { font-size:8pt; } </style> </head> <body> <%-- Exception Handler --%> <font color="red"> <%= exception.toString() %><br> </font> <% out.println("<!--"); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); exception.printStackTrace(pw); out.print(sw); sw.close(); pw.close(); out.println("-->"); application.log(sw.toString()); %> </body> </html>
Generierung des Password mit Digest
apache-tomcat/bin/digest.sh -a SHA1 manager
Eintragen der Password in die tomcat-users.xml
node73/conf/tomcat-users.xml
:
<tomcat-users> <user username="manager" password="536c0b339345616c1b33caf454454d8b8a190d6c" roles="manager-gui" /> <user username="tomcat" password="536c0b339345616c1b33caf454454d8b8a190d6c" roles="user" /> </tomcat-users>
Eintragen des Digest Algo im Realm
node73/conf/server.xml
.. <Engine name="Catalina" defaultHost="localhost" jvmRoute="node${port.prefix}"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" digest="SHA1" resourceName="UserDatabase"/> .. </Engine>
Restart des Servers
Erste Option ist die Übernahme der manager Anwendung in die Node.
cp -a ../apache-tomcat/webapps/manager/ webapps/
Besser wäre eine Referenz der Manager Anwendung in den Node zuvereinbaren.
conf/Catalina/localhost/manager.xml
:
<Context docBase="${catalina.home}/webapps/manager" antiResourceLocking="false" privileged="true" useHttpOnly="true"/>
firefox http://localhost:7380/manager/html
Benutzername: manager
Password: tomcat
( siehe conf/tomcat-users.xml
)
conf/tomcat-users.xml
<tomcat-users> <user name="manager" password="tomcat" roles="manager-gui" /> </tomcat-users>
Tomcat 8:
conf/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?> <tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0"> <role rolename="manager-gui"/> <user username="manager" password="tomcat" roles="manager-gui"/> </tomcat-users>
Mit dem GlobalResourcesLifecycleListener werden die Daten der UserDatabase im MbeanServer (JMX) veröffentlicht und sind damit änderbar. Wenn die UserDatabase schreibar ist, kann man die Änderungen sogar wieder speichern.
Vorsicht die Passwörter sind via JMX einsehbar und evtl. temporär änderbar!!!
conf/server.xml
<Server .. > <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" readonly="false" /> </GlobalNamingResources> <Service ..> <Engine ..> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> .. </Engine> </Service> <Server/>
Zur Installation von Anwendungen auf dem Server kann man auch curl nutzen. Dazu ist es notwendig das der „User“ der Manager Anwendung in der Role „manager-script“ eingetragen ist.
curl --user manager:tomcat "http://localhost:7380/manager/text/deploy?path=/docs&config=file:/home/nutzer18/workshop/node73/docs.xml"
docs.xml
<Context docBase="${catalina.home}/webapps/docs" />
Einschränkung des Zugriffs auf die Manager Anwendung nur vom lokalen Host
conf/Catalina/localhost/manager.xml
:
<Context docBase="${catalina.home}/webapps/manager" antiResourceLocking="false" privileged="true" useHttpOnly="true"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"/> </Context>
conf/server.xml
<Engine ...> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> ... </Engine>
conf/tomcat-users.xml
<tomcat-users> <user name="manager" password="tomcat" roles="manager-gui" /> <user name="script" password="tomcat" roles="manager-script" /> <user name="jmx" password="tomcat" roles="manager-jmx" /> <user name="status" password="tomcat" roles="manager-status" /> </tomcat-users>
curl -u status:tomcat http://localhost:7380/manager/status/all?XML=true
Ergebnis
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="/manager/xform.xsl" ?> <status> <jvm> <memory free="61724312" total="72613888" max="119341056"/> <memorypool name="PS Eden Space" type="Heap memory" usageInit="15007744" usageCommitted="30015488" usageMax="36503552" usageUsed="795720"/> <memorypool name="PS Old Gen" type="Heap memory" usageInit="40108032" usageCommitted="40108032" usageMax="89522176" usageUsed="7624024"/> <memorypool name="PS Survivor Space" type="Heap memory" usageInit="2490368" usageCommitted="2490368" usageMax="2490368" usageUsed="2469832"/> <memorypool name="Code Cache" type="Non-heap memory" usageInit="2555904" usageCommitted="2555904" usageMax="50331648" usageUsed="1095104"/> <memorypool name="PS Perm Gen" type="Non-heap memory" usageInit="21757952" usageCommitted="21757952" usageMax="174063616" usageUsed="16175656"/> </jvm> <connector name=""http-bio-7380""> <threadInfo maxThreads="200" currentThreadCount="10" currentThreadsBusy="1"/> <requestInfo maxTime="53" processingTime="146" requestCount="7" errorCount="0" bytesReceived="0" bytesSent="121567"/> <workers> <worker stage="R" requestProcessingTime="0" requestBytesSent="0" requestBytesReceived="0" remoteAddr="?" virtualHost="?" method="?" currentUri="?" currentQueryString="?" protocol="?"/> <worker stage="R" requestProcessingTime="0" requestBytesSent="0" requestBytesReceived="0" remoteAddr="?" virtualHost="?" method="?" currentUri="?" currentQueryString="?" protocol="?"/> <worker stage="S" requestProcessingTime="4" requestBytesSent="0" requestBytesReceived="0" remoteAddr="0:0:0:0:0:0:0:1" virtualHost="localhost" method="GET" currentUri="/manager/status/all" currentQueryString="XML=true" protocol="HTTP/1.1"/> </workers> </connector> <connector name=""ajp-bio-7309""> <threadInfo maxThreads="200" currentThreadCount="0" currentThreadsBusy="0"/> <requestInfo maxTime="0" processingTime="0" requestCount="0" errorCount="0" bytesReceived="0" bytesSent="0"/> <workers/> </connector> </status>
* Tomcat CSRF Filter * Cross-Site-Request-Forgery * XML Pretty Printer
Remote Monitoring mit dem Befehl jconsole
bin/startup.sh
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=7304 \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false \ -Djava.rmi.server.hostname=$(hostname) \ -Djava.rmi.server.useLocalHostname=true"
Wenn eine Autorisierung nötig ist geht das mit:
-Dcom.sun.management.jmxremote.authenticate=true \ -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password \ -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access \
conf/jmxremote.access
monitorRole readonly controlRole readwrite
conf/jmxremote.password
monitorRole tomcat controlRole tomcat
Tipp: Der Password-file muss read-only und nur von UNIX Prozess Nutzers des Tomcats lesbar sein!!
Konfiguration im Tomcat für Server und Registry port!
download jmx remote download http://tomcat.apache.org/download-70.cgi
cp catalina-jmx-remote.jar node73/lib
<Server ...> <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="${port.prefix}03" rmiServerPortPlatform="${port.prefix}04" /> </Server>
Freischaltung der Firewall
sudo iptables -A INPUT -p tcp --dport 7303 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 7304 -j ACCEPT
Access URL
service:jmx:rmi://192.168.1.218:7304/jndi/rmi://192.168.1.218:7303/jmxrmi
conf/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="manager-jmx"/> <role rolename="manager-gui"/> <user username="jmx" password="tomcat" roles="manager-jmx"/> <user username="manager" password="tomcat" roles="manager-gui,manager-jmx"/> </tomcat-users>
Access MBean Attribute WebModule stateName
http://notebook31:7380/manager/jmxproxy/?get=Catalina:j2eeType=WebModule,name=//localhost/hello,J2EEApplication=none,J2EEServer=none&att=stateName
Access with curl
$curl --user "jmx:tomcat" "http://notebook31:7380/manager/jmxproxy/?get=Catalina:j2eeType=WebModule,name=//localhost/hello,J2EEApplication=none,J2EEServer=none&att=stateName" OK - Attribute get 'Catalina:j2eeType=WebModule,name=//localhost/hello,J2EEApplication=none,J2EEServer=none' - stateName = STARTED
$ curl --user "jmx:tomcat" "http://notebook31:7380/manager/jmxproxy/?get=Catalina:j2eeType=WebModule,name=//localhost/hello,J2EEApplication=none,J2EEServer=none&att=stateName" --silent | awk '{print $1 " " $(NF)}' OK STARTED
conf/logging.properties
:
handlers = 1catalina.org.apache.juli.FileHandler .handlers = 1catalina.org.apache.juli.FileHandler ############################################################ # Handler specific properties. # Describes specific configuration info for Handlers. ############################################################ 1catalina.org.apache.juli.FileHandler.level = FINE 1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs 1catalina.org.apache.juli.FileHandler.prefix = catalina. #java.util.logging.ConsoleHandler.level = FINE #java.util.logging.ConsoleHandler.formatter =
bin/setenv.sh
:
#!/bin/bash JAVA_OPTS="$JAVA_OPTS -Dlogdir=${CATALINA_BASE}/logs"
cd bin chmod +x setenv.sh cd .. mkdir -p webapps/ROOT/WEB-INF/classes vi webapps/ROOT/WEB-INF/classes/logging.properties
webapps/ROOT/WEB-INF/classes/logging.properties
:
handlers=1root.org.apache.juli.FileHandler .handlers=1root.org.apache.juli.FileHandler .level=FINE 1root.org.apache.juli.FileHandler.level=FINE 1root.org.apache.juli.FileHandler.directory=${logdir} 1root.org.apache.juli.FileHandler.prefix=root-
Level :
Unterdrücken der WebSocket Meldung bei Verwendung von Java 6
conf/logging.properties
org.apache.tomcat.websocket.server.WsSci.level = OFF
Autoreloading Anwendung nachdem die logging.properties geändert wurde
webapps/ROOT/META-INF/context.xml
:
<Context> <WatchedResource>WEB-INF/classes/logging.properties</WatchedResource> </Context>
webapps/ROOT/log.jsp
:
<%@ page import="java.util.logging.*" %> <% Logger logger = Logger.getLogger(""); logger.info("Info"); logger.fine("Fine"); application.log("context log"); System.out.println("system.out"); System.err.println("system.err"); %> see logfiles
curl http://localhost:7380/log.jsp
Ausgabe
/var/log/tomcat/node74/root-<Date>.log
13.07.2010 15:25:32 org.apache.jsp.log_jsp _jspService INFO: Info 13.07.2010 15:25:32 org.apache.jsp.log_jsp _jspService FEIN: Fine 13.07.2010 15:25:32 org.apache.catalina.core.ApplicationContext log INFO: context log
Unterdrücken der Tomcat Meldungen:
webapps/ROOT/WEB-INF/classes/logging.properties
handlers=1root.org.apache.juli.FileHandler .handlers=1root.org.apache.juli.FileHandler .level=FINE 1root.org.apache.juli.FileHandler.level=FINE 1root.org.apache.juli.FileHandler.directory=${logdir} 1root.org.apache.juli.FileHandler.prefix=root- org.apache.catalina.level=INFO org.apache.tomcat.level=INFO org.apache.jasper.level=INFO
Ausgabe des Tomcat8
05-May-2015 10:03:24.863 INFO [http-nio-7380-exec-7] org.apache.jsp.log_jsp._jspService Info 05-May-2015 10:03:24.864 FINE [http-nio-7380-exec-7] org.apache.jsp.log_jsp._jspService Fine 05-May-2015 10:03:24.864 INFO [http-nio-7380-exec-7] org.apache.catalina.core.ApplicationContext.log context log
Änderung der Sprache für die LogAusgabe
check :
echo $LANG de_DE.UTF-8
bin/startup.sh und bin/shutdown.sh oder in der setenv.sh
export LANG="en_US.UTF-8" export JAVA_OPTS="$JAVA_OPTS -Duser.language=en -Duser.country=US"
Ausgabe
/var/log/tomcat/node74/root-<Date>.log Sep 3, 2010 10:09:11 AM org.apache.jsp.log_jsp _jspService INFO: Info Sep 3, 2010 10:09:11 AM org.apache.jsp.log_jsp _jspService FINE: Fine Sep 3, 2010 10:09:11 AM org.apache.catalina.core.ApplicationContext log INFO: context log
/var/log/tomcat/node74/catalina.out
system.out system.err
Umlenkung der Ausgabe von System.out und System.err in das Appliction.log
webapps/ROOT/META-INF/context.xml
:
<Context swallowOutput="true" />
/etc/logrotate.d/tomcat
:
/home/nutzer01/workshop/node73/logs/catalina.out { size=+10 compress create 640 nutzer01 nutzer01 copytruncate # Achtung: hierbei können einzelne Logmeldungen während des Kopier/Compress Vorgangs verloren gehen }
logrotate /etc/logrotate.conf
oder etwas ernsthafter
/etc/logrotate.d/tomcat
:
/home/nutzer01/workshop/node73/logs/catalina.out { rotate 8 daily compress create 640 nutzer01 nutzer01 copytruncate # Achtung: hierbei können einzelne Logmeldungen während des Kopier/Compress Vorgangs verloren gehen }
webapps/ROOT/WEB-INF/classes/logging.properties
.. 1root.org.apache.juli.FileHandler.rotatable=false
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/juli/FileHandler.html
sudo mkdir /var/log/tomcat/node73 sudo mkdir /var/tmp/tomcat/node73/temp sudo mkdir /var/tmp/tomcat/node73/work sudo chown nutzer01:nutzer01 /var/log/tomcat/node73 sudo chown -R nutzer01:nutzer01 /var/tmp/tomcat/node73
home/nutzer01/workshop/node73/bin/startup.sh
:
... export CATALINA_OUT=/var/log/tomcat/node73/catalina.out export CATALINA_TMPDIR=/var/tmp/tomcat/node73/temp export JAVA_OPTS=-Dport.prefix=73 -Dcatalina.workdir=/var/tmp/tomcat/node73/work ...
home/nutzer01/workshop/node73/bin/shutdown.sh
:
... export CATALINA_OUT=/var/log/tomcat/node73/catalina.out export CATALINA_TMPDIR=/var/tmp/tomcat/node73/temp export JAVA_OPTS=-Dport.prefix=73 -Dcatalina.workdir=/var/tmp/tomcat/node73/work ...
home/nutzer01/workshop/node73/conf/server.xml
:
<Engine ...> <Host name="localhost" appBase="webapps" workDir="${catalina.workdir}" > </Host> </Engine>
Anpassung der /etc/logrotate.d auf /var/log/tomcat/catalina.out nicht vergessen!
conf/logging.properties
.handlers=java.util.logging.ConsoleHandler handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level=FINE java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format=%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s %4$s: %5$s%n org.apache.tomcat.util.digester.Digester.level=OFF
Ausgabe
Sep 02, 2014 12:02:23 PM org.apache.catalina.startup.Catalina load WARNING: Catalina.start using conf/server.xml: Attribute name "port" associated with an element type "Server" must be followed by the ' = ' character. Sep 02, 2014 12:02:23 PM org.apache.catalina.startup.Catalina load WARNING: Catalina.start using conf/server.xml: Attribute name "port" associated with an element type "Server" must be followed by the ' = ' character. Sep 02, 2014 12:02:23 PM org.apache.catalina.startup.Catalina start SEVERE: Cannot start server. Server instance is not configured.
.handlers=java.util.logging.ConsoleHandler handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level=FINE java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS.%1$tL%1$tz %2$s %4$s: %5$s%n org.apache.tomcat.util.digester.Digester.level=OFF
Ausgabe
2014-09-02T12:15:09.333+0200 org.apache.catalina.startup.Catalina load WARNING: Catalina.start using conf/server.xml: Attribute name "port" associated with an element type "Server" must be followed by the ' = ' character. 2014-09-02T12:15:09.338+0200 org.apache.catalina.startup.Catalina load WARNING: Catalina.start using conf/server.xml: Attribute name "port" associated with an element type "Server" must be followed by the ' = ' character. 2014-09-02T12:15:09.338+0200 org.apache.catalina.startup.Catalina start SEVERE: Cannot start server. Server instance is not configured.
Es fehlt die Angabe über den Threadname oder die ID dieses gibt es nur mit dem OneLineFormatter bisher!
Als erster müssen wir die Source aus dem Trunk des Apache Tomcat 7 holen.
mkdir -p workshop/formatter/src/org/apache/juli cd workshop/formatter/src/org/apache/juli wget http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/juli/OneLineFormatter.java wget http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/juli/DateFormatCache.java javac -cp ../../../../../apache-tomcat.6.0.32/bin/tomcat-juli.jar *.java cd ../../.. jar -cf ../formatter.jar org/apache/juli/*.class cp ../formatter.jar ../../node73/bin cd ../../node73
bin/setenv.sh
#!/bin/bash export CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/formatter.jar
conf/logging.properties
handlers = 1catalina.org.apache.juli.FileHandler .handlers = 1catalina.org.apache.juli.FileHandler .level=INFO 1catalina.org.apache.juli.FileHandler.level = FINE 1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs 1catalina.org.apache.juli.FileHandler.prefix = catalina. 1catalina.org.apache.juli.FileHandler.formatter = org.apache.juli.OneLineFormatter
restart des Servers und Kontrolle des Log Files
logs/catalina.YYYY-MM_DD.log
12-Jul-2011 12:38:09.835 INFO org.apache.coyote.http11.Http11Protocol.start Starting Coyote HTTP/1.1 on http-7380 12-Jul-2011 12:38:10.046 INFO org.apache.jk.common.ChannelSocket.init JK: ajp13 listening on /0.0.0.0:7309 12-Jul-2011 12:38:10.060 INFO org.apache.jk.server.JkMain.start Jk running ID=0 time=0/44 config=null 12-Jul-2011 12:38:10.086 INFO org.apache.catalina.startup.Catalina.start Server startup in 5390 ms
Im Tomcat 7 existiert noch ein AsyncFileHandler der sich für High Traffic Sites eignet.
conf/logging.properties
handlers = 1catalina.org.apache.juli.AsyncFileHandler .handlers = 1catalina.org.apache.juli.AsyncFileHandler 1catalina.org.apache.juli.AsyncFileHandler.level = FINE 1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs 1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina 1catalina.org.apache.juli.AsyncFileHandler.rotatable= false 1catalina.org.apache.juli.AsyncFileHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS.%1$tL%1$tz %2$s %4$s: %5$s%n org.apache.tomcat.util.digester.Digester.level=OFF
System properties | Default |
org.apache.juli.AsyncOverflowDropType | 1 |
org.apache.juli.AsyncMaxRecordCount | 10000 |
org.apache.juli.AsyncLoggerPollInterval | 1000 |
AsyncOverflowDropType | Wert |
OVERFLOW_DROP_LAST | 1 |
OVERFLOW_DROP_FIRST | 2 |
OVERFLOW_DROP_FLUSH | 3 |
OVERFLOW_DROP_CURRENT | 4 |
Referenz der Properties: http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/juli/FileHandler.html
Beschreibung | Link |
---|---|
commons-logging | http://commons.apache.org/logging/ |
log4j | http://logging.apache.org/log4j |
tomcat logging | http://tomcat.apache.org/tomcat-6.0-doc/logging.html |
logback (Nachfolger von log4j) | http://logback.qos.ch/ |
logback AccessLog and Filter | http://logback.qos.ch/access.html |
SLF4J logback Tomcat Binding | http://github.com/grgrzybek/tomcat-slf4j-logback |
SLF4J logback Tomcat Download | https://github.com/grgrzybek/tomcat-slf4j-logback/downloads |
Log4j Tutorial | http://www.torsten-horn.de/techdocs/java-log4j.htm |
Java Logging API Erweiterung X4Juli | http://www.x4juli.org/ |
Syslog4j | http://syslog4j.org/ |
./conf/server.xml
unterhalb des Tags Engine oder Host oder innerhalb der Context Definition für eine Anwendung ./conf/Catalina/localhost/<app>.xml
:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access-" suffix=".log" pattern="%h %l "%u" %t "%r" %s %b %D %S" resolveHosts="false" />
Im Apache Tomcat 7 lässt sich der Zeitstempel auf die Millisekunde genau erzeugen und
man kann festlegen, ob der Zeitstempel vom Beginn oder Ende des Requests ausgeben wird.
./conf/Catalina/localhost/<app>.xml
:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access-" suffix=".log" rotatable="true" pattern="%h "%{begin:yyyy-MM-dd'T'HH:mm:ss:SSSZ}t" %{begin:msec}t "%r" "%{Referer}i" "%{User-Agent}i" %s %b "%I" %D %S" resolveHosts="false"/>
100 Anfragen schicken:
ab -c 5 -n 100 -k http://localhost:7380/hello/index.jsp
Anfragen größer 70 Millisekunden filter:
awk '$(NF-1)/10 >= 7' logs/access-2010-06-25.log perl -a -n -e 'print $F[-2],$/ if $F[-2] > 70' logs/access-2010-06-25.log
Einfügen des ServerLifeCycleListener bewirkt, das das JMX Mbean MBeanFactory hinzugefügt wird. Mit Hilfe des Mbean kann man zur Laufzeit Tomcat Komponenten wie eine AccessLogValve hinzufügen und ein Ausgabe setzen.
Im Apache Tomcat 7 gibt es diese Klasse nicht mehr und die MbeanFactory ist immer aktiv!
conf/server.xml
<Server ..> <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" /> .. <Service ..> .. </Service> </Server>
Attribute Pattern für das AccesLogValve mit einer erweiterten Ausgabe
%h %l "%u" %t "%r" %s %b %D %S "%{User-Agent}i" "%{Referer}i"
Vorsicht: In der server.xml die Doppelten Anführungsstriche bitte durch " ersetzen.
Mit dem Attribute
enabled=false
des AccessLogValve kann ein Ausgabe unterbunden werden. Dafür kann der JMX Zugang via jconsole genutzt werden.
Dynamisch kann man diese Umschaltung auf via Manager App folgendermassen bewirken.
http://notebook20:7380/manager/jmxproxy?set=Catalina:type=Valve,name=AccessLogValve,seq=1&att=enabled&val=false
http://logstash.net/docs/1.4.2/tutorials/getting-started-with-logstash
curl -O https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz tar zxvf logstash-1.4.2.tar.gz cd logstash-1.4.2 bin/logstash -e 'input { stdin { } } output { stdout {} }' bin/logstash -e 'input { stdin { } } output { stdout { codec => rubydebug } }'
Bald 1.5.x
Auf jeder Maschine sollten die Logs mit dem logstashforwarder abgeholt werden.
https://github.com/elastic/logstash-forwarder
Aufgaben
* Multiline Logs * Exceptions * Direkt Log mit GELF * Informationen in Log Meldungen maschinenlesbar formulieren * Begrenzung der Logs auf Verwertbares * Ausfall und wiederaufsetzen der LogInfrastruktur
https://github.com/elastic/elasticsearch
curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.5.2.tar.gz tar zxvf elasticsearch-1.5.2.tar.gz cd elasticsearch-1.5.2/ cd config vi elasticsearch.conf # disable autorecovery cluster discovery.zen.ping.multicast.enabled: false ./bin/elasticsearch bin/logstash -e 'input { stdin { } } output { elasticsearch { host => localhost } }' curl 'http://localhost:9200/_search?pretty'
tomcat.conf
input { stdin { } } filter { grok { match => { "message" => "%{IPORHOST:clientip} \"%{TIMESTAMP_ISO8601:timestamp}\" %{NUMBER:unixtime:int} \"%{WORD:verb} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}\" \"(?:%{URI:referrer}|-)\" \"%{GREEDYDATA:agent}\" %{NUMBER:response:int} (?:%{NUMBER:bytes:int}|-) \"%{GREEDYDATA:thread}\" %{NUMBER:duration:int} (?:%{WORD:session_id}.%{WORD:node}|-)"} } } output { elasticsearch { host => localhost } stdout { codec => rubydebug } }
Parse all access logs
input { file { path => "/home/nutzer17/workshop/*/logs/access-*.log" start_position => beginning } } filter { grok { match => { "message" => "%{IPORHOST:clientip} \"%{TIMESTAMP_ISO8601:timestamp}\" %{NUMBER:unixtime:int} \"%{WORD:verb} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}\" \"(?:%{URI:referrer}|-)\" \"%{GREEDYDATA:agent}\" %{NUMBER:response:int} (?:%{NUMBER:bytes:int}|-) \"%{GREEDYDATA:thread}\" %{NUMBER:duration:int} (?:%{WORD:session_id}.%{WORD:node}|-)"} } } output { elasticsearch { host => localhost } stdout { codec => rubydebug } }
Install HQ Plugin
http://www.elastichq.org/support_plugin.html
open http://localhost:9200/_plugin/HQ/
Aufgaben
* Erlernen der Query Sprache ist komplex und aufwendig * Cluster * Backup und Restore von Indexen
https://github.com/elastic/kibana
curl -O https://download.elastic.co/kibana/kibana/kibana-4.0.2-linux-x64.tar.gz tar zxvf kibana-4.0.2-linux-x64.tar.gz cd kibana-4.0.2/bin ./kibana open http://localhost:5601
Änderungen in config/kibana.yml
Aufgaben
* Erstellen eines Dashboards * Sollen Metriken auch in Elasticsearch gespeichert werden? (Volumen)
bin/startup.sh
:
export CATALINA_OPTS="-Dport.prefix=73 -Xms64m -Xmx128m"
Perm Heap vergössern
-XX:MaxPermSize=256m
GC Logging
DATE=`date +'%y-%m-%d-%H-%M-%S'` export CATALINA_OPTS="$CATALINA_OPTS -verbosegc -Xloggc:$CATALINA_BASE/logs/gc-$DATE.log" export CATALINA_OPTS="$CATALINA_OPTS -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintTenuringDistribution"
Jstat Memory Trace
jstat -gc `cat logs/tomcat.pid` 5000
GCViewer
VmParameter
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
http://localhost:7380/manager/html/sessions?path=/hello
Eine alternativer Tomcat Manager ist psi-probe.
Schicker: http://code.google.com/p/psi-probe runterladen und
unzip probe-2.3.3.zip cp probe.war webapps
cd cp -a node73/ node74 cd node74/
bin/startup.sh
:
#!/bin/bash export CATALINA_HOME=~/apache-tomcat/ export CATALINA_BASE=~/node74/ export JAVA_OPTS="-Dport.prefix=74" export CATALINA_OPTS="-Xmx128m" export CATALINA_PID="${CATALINA_BASE}/logs/tomcat.pid" ${CATALINA_HOME}/bin/catalina.sh start $@
bin/shutdown.sh
:
#!/bin/bash export CATALINA_HOME=~/apache-tomcat/ export CATALINA_BASE=~/node74/ export JAVA_OPTS="-Dport.prefix=74" export CATALINA_PID="${CATALINA_BASE}/logs/tomcat.pid" ${CATALINA_HOME}/bin/catalina.sh stop $@
./bin/startup.sh
oder::
vi start ln -s start stop vi setenv.sh vi restart chmod 700 start stop restart
start
#!/bin/bash export CATALINA_HOME=~/workshop/apache-tomcat export CATALINA_BASE=~/workshop/node74 ${CATALINA_HOME}/bin/catalina.sh `basename $0` $@
setenv.sh
export JAVA_OPTS="-Dport.prefix=74" export CATALINA_PID="${CATALINA_BASE}/logs/tomcat.pid" export CATALINA_OPTS="-Xmx128m" export CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=true \ -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password \ -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access \ -Djava.rmi.server.hostname=$(hostname) \ -Djava.rmi.server.useLocalHostname=true" export CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true"
restart
#!/bin/bash ~/workshop/node74/bin/stop -force sleep 2 ~/workshop/node74/bin/start
cp -a ../apache-tomcat-6.0.35/conf/* conf/
Änderungen ( nicht vollständig ):
conf/server.xml
:
<Server port="${port.prefix}05" shutdown="SHUTDOWN" > <Connector port="${port.prefix}80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="${port.prefix}09" protocol="AJP/1.3" redirectPort="8443" />
ermittelt seinen Namen aus dem Verzeichnis node<prefix> und setzt die jvmRoute und den port.prefix für die server.xml.
bin/startup.sh
:
#!/bin/bash # Get the fully qualified path to the script case $0 in /*) SCRIPT="$0" ;; *) PWD=`pwd` SCRIPT="$PWD/$0" ;; esac # Change spaces to ":" so the tokens can be parsed. SCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'` # Get the real path to this script, resolving any symbolic links TOKENS=`echo $SCRIPT | sed -e 's;/; ;g'` REALPATH= for C in $TOKENS; do REALPATH="$REALPATH/$C" while [ -h "$REALPATH" ] ; do LS="`ls -ld "$REALPATH"`" LINK="`expr "$LS" : '.*-> \(.*\)$'`" if expr "$LINK" : '/.*' > /dev/null; then REALPATH="$LINK" else REALPATH="`dirname "$REALPATH"`""/$LINK" fi done done # Change ":" chars back to spaces. REALPATH=`echo $REALPATH | sed -e 's;:; ;g'` # Change the current directory to the location of the script cd "`dirname "$REALPATH"`" cd "`dirname "$SCRIPT"`" REALDIR=`pwd` parentdir=`dirname $REALDIR` export CATALINA_BASE=$parentdir INSTANCE_NAME=`basename $parentdir` PORT_PREFIX=`echo $INSTANCE_NAME | awk '{ printf substr($1,5,2)}'` export CATALINA_HOME=/home/nutzer01/workshop/apache-tomcat-6.0.35 export CATALINA_OUT=/var/log/tomcat/$INSTANCE_NAME/catalina.out mkdir -p /var/log/tomcat/$INSTANCE_NAME export CATALINA_TMPDIR=/var/tmp/tomcat/$INSTANCE_NAME/temp mkdir -p /var/tmp/tomcat/$INSTANCE_NAME export JAVA_OPTS="-DjvmRoute=$INSTANCE_NAME -Dport.prefix=$PORT_PREFIX" export CATALINA_OPTS="-server -Xmx128m -Dcatalina.workdir=/var/tmp/tomcat/$INSTANCE_NAME/work" export CATALINA_PID=/var/log/tomcat/$INSTANCE_NAME/tomcat.pid $CATALINA_HOME/bin/catalina.sh start $@
Liste aller Java Prozesse eines Nutzers
jps
2390 Bootstrap 8259 Jps 8244 Bootstrap
Ausgabe der Parameter der Java Prozesse
jps -vml
2390 org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/home/nutzer06/workshop/apache-tomcat-6.0.28/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/home/nutzer06/workshop/apache-tomcat-6.0.28/endorsed -Dcatalina.base=/home/nutzer06/workshop/apache-tomcat-6.0.28 -Dcatalina.home=/home/nutzer06/workshop/apache-tomcat-6.0.28 -Djava.io.tmpdir=/home/nutzer06/workshop/apache-tomcat-6.0.28/temp 8295 sun.tools.jps.Jps -vml -Dapplication.home=/usr/lib/jvm/java-6-openjdk -Xms8m 8244 org.apache.catalina.startup.Bootstrap start -Dnop -DjvmRoute=node74 -Dport.prefix=74 -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Dcatalina.workdir=/var/tmp/tomcat/node74/work -Djava.endorsed.dirs=/home/nutzer06/workshop/apache-tomcat-6.0.28/endorsed -Dcatalina.base=/home/nutzer06/workshop/node74 -Dcatalina.home=/home/nutzer06/workshop/apache-tomcat-6.0.28 -Djava.io.tmpdir=/var/tmp/tomcat/node74/temp
Protokollierung des Speicherverbrauchs eines Java Prozesses
jstat -gc <jpid> <time msec>
Ausgabe
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 64,0 64,0 0,0 32,0 4288,0 342,9 35776,0 3195,2 16384,0 10085,0 125 0,142 28 1,567 1,709 64,0 64,0 0,0 32,0 4288,0 342,9 35776,0 3195,2 16384,0 10085,0 125 0,142 28 1,567 1,709 64,0 64,0 0,0 32,0 4288,0 428,7 35776,0 3195,2 16384,0 10085,0 125 0,142 28 1,567 1,709
Im Tomcat 6 ist es möglich einen Threadpool auf der Basis des Standard Java Executor API zu nutzen. Damit können endlich auch verschiedenen Connectoren einen gemeinsamen Threadpool nutzen.
<Executor name="Catalina-Threads" namePrefix="Catalina-exec" maxThreads="200" minSpareThreads="50" /> <Connector port="${port.prefix}80" executor="Catalina-Threads" protocol="HTTP/1.1" /> <Connector port="${port.prefix}90" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11NioProtocol" /> <Connector port="${port.prefix}09" executor="Catalina-Threads" protocol="org.apache.coyote.ajp.AjpProtocol" />
<?xml version='1.0' encoding='utf-8'?> <Server port="${port.prefix}05" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <Executor name="TomcatThreads" namePrefix="Catalina-exec" maxThreads="200" minSpareThreads="50" /> <Connector port="${port.prefix}80" protocol="org.apache.coyote.http11.Http11NioProtocol" executor="TomcatThreads" /> <Connector port="${port.prefix}81" protocol="org.apache.coyote.http11.Http11Nio2Protocol" executor="TomcatThreads" /> <Connector port="${port.prefix}90" protocol="org.apache.coyote.http11.Http11Protocol" executor="TomcatThreads"/> <Engine name="Catalina" defaultHost="localhost" jvmRoute="node${port.prefix}"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access-" suffix=".log" rotatable="true" pattern="%h "%{begin:yyyy-MM-dd'T'HH:mm:ss:SSSZ}t" %{begin:msec}t "%r" "%{Referer}i" "%{User-Agent}i" %s %b "%I" %D %S" resolveHosts="false"/> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host name="localhost" appBase="webapps"> </Host> </Engine> </Service> </Server>
sudo apt-get install apache2-utils
Erzeugung von statischen Dateien
cd webapps mkdir last cd last dd if=/dev/urandom of=8k.bin bs=1024 count=8 dd if=/dev/urandom of=25k.bin bs=1024 count=25 dd if=/dev/urandom of=64k.bin bs=1024 count=64 dd if=/dev/urandom of=100k.bin bs=1024 count=100 dd if=/dev/urandom of=250k.bin bs=1024 count=250
Ausführen der Test mit ab einer Testserie mit 5,10,25,100,200,300 paralleln Anfragen mit jeweils 50000 Anfragen.
ab -c 5 -n 50000 -k http://127.0.0.1:7380/last/8k.bin ab -c 10 -n 50000 -k http://127.0.0.1:7380/last/8k.bin ...
Ausführung eines Tests
cd workshop/node74 mkdir stat vi last.sh chmod 750 last.sh
last.sh
#!/bin/sh req=50000 for port in 7480 ; do \ for con in 10 50 100 250 400 800; do \ for datei in 8 25 64 100 250 ; do \ for iter in 1 2 3 ; do \ sleep 1 ab -c ${con} -n ${req} -k \ http://localhost:${port}/last/${datei}k.bin > stat/${port}-${datei}k-${con}-${req}-${iter}.txt ; done ; done ; done ; done
Auswertung der Dateien
cd stat find . -exec grep -H "Requests per" {} \;
Start visualVM remote
ssh -X nutzer18@192.168.1.218 jvisualvm --jdkhome /usr/lib/jvm/java-6-sun-1.6.0.26
gnuplot
http://forums.cpanel.net/f402/using-apache-ab-benchmarking-gnuplot-graphing-275542.html
sudo -i vi /etc/apt/sources-list sudo apt-get update sudo apt-get install gnuplot vi plot.p ab -c 5 -n 50000 -g data.dat http://localhost:7380/last/8k.bin
/etc/apt/sources-list
deb [arch=amd64] http://ubuntu/ubuntu trusty main restricted universe multiverse deb [arch=amd64] http://ubuntu/ubuntu trusty-security main restricted universe multiverse deb [arch=amd64] http://ubuntu/ubuntu trusty-updates main restricted universe multiverse
plot.p
#output as png image set terminal png #save file to "data.png" set output "data.png" #graph title set title "ab -n 50000 -c 5" #nicer aspect ratio for image size set size 1,0.7 # y-axis grid set grid y #x-axis label set xlabel "request" #y-axis label set ylabel "response time (ms)" #plot data from "domain.dat" using column 9 with smooth sbezier lines #and title of "something" for the given data plot "data.dat" using 9 smooth sbezier with lines title "something"
gnuplot <plot.p ls -l data.* -rw-rw-r-- 1 nutzer31 nutzer31 2200170 Sep 3 17:47 data.dat -rw-rw-r-- 1 nutzer31 nutzer31 3993 Sep 3 17:54 data.png
sudo aptitude install libapr1-dev sudo aptitude install libssl-dev cd apache-tomcat-6.0.33/bin cp tomcat-native.tar.gz ../.. cd ../.. tar xzf tomcat-native.tar.gz cd tomcat-native-1.1.20-src/jni/native ./configure --with-apr=/usr/bin/apr-1-config --with-java-home=/usr/lib/jvm/java-6-sun --with-ssl=yes --prefix=/home/nutzer01/workshop/apache-tomcat-6.0.33 make make install cd ../../../node74
Ubuntu 14.04
sudo apt-get install libapr1-dev sudo apt-get install libssl-dev cd ~/workshop/apache-tomcat/bin tar xzf tomcat-native.tar.gz cd tomcat-native-1.1.31-src/jni/native ./configure --with-apr=/usr/bin/apr-1-config --with-java-home=/usr/lib/jvm/java-1.7.0-openjdk-amd64 --with-ssl=yes --prefix=/home/nutzer31/workshop/apache-tomcat make make install cd ../../../node73
conf/server.xml
<Server ... <Listener className="org.apache.catalina.core.AprLifecycleListener" /> <Service ... <Connector port="${port.prefix}80" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11Protocol" /> <Connector port="${port.prefix}82" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11AprProtocol" /> <Connector port="${port.prefix}84" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11NioProtocol" /> <Engine ...
bin/startup.sh
export CATALINA_HOME=/home/nutzer01/workshop/apache-tomcat-6.0.33 export LD_LIBRARY_PATH=${CATALINA_HOME}/lib
/etc/security/limits.conf
anhängen!
... * soft nofile 1024 * hard nofile 20000 ...
In der shell
nachfolgende Befehle absetzen
ulimit -n 20000 echo 20000 > /proc/sys/fs/file-max
/etc/sysctl.conf
anhängen!
fs.file-max = 20000
Es sollte in /etc/profiles.sh/ulimit.sh
mit folgendem Inhalt erstellt werden:
ulimit - n 20000
cd node73/conf openssl genrsa -des3 -out tomcatkey.pem 2048
Eingabe des Password „tomcat“ (s.u.)
openssl req -new -x509 -key tomcatkey.pem -out tomcatcert.pem -days 1095
Anlage der Zertifikatsinformationen (Common Name sollte der Name des Rechners sein!)
#Eingabe Country Name (2 letter code) [AU]:DE State or Province Name (full name) [Some-State]:NRW Locality Name (eg, city) []:Bochum Organization Name (eg, company) [Internet Widgits Pty Ltd]:LinuxHotel Organizational Unit Name (eg, section) []:noteboo16 Common Name (eg, YOUR name) []:notebook16 Email Address []:pr@objektpark.de
conf/server.xml
<Server ... <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Service ... <!-- Define a SSL HTTP/1.1 Connector on port xx43 --> <Connector port="${port.prefix}43" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11AprProtocol" scheme="https" secure="true" sslProtocol="TLS" SSLEnabled="true" SSLCertificateFile="${catalina.base}/conf/tomcatcert.pem" SSLCertificateKeyFile="${catalina.base}/conf/tomcatkey.pem" SSLPassword="tomcat" />
Zugang via SSL zum Tomcat mit openssl
openssl s_client -connect notebook16:7343
* http://www.madboa.com/geek/openssl/
GET /hello/index.jsp HTTP/1.0 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=3035FA551AD683F6939EDFA7A2CCE3D5.node73; Path=/hello/; Secure; HttpOnly Content-Type: text/html;charset=ISO-8859-1 Content-Length: 18 Date: Thu, 13 Sep 2012 10:50:02 GMT Connection: close Hello LinuxHotel!
Access https via url
curl --insecure https://192.168.1.218:7343/hello/index.jsp
last.sh
#!/bin/bash K=10; HTTPSA='https://192.168.1.218:7343/last/8k.bin' date +%M-%S-%N>curlres.txt for (( c=1; c<=$K; c++ )) do curl --insecure --silent $HTTPSA >/dev/null& done date +%M-%S-%N>>curlres.txt
keytool -keystore keystore -genkey -alias tomcat -keyalg RSA
Neues Kennwort erneut eingeben: Wie lautet Ihr Vor- und Nachname? [Unknown]: localhost Wie lautet der Name Ihrer organisatorischen Einheit? [Unknown]: development Wie lautet der Name Ihrer Organisation? [Unknown]: tomcat Wie lautet der Name Ihrer Stadt oder Gemeinde? [Unknown]: Bochum Wie lautet der Name Ihres Bundeslands? [Unknown]: NRW Wie lautet der Ländercode (zwei Buchstaben) für diese Einheit? [Unknown]: de Ist CN=localhost, OU=development, O=tomcat, L=Bochum, ST=NRW, C=de richtig? [Nein]: j
<Executor name="Catalina-Threads" namePrefix="Catalina-exec" maxThreads="200" minSpareThreads="50" /> <Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="${port.prefix}43" connectionTimeout="120000" executor="Catalina-Threads" scheme="https" secure="true" SSLEnabled="true" keystoreFile="${catalina.base}/conf/keystore" keystorePass="changeit" clientAuth="false" sslProtocol="TLS"/>
Aufruf
https://localhost:7343/hello/index.jsp
Selfsign Cert mit eignem Ablaufdatum von 360 Tagen
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048
Links
Download des Packet TomcatDeployer (apache-tomcat-6.0.35-deployer.tar.gz)
http://tomcat.apache.org/download-60.cgi
apache-tomcat-6.0.35-deployer/deployer.properties
url=http://localhost:7480/manager username=manager password=tomcat webapp=/home/nutzer01/workshop/node74/webapps/ROOT path=/myapp
Eine neue Anwendung mit vorkompilierten JSP befindet sich in der Instanz node74.
Tomcat Manager API
Alle MBeans
curl --user manager:tomcat http://192.168.1.218:7380/manager/jmxproxy?qry=*:*
Ein Mbean
curl --user manager:tomcat http://192.168.1.218:7380/manager/jmxproxy?qry=tomcat.jdbc:*
OK - Number of results: 1 Name: tomcat.jdbc:name="jdbc/DB",type=ConnectionPool,class=org.apache.tomcat.jdbc.pool.DataSource modelerType: org.apache.tomcat.jdbc.pool.jmx.ConnectionPool Size: 10 Idle: 10 Active: 0 NumIdle: 10 NumActive: 0 WaitCount: 0 Name: Tomcat Connection Pool[1-219730313] Username: root MaxAge: 0 MaxActive: 20 Password: Password not available as DataSource/JMX operation. DefaultTransactionIsolation: -1 DriverClassName: com.mysql.jdbc.Driver MaxIdle: 10 MinIdle: 10 InitialSize: 10 MaxWait: 15000 TestOnBorrow: true TestOnReturn: false TestOnConnect: false TimeBetweenEvictionRunsMillis: 10000 NumTestsPerEvictionRun: 0 MinEvictableIdleTimeMillis: 180000 TestWhileIdle: true Url: jdbc:mysql://127.0.0.1/tomcat?autoReconnect=true ValidationQuery: SELECT 1 ValidationInterval: 30000 AccessToUnderlyingConnectionAllowed: true RemoveAbandoned: true RemoveAbandonedTimeout: 60 LogAbandoned: false DbProperties: {user=root} JdbcInterceptors: org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx(threshold=2,maxQueries=1000) JmxEnabled: true FairQueue: true UseEquals: true AbandonWhenPercentageFull: 0 UseLock: false SuspectTimeout: 0 AlternateUsernameAllowed: false CommitOnReturn: false RollbackOnReturn: false UseDisposableConnectionFacade: true LogValidationErrors: false PropagateInterruptState: false PoolName: Tomcat Connection Pool[1-219730313] JdbcInterceptorsAsArray: Array[org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorDefinition] of length 4 org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorDefinition@46e5dce1 org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorDefinition@856140c org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorDefinition@4b3e241a org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorDefinition@5cb44d8d PoolSweeperEnabled: true
Anfrage an ein Attribute
curl --user manager:tomcat 'http://192.168.1.218:7380/manager/jmxproxy?get=tomcat.jdbc:name="jdbc/DB",type=ConnectionPool,class=org.apache.tomcat.jdbc.pool.DataSource&att=NumActive'
Result
OK - Attribute get 'tomcat.jdbc:name="jdbc/DB",type=ConnectionPool,class=org.apache.tomcat.jdbc.pool.DataSource' - NumActive = 0
Holte Anzahl der Busy Thread vom HTTP Connector
curl -X GET -u manager:tomcat "http://192.168.1.218:7480/manager/jmxproxy?get=Catalina:type=ThreadPool,name=%22http-bio-7480%22&att=currentThreadsBusy"
Ausgabe
OK - Attribute get 'Catalina:type=ThreadPool,name="http-bio-7480"' - currentThreadsBusy = 2
http://code.google.com/p/psi-probe
Manchmal gibt es Hänger beim Runterfahren von probe
Füge diese Startkonfiguration des Quartz Job Scheduler der Probe Anwendung hinzu:
bin/setenv.sh
export CATALINA_OPTS="${CATALINA_OPTS} -Dorg.quartz.scheduler.makeSchedulerThreadDaemon=true -Dorg.quartz.scheduler.skipUpdateCheck=true"
Weitere Parameter http://quartz-scheduler.org/documentation/quartz-1.x/configuration/ConfigMain
Hat auch nicht geklappt!
webapps/probe/WEB-INF/classes/shutdown
package shutdown; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.ContextLoader; import org.quartz.Scheduler; public class ShutDownHook implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { try { // Get a reference to the Scheduler and shut it down WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); Scheduler scheduler = (Scheduler) context.getBean("scheduler"); scheduler.shutdown(true); // Sleep for a bit so that we don't get any errors Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } @Override public void contextInitialized(ServletContextEvent arg0){ } }
Compile ShutDownHook.java
cd /workshop/node73/webapps/probe/WEB-INF/classes/shutdown javac -cp ~/workshop/apache-tomcat/lib/servlet-api.jar:../../lib/quartz-1.6.0.jar:../../lib/spring-core-2.5.6.SEC01.jar:../../lib/spring-web-2.5.6.SEC01.jar:../../lib/spring-context-2.5.6.SEC01.jar:../../lib/spring-beans-2.5.6.SEC01.jar ShutDownHook.java
WEB-INF/web.xml
<web-app ..> <display-name>PSI Probe for Apache Tomcat</display-name> <listener> <listener-class>shutdown.ShutDownHook</listener-class> </listener> ... </web-app>
http://code.google.com/p/javamelody/wiki/UserGuide
Installation in eine Anwendung.
cd workshop wget http://javamelody.googlecode.com/files/javamelody-1.29.0.zip mkdir javamelody-1.29.0-src cd javamelody-1.29.0-src unzip ../javamelody-1.29.0.zip mkdir ../node74/webapps/hello/WEB-INF/lib cp javamelody.jar ../node74/webapps/hello/WEB-INF/lib cp jrobin-1.5.9.1.jar ../node74/webapps/hello/WEB-INF/lib
../node74/webapps/hello/WEB-INF/web.xml
<filter> <filter-name>monitoring</filter-name> <filter-class>net.bull.javamelody.MonitoringFilter</filter-class> <init-param> <param-name>storage-directory</param-name> <param-value>${catalina.base}/javamelody</param-value> </init-param> </filter> <filter-mapping> <filter-name>monitoring</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>net.bull.javamelody.SessionListener</listener-class> </listener> <login-config> <auth-method>BASIC</auth-method> <realm-name>Monitoring</realm-name> </login-config> <security-role> <role-name>monitoring</role-name> </security-role> <security-constraint> <web-resource-collection> <web-resource-name>Monitoring</web-resource-name> <url-pattern>/monitoring</url-pattern> </web-resource-collection> <auth-constraint> <role-name>monitoring</role-name> </auth-constraint> <!-- if SSL enabled (SSL and certificate must then be configured in the server) <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> --> </security-constraint>
Add User to Realm Database
conf/tomcat-users.xml
<role rolename="monitoring"/> <user username="monitoring" password="monitoring" roles="monitoring"/>
evtl. restart des Servers oder Reload der Anwendung.. Zugriff auf die Monitoring-Informationen
http://localhost:7480/hello/monitoring
<b>Tipp</b> Auf Servlet API 3.0 WebContainer wie der Tomcat 7 oder 8 kann man Java Meldody auf als Plugin in einen bestehende Anwendung einbinden, da die javameldody.jar (>1.48) ein META-INF/web-fragment.xml enthält.
In der eigenen Anwendung wird javamelody aktive wenn es im WEB-INF/lib Verzeichnis ist.
Für eine externe Einbindung kann man den ClassLoader der Anwendung einbinden.
cd node74 mkdir plugin cp XXX/javamelody.jar plugins cp jrobin-1.5.9.1.jar plugins cd webapps/hello/ vi META-INF/context.xml
META-INF/context.xml
<Context> <Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="${catalina.base}/plugins/javamelody.jar;${catalina.base}/plugins/jrobin-1.5.9.1.jar" /> </Context>
Es ist darauf zu achten, das
metadata-complete
auf <i>true</i> steht und bei der Wahl der absoluten Reihenfolgen von Fragments JavaMelody enthalten ist.
cd plugins mkdir javamelody cd javamelody jar xf ../javamelody.jar cd META-INF vi web-fragment.xml cd .. # VORSICHT überschreibt orginal! jar cf ../javamelody.jar
web-fragment.xml
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd" version="3.0"> <name>JavaMelody</name> <filter> <filter-name>javamelody</filter-name> <filter-class>net.bull.javamelody.MonitoringFilter</filter-class> <async-supported>true</async-supported> </filter> <filter-mapping> <filter-name>javamelody</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>net.bull.javamelody.SessionListener</listener-class> </listener> <security-role> <role-name>monitoring</role-name> </security-role> <security-constraint> <web-resource-collection> <web-resource-name>Monitoring</web-resource-name> <url-pattern>/monitoring</url-pattern> </web-resource-collection> <auth-constraint> <role-name>monitoring</role-name> </auth-constraint> </security-constraint> </web-fragment>
Explizites einbinden
webapps/hello/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="false"> <login-config> <auth-method>BASIC</auth-method> <realm-name>Monitoring</realm-name> </login-config> <!-- only use JavaMelody --> <absolute-ordering> <name>JavaMelody</name> </absolute-ordering> </web-app>
http://www.jolokia.org/
http://prometheus.io/ https://github.com/prometheus/jmx_exporter
download linux 64 bit binary
cp jmx4prometheus.json node73/conf cp -r prom node73/webapps/prom node73/bin/restart.sh ./prometheus -config.file prometheus.conf
open localhost:9090/graph
prometheus.conf
# Global default settings. global: { scrape_interval: "15s" # By default, scrape targets every 15 seconds. evaluation_interval: "15s" # By default, evaluate rules every 15 seconds. # Attach these extra labels to all time series collected by this Prometheus instance. labels: { label: { name: "monitor" value: "tutorial-monitor" } } } # A job definition containing exactly one endpoint to scrape: Prometheus itself. job: { # The job name is added as a label `job={job-name}` to any time series scraped from this job. name: "prometheus" # Override the global default and scrape targets from this job every 5 seconds. scrape_interval: "5s" # Let's define a group of static targets to scrape for this job. In this # case, only one. target_group: { # These endpoints are scraped via HTTP. target: "http://localhost:9090/metrics" } } job: { name: "prom4jmx" scrape_interval: "15s" target_group: { labels: { label: { name: "zone" value: "de-berlin-1" } label: { name: "env" value: "dev" } } target: "http://127.0.0.1:7380/prom/metrics" } }
jmx4prometheus.conf
{ "lowercaseOutputName": true, "lowercaseOutputLabelNames": true, "rules": [ { "pattern": "Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+):", "name": "tomcat_$3_total", "labels": { "protocol":"$1", "port":"$2" }, "help": "Tomcat global $3", "type": "COUNTER", }, { "pattern": "Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount):", "name": "tomcat_servlet_$3_total", "labels": { "module":"$1", "servlet":"$2" }, "help": "Tomcat servlet $3 total", "type": "COUNTER", }, { "pattern": "Catalina<type=ThreadPool, name=\"(\w+-\w+)-(\d+)\"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount):", "name": "tomcat_threadpool_$3", "labels": { "protocol":"$1", "port":"$2" }, "help": "Tomcat threadpool $3", "type": "GAUGE", }, { "pattern": "Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions):", "name": "tomcat_session_$3_total", "labels": { "host":"$1", "context":"$2" }, "help": "Tomcat session $3 total", "type": "COUNTER", }, ] }
Installation der Mysql
sudo aptitude install mysql-server mysql -u root -p create database tomcat ; use tomcat ; create table nutzer( firstname varchar(80), lastname varchar(80)); insert into nutzer values ("Nutzer01", "linuxhotel" ); quit
Im Dialog ein Password setzen. (tomcat)
Laden des MYSQL Treibers
http://www.mysql.com/downloads/connector/j/
evtl. scp mysql-connector-java-5.1.17.zip nutzer24@notebook24:/home/nutzer24/workshop
unzip mysql-connector-java-5.1.17.zip cd mysql-connector-java-5.1.17 mkdir -p ../node74/lib cp mysql-connector-java-5.1.17-bin.jar ../node74/lib
Definition einer DB-Ressource im Tomcat
node74/conf/server.xml
<GlobaleNamingResources> ... <Resource name="jdbc/DB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1/tomcat" username="root" password="tomcat" maxActive="20" maxIdle="10" maxWait="15000" removeAbandoned="true" validationQuery="SELECT 1" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="180000" /> ... </GlobalNamingResources>
Anlage einer Anwendung die die Ressource nutzt
cd node74/webapps mkdir nutzer mkdir nutzer/META-INF/ mkdir nutzer/WEB-INF cd nutzer
META-INF/context.xml
<Context> <ResourceLink name="jdbc/DB" global="jdbc/DB" type="javax.sql.Datasource" /> </Context>
WEB-INF/web.xml
<web-app> <resource-ref> <description>JDBC DB</description> <res-ref-name>jdbc/DB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </web-app>
index.jsp
<%@ page import="javax.sql.*,javax.naming.*,java.sql.*" session="false" %> <% InitialContext initCtx = new InitialContext() ; Context envCtx = (Context)initCtx.lookup("java:comp/env/"); DataSource datasource = (DataSource) envCtx.lookup("jdbc/DB" ) ; Connection con = null; Statement stmt = null ; ResultSet srs = null; try { con = datasource.getConnection(); stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); srs = stmt.executeQuery( "SELECT firstname, lastname FROM nutzer"); while (srs.next()) { String firstName = srs.getString("firstname"); String lastName = srs.getString("lastname"); out.println(firstName + " " + lastName); } } finally { if(srs != null) srs.close(); if(stmt != null) stmt.close(); if(con != null) con.close(); } %>
Test der Anwendung
node74/bin/shutdown.sh cp apache-tomcat-6.0.32/conf/catalina.properties node74/conf node74/bin/startup.sh http://localhost:7480/nutzer/index.jsp
webapps/nutzer/insert.jsp
<%@ page import="javax.sql.*,javax.naming.*,java.sql.*" session="false" %> <html> <body> <h1>Nutzer anlegen</h1> <% InitialContext initCtx = new InitialContext() ; Context envCtx = (Context)initCtx.lookup("java:comp/env/"); DataSource datasource = (DataSource) envCtx.lookup("jdbc/DB" ) ; Connection con = null; Statement stmt = null ; try { con = datasource.getConnection(); stmt = con.createStatement(); for(int i = 0; i < 100; i++) { String name = "nutzer-" + i ; stmt.executeUpdate( "insert into nutzer values('" + name + "', 'linuxhotel"+ i + "')"); out.println("New user: " + name + "</br>"); } } finally { if(stmt != null) stmt.close(); if(con != null) con.close(); } %> </body> </html>
restart mysql
sudo /etc/init.d/mysql stop sudo /etc/init.d/mysql start
Parameter für Profile und Slow Query Detection
<Resource name="jdbc/DB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1/tomcat?autoReconnect=true&profileSQL=true&logSlowQueries=true&slowQueryThresholdMillis=2" username="root" password="tomcat" maxActive="20" maxIdle="10" maxWait="15000" removeAbandoned="true" validationQuery="SELECT 1" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="180000" />
Result
Thu Sep 13 15:19:03 CEST 2012 INFO: Profiler Event: [QUERY] at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) duration: 0 ms, connection-id: 2585, statement-id: 20540, resultset-id: 20776, message: SELECT firstname, lastname FROM nutzer Thu Sep 13 15:19:03 CEST 2012 INFO: Profiler Event: [FETCH] at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) duration: 1 ms, connection-id: 2585, statement-id: 20540, resultset-id: 20776 Thu Sep 13 15:19:03 CEST 2012 INFO: Profiler Event: [QUERY] at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) duration: 1 ms, connection-id: 2585, statement-id: 20541, resultset-id: 20777, message: SELECT 1 Thu Sep 13 15:19:03 CEST 2012 INFO: Profiler Event: [FETCH] at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) duration: 0 ms, connection-id: 2585, statement-id: 20541, resultset-id: 20777 Thu Sep 13 15:19:03 CEST 2012 INFO: Profiler Event: [SLOW QUERY] at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) duration: 5 ms, connection-id: 2585, statement-id: 20542, resultset-id: 20778, message: The following query was executed using no index, use 'EXPLAIN' for more details: SELECT firstname, lastname FROM nutzer Thu Sep 13 15:19:03 CEST 2012 INFO: Profiler Event: [QUERY] at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208) duration: 5 ms, connection-id: 2585, statement-id: 20542, resultset-id: 20778, message: SELECT firstname, lastname FROM nutzer
Download des Treibers von Maven Repo Tomcat > 7.0.19 tomcat-jdbc.jar Kopieren in die Tomcat Installation node73/lib Anpassen der Resource Definition durch hinzufügen von factory und jmxEnabled Restart des Tomcats
conf/server.xml
<Resource name="jdbc/DB" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1/tomcat?autoReconnect=true" username="root" password="tomcat" maxActive="20" maxIdle="10" maxWait="15000" removeAbandoned="true" validationQuery="SELECT 1" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="180000" jmxEnabled="true" jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx(threshold=2,maxQueries=1000)" />
In zwei Instanzen muss die Konfiguration geändert werden. Beide Instanzen müssen dann in einem Abstand von 30 Sekunden gestartet werden. Jeder Teilnehmer sollte ein exklusiven Port in sein Startskript schreiben das in den vier Instanzen node84,node85,node94 und node95 gleich ist.
node84/bin/startup.sh node94/bin/startup.sh
export CATALINA_OPTS="${CATALINA_OPTS} -Dcluster.prefix=416"
node85/bin/startup.sh node95/bin/startup.sh
export CATALINA_OPTS="${CATALINA_OPTS} -Dcluster.prefix=417"
conf/server.xml
Einfache Konfiguration
<Engine ... <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8" > <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" port="${cluster.prefix}00" /> <Receiver address="127.0.0.1" className="org.apache.catalina.tribes.transport.nio.NioReceiver" maxThreads="6" port="${cluster.prefix}${port.prefix}" selectorTimeout="5000" /> </Channel> </Cluster>
<Engine> ... <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Channel className="org.apache.catalina.tribes.group.GroupChannel" > <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="${cluster.prefix}00" frequency="500" dropTime="3000"/> </Channel> </Cluster> </Engine>
/etc/apache2/mods-available/jk.conf
JKWorkerProperty worker.list=loadbalancer,jkstatus JKWorkerProperty worker.node84.port=8409 JKWorkerProperty worker.node84.host=localhost JKWorkerProperty worker.node84.type=ajp13 JkWorkerProperty worker.node84.secret=tomcat JkWorkerProperty worker.node84.domain=cl24 JKWorkerProperty worker.node85.port=8509 JKWorkerProperty worker.node85.host=localhost JKWorkerProperty worker.node85.type=ajp13 JkWorkerProperty worker.node85.secret=tomcat JkWorkerProperty worker.node85.domain=cl25 JKWorkerProperty worker.node94.port=9409 JKWorkerProperty worker.node94.host=localhost JKWorkerProperty worker.node94.type=ajp13 JkWorkerProperty worker.node94.secret=tomcat JkWorkerProperty worker.node94.domain=cl24 JKWorkerProperty worker.node95.port=9509 JKWorkerProperty worker.node95.host=localhost JKWorkerProperty worker.node95.type=ajp13 JkWorkerProperty worker.node95.secret=tomcat JkWorkerProperty worker.node95.domain=cl25 JKWorkerProperty worker.loadbalancer.type=lb JKWorkerProperty worker.loadbalancer.balance_workers=node84,node85,node94,node95 JKWorkerProperty worker.jkstatus.type=status
nodeXX/conf/server.xml
... <Connector port="${port.prefix}09" executor="Catalina-Threads" protocol="org.apache.coyote.ajp.AjpProtocol" requiredSecret="tomcat" /> ...
/etc/apache2/sites-available/default
JkMount /ClusterTest* loadbalancer
sudo apache2clt restart cd workshop/cluster node84/bin/shutdown.sh -force node94/bin/shutdown.sh -force node85/bin/shutdown.sh -force node95/bin/shutdown.sh -force
wget http://192.168.1.189:2211/cluster/ClusterTest.war cp ClusterTest.war node84/webapps cp ClusterTest.war node94/webapps cp ClusterTest.war node85/webapps cp ClusterTest.war node95/webapps
Deployment der ClusterTest.war von der CD. Durchstarten der beiden Instanzen hintereinander mit einer kleinen Wartezeit 10sec - 1Min.
node84/bin/startup.sh node94/bin/startup.sh node85/bin/startup.sh node95/bin/startup.sh
conf/server.xml
<?xml version='1.0' encoding='utf-8'?> <Server port="${port.prefix}05" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/> <Listener className="org.apache.catalina.core.JasperListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" readonly="false" /> <Resource name="jdbc/DB" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1/tomcat?autoReconnect=true" username="root" password="tomcat" maxActive="100" maxIdle="10" maxWait="15000" removeAbandoned="true" validationQuery="SELECT 1" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="180000" jmxEnabled="true" jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx(threshold=2,maxQueries=1000)" /> <!-- <Resource name="jdbc/DB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1/tomcat?autoReconnect=true&profileSQL=true&logSlowQueries=true&slowQueryThresholdMillis=2" username="root" password="tomcat" maxActive="20" maxIdle="10" maxWait="15000" removeAbandoned="true" validationQuery="SELECT 1" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="180000" /> --> </GlobalNamingResources> <Service name="Catalina"> <Executor name="Catalina-Threads" namePrefix="Catalina-exec" maxThreads="200" minSpareThreads="50" /> <Connector port="${port.prefix}70" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11AprProtocol" /> <Connector port="${port.prefix}80" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11Protocol" /> <Connector port="${port.prefix}90" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11NioProtocol" /> <Connector port="${port.prefix}09" executor="Catalina-Threads" protocol="org.apache.coyote.ajp.AjpProtocol" /> <Connector port="${port.prefix}43" executor="Catalina-Threads" protocol="org.apache.coyote.http11.Http11AprProtocol" scheme="https" secure="true" sslProtocol="TLS" SSLEnabled="true" SSLCertificateFile="${catalina.base}/conf/tomcatcert.pem" SSLCertificateKeyFile="${catalina.base}/conf/tomcatkey.pem" SSLPassword="tomcat" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="node${port.prefix}"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access-" suffix=".log" pattern="%h %l "%u" "%{begin:yyyy-MM-dd hh:mm:ss.SSSZ}t" %{msec}t "%r" %s %b %D %S" resolveHosts="false" /> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8" > <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" port="${cluster.prefix}00" /> <Receiver address="127.0.0.1" className="org.apache.catalina.tribes.transport.nio.NioReceiver" maxThreads="6" port="${cluster.prefix}${port.prefix}" selectorTimeout="5000" /> </Channel> </Cluster> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" > </Host> </Engine> </Service> </Server>
<Cluster channelSendOptions="8" channelStartOptions="3" className="org.apache.catalina.ha.tcp.SimpleTcpCluster"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" domainReplication="true" notifyListenersOnReplication="true" /> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" port="${cluster.prefix}00" domain="test-domain"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" /> </Sender> <Receiver address="127.0.0.1" className="org.apache.catalina.tribes.transport.nio.NioReceiver" maxThreads="6" port="${cluster.prefix}${port.prefix}" selectorTimeout="5000" /> <Interceptor className="interceptors.DisableMulticastInterceptor" /> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" /> <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor"> <Member className="org.apache.catalina.tribes.membership.StaticMember" port="${cluster.prefix}74" host="127.0.0.1" domain="test-domain" uniqueId="{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}" /> </Interceptor> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" /> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;" /> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" /> </Cluster>
package interceptors; import org.apache.catalina.tribes.group.ChannelInterceptorBase; import org.apache.catalina.tribes.ChannelException; import org.apache.catalina.tribes.Channel; public class DisableMulticastInterceptor extends ChannelInterceptorBase { @Override public void start(int svc) throws ChannelException { svc = (svc & (~Channel.MBR_TX_SEQ)); super.start(svc); } }
Lösche Tomcat Version Numer in Fehlerreports des Tomcats
cd node74 mkdir -p lib/org/apache/catalina/util vi lib/org/apache/catalina/util/ServerInfo.properties bin/restart.sh
lib/org/apache/catalina/util/ServerInfo.properties
server.info=Apache Tomcat server.number= server.built=Mar 7 2014 02:18:35