由于官方仓库不能使用sun的java包,利用yum安装tomcat 时会默认安装openjdk 作为依赖包,但是openjdk并不好用。tomcat跟apache、php不同,它无需编译即可运行,故可不需要安装源码包,tar.gz包 和rpm包不存在内在性能问题。 并且tomcat 漏洞频出,如果手动安装的话,需要我们时刻维护它,而官方仓库中的tomcat 可以经常得到更新。
tomcat虽然简单,手动安装其实并不容易,常常考虑不周全,我见过很多人用root来运行tomcat,不多解释。
而rpm包很好的解决了这个问题。
下面的办法可以两全其美。
1、使用了sun的java
2、使用了仓库中的tomcat
环境centos 6 x64
下载并安装最新的sun jdk
# rpm -ivh jdk-7u25-linux-amd64.rpm
输出java 变量
# export JAVA_HOME=/usr/java/default # export PATH=$PATH:$JAVA_HOME/bin # export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar # cat > /etc/profile.d/java.sh <<EOF export JAVA_HOME=/usr/java/default export PATH=\$PATH:\$JAVA_HOME/bin export CLASSPATH=.:\$JAVA_HOME/jre/lib:\$JAVA_HOME/lib:\$JAVA_HOME/lib/tools.jar EOF
修正java 变量(解决多个java版本并存问题)
# alternatives --install /usr/bin/java java /usr/java/default/bin/java 400 # alternatives --install /usr/bin/java java /usr/java/default/jre/bin/java 400 # alternatives --install /usr/bin/javac javac /usr/java/default/bin/javac 400 # alternatives --set java /usr/java/default/bin/java # java -version java version "1.7.0_25" Java(TM) SE Runtime Environment (build 1.7.0_25-b15) Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
安装tomcat
# yum install tomcat tomcat-webapps tomcat-admin-webapps log4j mysql-connector-java
jvm优化(请根据具体情况优化)
# echo JAVA_HOME=\"/usr/java/default/\" >> /etc/tomcat/tomcat.conf # echo JAVA_OPTS=\"-server -Xms256M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M\" >>/etc/tomcat/tomcat.conf
tomcat启用apr或NIO,关闭客户端DNS查询,优化性能
# rpm-ivh epel-release-6-7.noarch.rpm # yum install tomcat-native apr apr-util --enablerepo=epel
apr 在安装后就会被tomcat自动启用,启动日志里会有“http-apr”字样。
使用NIO,修改/etc/tomcat/server.xml,
将
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
改为
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />
其它优化,伪装header,禁用dns查询,gzip压缩
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" server="nginx" enableLookups="false" URIEncoding="UTF-8" compression="on" useSendfile="false" compressionMinSize="2048" noCompressionUserAgents="gozilla,traviata" redirectPort="8443" />
编辑/etc/tomcat/tomcat-users.xml,
在大约倒数第10行左右添加一个用户,以便登录tomcat manager
<role rolename="manager"/> <user username="tomcat" password="s3cret" roles="manager"/>
隐藏tomcat版本号和标识
cd /usr/share/tomcat/lib mkdir -p org/apache/catalina/util echo "server.info=Apache tomcat" > org/apache/catalina/util/ServerInfo.properties
启动tomcat
# chkconfig tomcat on # /etc/init.d/tomcat start
查看进程
# ps aux |grep tomcat tomcat 2052 0.8 13.9 1304208 142968 ? Sl 22:10 0:05 /usr/bin/java -Xmx512M -Xms256M -classpath .:/usr/java/default/jre/lib:/usr/java/default/lib:/usr/java/default/lib/tools.jar:/usr/share/tomcat6/bin/bootstrap.jar:/usr/share/tomcat6/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat6 -Dcatalina.home=/usr/share/tomcat -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat6/temp -Djava.util.logging.config.file=/usr/share/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start root 2152 0.0 0.0 6420 592 pts/0 S+ 22:21 0:00 grep tomcat
如果没有防火墙,直接访问IP 加 8080端口即可看到tomcat的欢迎主页,侧边栏有tomcat manager。
页面测试
cat >/var/lib/tomcat/webapps/ROOT/test.jsp <<EOF <HTML> <HEAD> <TITLE>JSP测试页面</TITLE> </HEAD> <BODY> <%out.println("<h1>Hello World! </h1>");%> </BODY> </HTML> EOF
访问http://your-ip:8080/test.jsp,应该能看到hello world
查看日志,没有发现异常
# cat /var/log/tomcat/catalina.out Sep 02, 2013 10:23:04 PM org.apache.coyote.http11.Http11NioProtocol pause INFO: Pausing Coyote HTTP/1.1 on http-8080 Sep 02, 2013 10:23:04 PM org.apache.coyote.ajp.AjpAprProtocol pause INFO: Pausing Coyote AJP/1.3 on ajp-8009 Sep 02, 2013 10:23:05 PM org.apache.catalina.core.StandardService stop INFO: Stopping service Catalina Sep 02, 2013 10:23:05 PM org.apache.catalina.core.ApplicationContext log INFO: SessionListener: contextDestroyed() Sep 02, 2013 10:23:05 PM org.apache.catalina.core.ApplicationContext log INFO: ContextListener: contextDestroyed() Sep 02, 2013 10:23:05 PM org.apache.coyote.http11.Http11NioProtocol destroy INFO: Stopping Coyote HTTP/1.1 on http-8080 Sep 02, 2013 10:23:06 PM org.apache.coyote.ajp.AjpAprProtocol destroy INFO: Stopping Coyote AJP/1.3 on ajp-8009 Sep 02, 2013 10:23:08 PM org.apache.catalina.core.AprLifecycleListener init INFO: Loaded APR based Apache Tomcat Native library 1.1.22. Sep 02, 2013 10:23:08 PM org.apache.catalina.core.AprLifecycleListener init INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. Sep 02, 2013 10:23:08 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector INFO: Using a shared selector for servlet write/read Sep 02, 2013 10:23:08 PM org.apache.coyote.http11.Http11NioProtocol init INFO: Initializing Coyote HTTP/1.1 on http-8080 Sep 02, 2013 10:23:08 PM org.apache.coyote.ajp.AjpAprProtocol init INFO: Initializing Coyote AJP/1.3 on ajp-8009 Sep 02, 2013 10:23:08 PM org.apache.catalina.startup.Catalina load INFO: Initialization processed in 827 ms Sep 02, 2013 10:23:08 PM org.apache.catalina.core.StandardService start INFO: Starting service Catalina Sep 02, 2013 10:23:08 PM org.apache.catalina.core.StandardEngine start INFO: Starting Servlet Engine: Apache Tomcat/6.0.24 Sep 02, 2013 10:23:08 PM org.apache.catalina.startup.HostConfig deployDescriptor INFO: Deploying configuration descriptor host-manager.xml Sep 02, 2013 10:23:09 PM org.apache.catalina.startup.HostConfig deployDescriptor INFO: Deploying configuration descriptor manager.xml Sep 02, 2013 10:23:09 PM org.apache.catalina.startup.HostConfig deployDirectory INFO: Deploying web application directory ROOT Sep 02, 2013 10:23:09 PM org.apache.catalina.startup.HostConfig deployDirectory INFO: Deploying web application directory examples Sep 02, 2013 10:23:10 PM org.apache.catalina.core.ApplicationContext log INFO: ContextListener: contextInitialized() Sep 02, 2013 10:23:10 PM org.apache.catalina.core.ApplicationContext log INFO: SessionListener: contextInitialized() Sep 02, 2013 10:23:10 PM org.apache.catalina.startup.HostConfig deployDirectory INFO: Deploying web application directory sample Sep 02, 2013 10:23:10 PM org.apache.coyote.http11.Http11NioProtocol start INFO: Starting Coyote HTTP/1.1 on http-8080 Sep 02, 2013 10:23:10 PM org.apache.coyote.ajp.AjpAprProtocol start INFO: Starting Coyote AJP/1.3 on ajp-8009 Sep 02, 2013 10:23:10 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 1350 ms
网上有很多教程修改tomcat的监听端口,有些误人子弟。修改端口分为两种情况。
1)高位端口(1024以上),这里以8088为例。
编辑文件/etc/tomcat/server.xml,将下列文本内容中的8080改为8088即可
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
2)低位端口
如果想让tomcat监听在1024以下的端口,比如80,如果你按照上面的方法修改成功了,几乎可以证明,你在用特权用户(root)身份运行tomcat 。这犯了安全大忌。
这个时候需要曲线救国,可以让iptables帮忙将80端口的请求重定向到本机的8080端口。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
另一种更流行的方法是在tomcat前端加上nginx反向代理,或者叫tomcat的负载均衡集群,nginx额外还可以缓存静态文件,做动静分离。
示例配置文件/etc/nginx/conf.d/tomcat.conf,内容如下。
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=static:10m inactive=1d max_size=1g; upstream tomcat { server 127.0.0.1:8080; keepalive 16; } server { listen 80; server_name tomcat.example.com; charset utf-8; access_log /var/log/nginx/tomcat.access.log main; root /usr/share/nginx/html; index index.html index.htm index.jsp; location / { proxy_pass http://tomcat; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_http_version 1.1; proxy_set_header Connection ""; } location ~* ^.+\.(js|css|ico|gif|jpg|jpeg|png|html|htm)$ { proxy_pass http://tomcat ; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_cache static; proxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 302 1d; proxy_cache_valid 404 1m; proxy_cache_valid any 1h; add_header X-Cache $upstream_cache_status; expires 7d; } location ~ /\.ht { deny all; } }
反向代理的“坏处”是tomcat无法正确获得客户端地址,需要修改tomcat配置文件server.xml的日志配置
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" protocolHeader="x-forwarded-proto" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="tomcat8082_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
有时候,我们想给tomcat多开几个实例,每个实例监听不同的端口,其实tomcat配置文件支持多端口,也就是多加几个<Service>段,尽管与多实例有些区别,但效果上和多实例相同。
示例:
mkdir -p /usr/share/tomcat/webapps8081/ROOT mkdir -p /usr/share/tomcat/webapps8082/ROOT mkdir -p /etc/tomcat/Catalina chown -R tomcat:tomcat /etc/tomcat/Catalina
(tomcat 分别监听8080,8081,8082三个端口 ,配置文件/etc/tomcat/server.xml,注意字段 Service name 、Connect port、defaulthost、Host name、appBase)
<?xml version='1.0' encoding='utf-8'?> <Server port="8005" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JasperListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <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"> <Connector port="8080" protocol="HTTP/1.1" maxThreads="300" minSpareThreads="15" connectionTimeout="20000" enableLookups="false" redirectPort="8443" URIEncoding="UTF-8" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" protocolHeader="x-forwarded-proto" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> <Service name="Catalina8081"> <Connector port="8081" protocol="HTTP/1.1" maxThreads="300" minSpareThreads="15" connectionTimeout="20000" enableLookups="false" redirectPort="8443" URIEncoding="UTF-8" /> <Engine name="Catalina" defaultHost="tomcat8081"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="tomcat8081" appBase="webapps8081" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" protocolHeader="x-forwarded-proto" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="tomcat8081_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> <Service name="Catalina8082"> <Connector port="8082" protocol="HTTP/1.1" maxThreads="300" minSpareThreads="15" connectionTimeout="20000" enableLookups="false" redirectPort="8443" URIEncoding="UTF-8" /> <Engine name="Catalina" defaultHost="tomcat8082"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="tomcat8082" appBase="webapps8082" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" protocolHeader="x-forwarded-proto" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="tomcat8082_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> </Server>
tomcat目录下有upload目录,想要和程序分离?
解决方法,修改server.xml
添加一行
<Host ...... <Context docBase="/data/upload" path="/upload" /> </Host>
想要监控tomcat ? 你得开启jmx 功能
1、给tomcat添加jmx支持
cd /usr/share/tomcat/libs wget http://mirrors.ustc.edu.cn/apache/tomcat/tomcat-7/v7.0.64/bin/extras/catalina-jmx-remote.jar
2、给tomcat增加启动参数,修改/etc/tomcat6/tomcat.conf
JAVA_OPTS=-Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true
3、nagios jmx 插件
https://exchange.nagios.org/directory/Plugins/Java-Applications-and-Servers/check_jmx/details
(未完待续)
更新20150911
1、由tomcat6更新为tomcat7
2、添加nginx反向代理内容
更新20161018
1、添加程序与上传文件的分离