标签:基于ip class nginx cas base inf orm r文件 jvm
一、Tomcat体系结构
二、Tomcat管理
三、httpd反代tomcat
四、tomcat cluster
tomcat应该是java程序员最熟悉的servlet容器了,作为一个用java实现的web应用程序服务器,下图是tomcat的体系结构
一个常见的Tomcat配置文件以下xml结构所示,对应上图的不同组件,每个组件都是个Java Class
<Server> <Service> <connector/> <connector/> <Engine> <Host /> <Host> <Context/> ... </Host> </Engine> </Service> </Server>
下文会对每个组件详细说明
tomcat的安装:...略,注意安装完配置环境变量
export CATALINA_BASE=/usr/local/tomcat
export PATH=$CATALINA_BASE/bin:$PATH
tomcat的目录结构:
tomcat的配置文件:
以下实例是适用于CentOS6的chkconfig服务脚本
#!/bin/bash # # chkconfig: - 95 15 # description: Tomcat start/stop/status script #Location of JAVA_HOME (bin files) export JAVA_HOME= #Add Java binary files to PATH export PATH=$JAVA_HOME/bin:$PATH #CATALINA_HOME is the location of the configuration files of this instance of Tomcat CATALINA_HOME=/usr/local/tomcat #TOMCAT_USER is the default user of tomcat TOMCAT_USER=www #TOMCAT_USAGE is the message if this script is called without any options TOMCAT_USAGE="Usage: $0 {\e[00;32mstart\e[00m|\e[00;31mstop\e[00m|\e[00;32mstatus\e[00m|\e[00;31mrestart\e[00m}" #SHUTDOWN_WAIT is wait time in seconds for java proccess to stop SHUTDOWN_WAIT=20 tomcat_pid() { echo `ps -ef | grep $CATALINA_HOME | grep -v grep | tr -s " "|cut -d" " -f2` } start() { pid=$(tomcat_pid) if [ -n "$pid" ];then echo -e "\e[00;31mTomcat is already running (pid: $pid)\e[00m" else echo -e "\e[00;32mStarting tomcat\e[00m" if [ `user_exists $TOMCAT_USER` = "1" ];then su $TOMCAT_USER -c $CATALINA_HOME/bin/startup.sh else $CATALINA_HOME/bin/startup.sh fi status fi return 0 } status(){ pid=$(tomcat_pid) if [ -n "$pid" ];then echo -e "\e[00;32mTomcat is running with pid: $pid\e[00m" else echo -e "\e[00;31mTomcat is not running\e[00m" fi } stop() { pid=$(tomcat_pid) if [ -n "$pid" ];then echo -e "\e[00;31mStoping Tomcat\e[00m" $CATALINA_HOME/bin/shutdown.sh let kwait=$SHUTDOWN_WAIT count=0; until [ `ps -p $pid | grep -c $pid` = ‘0‘ ] || [ $count -gt $kwait ] do echo -n -e "\e[00;31mwaiting for processes to exit\e[00m\n"; sleep 1 let count=$count+1; done if [ $count -gt $kwait ];then echo -n -e "\n\e[00;31mkilling processes which didn‘t stop after $SHUTDOWN_WAIT seconds\e[00m" kill -9 $pid fi else echo -e "\e[00;31mTomcat is not running\e[00m" fi return 0 } user_exists(){ if id -u $1 >/dev/null 2>&1; then echo "1" else echo "0" fi } case $1 in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo -e $TOMCAT_USAGE ;; esac exit 0 Sun Aug 2 20:13:23 CST 2015
<Server port=”8005” shutdown=”SHUTDOWN”>
这会让Tomcat6启动一个server实例(即一个JVM),它监听在8005端口以接收shutdown命令。各Server的定义不能使用同一个端口,这意味着如果在同一个物理机上启动了多个Server实例,必须配置它们使用不同的端口。这个端口的定义用于为管理员提供一个关闭此实例的便捷途径,因此,管理员可以直接telnet至此端口使用SHUTDOWN命令关闭此实例。不过,基于安全角度的考虑,这通常不允许远程进行。
Server的相关属性:
className: 用于实现此Server容器的完全限定类的名称,默认为org.apache.catalina.core.StandardServer;
port: 接收shutdown指令的端口,默认仅允许通过本机访问,默认为8005;
shutdown:发往此Server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN;
官方解释:A Service is a group of one or more Connectors that share a single Container to process incoming requests. This arrangment allows, for example, a non-SSL and ssl connector to share the same population of web apps.
<Service name=”Catalina”>
Service主要用于关联一个引擎和与此引擎相关的连接器,每个连接器通过一个特定的端口和协议接收入站请求交将其转发至关联的引擎进行处理。困此,Service要包含一个引擎、一个或多个连接器。
这定义了一个名为Catalina的Service,此名字也会在产生相关的日志信息时记录在日志文件当中。
Service相关的属性:
className: 用于实现service的类名,一般都是org.apache.catalina.core.StandardService。
name:此服务的名称,默认为Catalina;
官网解释:
HTTP: The Http connnectors is setup by default with Tomcat, and is ready to use. This connector features the lowest latency and best overall performance.
AJP: When using a single server, the performance when using a native webserver in front of the Tomcat instance is most of the time significantly worse than a standalone Tomcat with its default HTTP connector, even if a large part of the web application is made of static files. If integration with the native webserver is needed for any reason, an AJP connector will provide faster performance than proxied HTTP. AJP clustering is the most efficient from the Tomcat perspective. It is otherwise functionally equivalent to HTTP clustering.
进入Tomcat的请求可以根据Tomcat的工作模式分为如下两类:
Tomcat作为应用程序服务器:请求来自于前端的web服务器,这可能是Apache, IIS, Nginx等;
Tomcat作为独立服务器:请求来自于web浏览器;
Tomcat应该考虑工作情形并为相应情形下的请求分别定义好需要的连接器才能正确接收来自于客户端的请求。一个引擎可以有一个或多个连接器,以适应多种请求方式。
定义连接器可以使用多种属性,有些属性也只适用于某特定的连接器类型。一般说来,常见于server.xml中的连接器类型通常有4种:
1) HTTP连接器
2) SSL连接器
3) AJP 1.3连接器
<Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443"/>
定义连接器时可以配置的属性非常多,但通常定义HTTP连接器时必须定义的属性只有“port”,定义AJP连接器时必须定义的属性只有"protocol",因为默认的协议为HTTP。以下为常用属性的说明:
下面是一个定义了多个属性的SSL连接器:
<Connector port="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />
Tomcat HTTP的连接器分为三类:
(1) 基于Java的HTTP/1.1连接器,这也是Tomcat6默认使用的连接器;它是Tomcat作为Standalone模式工作时所用到的连接器,可直接响应来自用户浏览器的请求;默认是8080端口
(2) 基于Java开发的NIO HTTP/1.1连接器,非阻塞式IO和Comnet,在基于库向tomcat发起请求时,此连接器表现不俗;
(3) C/C++开发的native APR HTTP/1.1连接器,在负载较大的场景中,性能不错,APR就是Apache Protable Runtime,它是一个能让开发者采用与平台无关分风格来开发C/C++代码本地库,可以很好的跨Linux和Unix等平台工作。此连接器从三个主要方面优化了系统性能并提升了系统的伸缩能力:(1)使用sendfile()内核模式调用发送大的静态文件;(2) 仅使用一个native code保持大量的连接;(3) 使用能够加速SSL请求处理的OpenSSL本地代码;
启用APR连接器的条件:
1) 将连接器的protocol属性设定为org.apache.coyote.http11.Http11AprProtocol;
2) APR的库文件已经在系统库文件的搜索路径内;
AJP(Apache JServ Protocol):
AJP是面向数据包的基于TCP/IP的协议,它在Apache和Tomcat的实例之间提供了一个专用的通信信道。目前常用AJP协议的版本是1.3,它主要有以下特征:
1) 在快速网络有着较好的性能表现,支持数据压缩传输;
2) 支持SSL,加密及客户端证书;
3) 支持Tomcat实例集群;
4) 支持在apache和tomcat之间的连接的重用;
附:如何安装apr
事先安装apr-devel包,而后编译安装tomcat的APR JNI。安装方法如下
# cd $CATALINA_HOME/bin # tar xf tomcat-native.tar.gz # cd tomcat-native-1.1.22-src/jni/native/ # ./configure --with-apr=/usr --with-ssl --with-apxs # make && make install # echo "/usr/local/apr/lib/" > /etc/ld.so.conf.d/apr.conf # ldconfig
<Engine name="Catalina" defaultHost="localhost">
Engine是Servlet处理器的一个实例,即servlet引擎,默认为定义在server.xml中的Catalina。Engine需要defaultHost属性来为其定义一个接收所有发往非明确定义虚拟主机的请求的host组件。如前面示例中定义的:
常用的属性定义:
defaultHost:Tomcat支持基于FQDN的虚拟主机,这些虚拟主机可以通过在Engine容器中定义多个不同的Host组件来实现;但如果此引擎的连接器收到一个发往非非明确定义虚拟主机的请求时则需要将此请求发往一个默认的虚拟主机进行处理,因此,在Engine中定义的多个虚拟主机的主机名称中至少要有一个跟defaultHost定义的主机名称同名;
name:Engine组件的名称,用于日志和错误信息记录时区别不同的引擎;
jvmRoute=
Engine容器中可以包含Realm、Host、Listener和Valve子容器。
常用属性说明:
1) appBase:此Host的webapps目录,即存放非归档的web应用程序的目录或归档后的WAR文件的目录路径;可以使用基于$CATALINA_HOME的相对路径;
2) autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true;
3) unpackWars:在启用此webapps时是否对WAR格式的归档文件先进行展开;默认为true;
虚拟主机定义示例:
<Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps"> <Context path="" docBase="ROOT"/> <Context path="/bbs" docBase="/web/bss" reloadable="true" crossContext="true"/> </Host> <Host name="mail.magedu.com" appBase="/web/mail"> <Context path="/" docBase="ROOT"/> </Host> </Engine>
如果一个主机有两个或两个以上的主机名,额外的名称均可以以别名的形式进行定义,如下
<Host name="www.magedu.com" appBase="webapps" unpackWARs="true"> <Alias>magedu.com</Alias> </Host>
Context在某些意义上类似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序;如下面的定义:
<!-- Tomcat Root Context --> <Context path="" docBase="/web/webapps"/> <!-- buzzin webapp --> <Context path="/bbs" docBase="/web/threads/bbs" reloadable="true"> </Context> <!-- chat server --> <Context path="/chat" docBase="/web/chat"/> <!-- darian web --> <Context path="/darian" docBase="darian"/>
在Tomcat6中,每一个context定义也可以使用一个单独的XML文件进行,其文件的目录为$CATALINA_HOME/conf/<engine name>/<host name>。可以用于Context中的XML元素有Loader,Manager,Realm,Resources和WatchedResource。
常用的属性定义有:
1) docBase:相应的Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径;切记,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字;
2) path:相对于Web服务器根路径而言的URI;如果为空“”,则表示为此webapp的根路径;如果context定义在一个单独的xml文件中,此属性不需要定义;
3) reloadable:是否允许重新加载此context相关的Web应用程序的类;默认为false;
官网:A Valve is a request processing component associated with a particular Container. A series of Valves are generally associated with each other into a Pipeline. The detailed contract for a Valve is included in the description of the invoke() method below.
HISTORICAL NOTE: The "Valve" name was assigned to this concept because a valve is what you use in a real world pipeline to control and/or modify flows through it.
用来拦截请求并在将其转至目标之前进行某种处理操作,类似于Servlet规范中定义的过滤器。Valve可以定义在任何容器类的组件中。Valve常被用来记录客户端请求、客户端IP地址和服务器等信息,这种处理技术通常被称作请求转储(request dumping)。请求转储valve记录请求客户端请求数据包中的HTTP首部信息和cookie信息文件中,响应转储valve则记录响应数据包首部信息和cookie信息至文件中。
RemoteHostValve和RemoteAddrValve可以分别用来实现基于主机名称和基于IP地址的访问控制,控制本身可以通过allow或deny来进行定义,这有点类似于Apache的访问控制功能;如下面的Valve则实现了仅允许本机访问/probe:
<Context path="/probe" docBase="probe"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1"/> </Context>
其中相关属性定义有:
1) className:相关的java实现的类名,相应于分别应该为org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve;
2) allow:以逗号分开的允许访问的IP地址列表,支持正则表达式,因此,点号“.”用于IP地址时需要转义;仅定义allow项时,非明确allow的地址均被deny;
3) deny: 以逗号分开的禁止访问的IP地址列表,支持正则表达式;使用方式同allow;
tomcat作为应用程序服务器,并不适合处理静态资源,前端一般都会放置一个代理服务器,可以是nginx或者httpd。前面说过,tomcat支持2大类的Connecotr,nginx只能反代http类的协议,而httpd服务器同时支持http协议和ajp协议。下面演示httpd的二种反代配置,使用httpd的虚拟主机即可。
第一种:Client --> http --> httpd --> reverse_proxy_module (http) --> tomcat (http connector)
httpd需要模块proxy_module, proxy_http_module
配置如下:
<VirtualHost *:80> ServerName tc1.ysz214.com # 关闭正向代理 ProxyRequests Off ProxyVia On # 支持tomcat的虚拟主机机制 ProxyPreserveHost On # 权限控制 <Proxy *> Require all granted </Proxy> # 反向代理 ProxyPass / http://localhost:8080/ # ProxyPassReverse / http://localhost:8080/ # 访问控制 <Location /> Require all granted </Location>
</VirtualHost>
第二种只要将8080端口修改为tomcat的8009端口,默认监听ajp连接器的端口是8009
Client --> http --> httpd --> reverse_proxy_module (ajp) --> tomcat (ajp connector)
依赖于模块proxy_module, proxy_ajp_module
<VirtualHost *:80> ServerName tc1.ysz214.com # 关闭正向代理 ProxyRequests Off ProxyVia On # 支持tomcat的虚拟主机机制 ProxyPreserveHost On # 权限控制 <Proxy *> Require all granted </Proxy> # 反向代理 ProxyPass / ajp://localhost:8009/ # ProxyPassReverse / ajp://localhost:8009/ # 访问控制 <Location /> Require all granted </Location> </VirtualHost>
利用http connector,需要httpd三个模块:
mod_proxy
mod_proxy_http
mod_proxy_balancer
实现负载均衡:
byrequests
bybusyness
<proxy balancer://lbcluster1> BalancerMember http://172.16.100.68:8080 loadfactor=10 route=TomcatA BalancerMember http://172.16.100.69:8080 loadfactor=10 route=TomcatB ProxySet lbmethod=bybusyness </proxy> <VirtualHost *:80> ServerName web1.magedu.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / balancer://lbcluster1/ ProxyPassReverse / balancer://lbcluster1/ <Location /> Require all granted </Location>
<Location /balancer-manager>
SetHandler balancer-manager
ProxyPass !
Require all granted
</Location>
</VirtualHost>
如果想要实现会话粘性
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <proxy balancer://lbcluster1> BalancerMember http://172.16.100.68:8080 loadfactor=10 route=TomcatA BalancerMember http://172.16.100.69:8080 loadfactor=10 route=TomcatB ProxySet stickysession=ROUTEID </proxy> <VirtualHost *:80> ServerName web1.magedu.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / balancer://lbcluster1/ ProxyPassReverse / balancer://lbcluster1/ <Location /> Require all granted </Location> </VirtualHost>
说明,管理接口
<Location /balancer-manager> SetHandler balancer-manager Proxypass ! Order Deny,Allow Allow from all </Location>
跟上面的类似,只是换成ajp协议,建议使用ajp,不要使用第三种方式jk的方式.
#Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <proxy balancer://lbcluster1> BalancerMember ajp://172.16.100.68:8009 loadfactor=10 route=TomcatA BalancerMember ajp://172.16.100.69:8009 loadfactor=10 route=TomcatB ProxySet stickysession=ROUTEID </proxy> 1 <VirtualHost *:80> ServerName web1.magedu.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / balancer://lbcluster1/ ProxyPassReverse / balancer://lbcluster1/ <Location /> Require all granted </Location> </VirtualHost>
mod_jk 模块可以在tomcat官网Connectors中找到下载,需要额外编译安装
yum install httpd-devel tar zxf tomcat-connectors-VERSION.tar.gz cd tomcat-connectors-VERSION/native ./configure --with-apxs/usr/bin/apxs make make install
(1) 反代配置
LoadModule jk_module modules/mod_jk.so JkWorkersFile /etc/httpd/conf.d/workers.properties JkLogFile logs/mod_jk.log JkLogLevel debug JkMount /* TomcatA JkMount /status/ stat1
workers配置文件:workers.properties
worker.list=TomcatA,stat1 worker.TomcatA.port=8009 worker.TomcatA.host=172.16.100.68 worker.TomcatA.type=ajp13 worker.TomcatA.lbfactor=1 worker.stat1.type = status
说明: 其中ajp13是后端服务器协议,ajp,版本是1.3
(2) 负载均衡配置
LoadModule jk_module modules/mod_jk.so JkWorkersFile /etc/httpd/conf.d/workers.properties JkLogFile logs/mod_jk.log JkLogLevel debug JkMount /* lbcluster1 JkMount /status/ stat1
worker.list = lbcluster1,stat1 worker.TomcatA.type = ajp13 worker.TomcatA.host = 172.16.100.68 worker.TomcatA.port = 8009 worker.TomcatA.lbfactor = 1 worker.TomcatB.type = ajp13 worker.TomcatB.host = 172.16.100.69 worker.TomcatB.port = 8009 worker.TomcatB.lbfactor = 1 worker.lbcluster1.type = lb worker.lbcluster1.sticky_session = 0 worker.lbcluster1.balance_workers = TomcatA, TomcatB worker.stat1.type = status
如果要会话绑定, tomcat需要配置Engine属性中的jvmRoute,且和worker名称一致
功能:一个通过多播协议进行的会话集群
基本没啥人用,这里随便说下怎么配置
(1) 配置server.xml
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.101.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.1.212" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
说明:其中228.101.0.4是多播地址,本地的地址是192.168.1.212
(2) 每个需要被集群管理的webapp中要配置web.xml
WEB-INF/web.xml中添加
<distributable/>
标签:基于ip class nginx cas base inf orm r文件 jvm
原文地址:http://www.cnblogs.com/carl10086/p/5998706.html