tomcat 安装
安装jdk
jdk我使用的是oracle的,如果下载请在oracle的官网上下载。或者你也可以使用openjdk,官网在http://openjdk.java.net/。
# tar xf jdk-7u79-linux-x64.tar.gz -C /usr/local/
# ln -sv /usr/local/jdk1.7.0_79 /usr/local/java
"/usr/local/java" -> "/usr/local/jdk1.7.0_79"
# cat /etc/profile.d/java.sh
export JAVA_HOME=/usr/local/java
export JAVA_CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
# . /etc/profile.d/java.sh
# java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (rhel-2.5.5.4.el6-x86_64 u79-b14)
OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)
安装tomcat
tomcat 请下载Binary Distributions安装,对于源码安装这里不做介绍。原先安装tomcat 没注意使用的是源码文件,并且安装方法是按二进制的安装的,之后就悲剧了!
# tar xf apache-tomcat-7.0.72.tar.gz -C /usr/local/
# ln -sv /usr/local/apache-tomcat-7.0.72 /usr/local/tomcat
"/usr/local/tomcat" -> "/usr/local/apache-tomcat-7.0.72"
# cat /etc/profile.d/tomcat.sh
export CATALINA_HOME=/usr/local/tomcat
export PATH=$PATH:$CATALINA_HOME/bin
# . /etc/profile.d/tomcat.sh
# catalina.sh start
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
# ss -tnlp |grep java
LISTEN 0 1 ::ffff:127.0.0.1:8005 :::* users:(("java",6497,46))
LISTEN 0 100 :::8009 :::* users:(("java",6497,43))
LISTEN 0 100 :::8080 :::* users:(("java",6497,42))
tomcat 配置文件
# ls /usr/local/tomcat/conf/
catalina.policy catalina.properties context.xml logging.properties server.xml tomcat-users.xml web.xml
server.xml:主配置文件之一,包含了诸多的重要配置,如IP地址、端口、虚拟主机、context路径等;
context.xml:每个webapp都可以有专用的配置文件,这些配置文件通常位于webapp应用程序目录下的WEB-INF目录中,用于定义会话管理器、JDBC等;conf/context.xml是为各webapp提供默认配置;
web.xml:定义tomcat实例启动时为所有装载至当前实例中的webapp定义的默认属性值;当然,某webapp也可以定义自己的属性来替代这里的默认值;
tomcat-users.xml:用户认证的账号和密码配置文件;
catalina.policy:当使用-security选项启动tomcat实例时会读取此配置文件来实现其安全运行策略;
catalina.properties:Java属性的定义文件,用于设定类加载器路径等,以及一些JVM性能相关的调优参数;
logging.properties:日志相关的配置信息;
tomcat 配置文件
Server组件
<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;
Service组件:
Service主要用于关联一个引擎和与此引擎相关的连接器,每个连接器通过一个特定的端口和协议接收入站请求交将其转发至关联的引擎进行处理。困此,Service要包含一个引擎、一个或多个连接器。
<Service name=”Catalina”>
这定义了一个名为Catalina的Service,此名字也会在产生相关的日志信息时记录在日志文件当中。
Service相关的属性:
className: 用于实现service的类名,一般都是org.apache.catalina.core.StandardService。
name:此服务的名称,默认为Catalina;
Connector组件:
进入Tomcat的请求可以根据Tomcat的工作模式分为如下两类:
Tomcat作为应用程序服务器:请求来自于前端的web服务器,这可能是Apache, IIS, Nginx等;
Tomcat作为独立服务器:请求来自于web浏览器;
Tomcat应该考虑工作情形并为相应情形下的请求分别定义好需要的连接器才能正确接收来自于客户端的请求。一个引擎可以有一个或多个连接器,以适应多种请求方式。
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="150" connectionTimeout="20000"
redirectPort="8443"/>
定义连接器时可以配置的属性非常多,但通常定义HTTP连接器时必须定义的属性只有“port”,定义AJP连接器时必须定义的属性只有"protocol",因为默认的协议为HTTP。以下为常用属性的说明:
address:指定连接器监听的地址,默认为所有地址,即0.0.0.0;
maxThreads:支持的最大并发连接数;
port:监听的端口;
protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3;
redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属性定义的端口;
connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为20000,即20秒;
enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名;默认为true;
acceptCount:设置等待队列的最大长度;通常在tomcat所有处理线程均处于繁忙状态时,新发来的请求将被放置于等待队列中;
Engine组件:
Engine是Servlet处理器的一个实例,即servlet引擎,默认为定义在server.xml中的Catalina。Engine需要defaultHost属性来为其定义一个接收所有发往非明确定义虚拟主机的请求的host组件。如前面示例中定义的:
<Engine name="Catalina" defaultHost="localhost">
常用的属性定义:
defaultHost:Tomcat支持基于FQDN的虚拟主机,这些虚拟主机可以通过在Engine容器中定义多个不同的Host组件来实现;但如果此引擎的连接器收到一个发往非非明确定义虚拟主机的请求时则需要将此请求发往一个默认的虚拟主机进行处理,因此,在Engine中定义的多个虚拟主机的主机名称中至少要有一个跟defaultHost定义的主机名称同名;
name:Engine组件的名称,用于日志和错误信息记录时区别不同的引擎;
Engine容器中可以包含Realm、Host、Listener和Valve子容器。
Host组件:
位于Engine容器中用于接收请求并进行相应处理的主机或虚拟主机,如前面示例中的定义:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>
常用属性说明:
appBase:此Host的webapps目录,即存放非归档的web应用程序的目录或归档后的WAR文件的目录路径;可以使用基于$CATALINA_HOME的相对路径;
autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true;
unpackWars:在启用此webapps时是否对WAR格式的归档文件先进行展开;默认为true;
Context组件:
Context在某些意义上类似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序;如下面的定义:
<!-- Tomcat Root Context -->
<Context path="" docBase="/web/webapps"/>
常用的属性定义有:
docBase:相应的Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径;切记,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字;
path:相对于Web服务器根路径而言的URI;如果为空“”,则表示为此webapp的根路径;如果context定义在一个单独的xml文件中,此属性不需要定义;
reloadable:是否允许重新加载此context相关的Web应用程序的类;默认为false;
Realm组件:
一个Realm表示一个安全上下文,它是一个授权访问某个给定Context的用户列表和某用户所允许切换的角色相关定义的列表。因此,Realm就像是一个用户和组相关的数据库。定义Realm时惟一必须要提供的属性是classname,它是Realm的多个不同实现,用于表示此Realm认证的用户及角色等认证信息的存放位置。
JAASRealm:基于Java Authintication and Authorization Service实现用户认证;
JDBCRealm:通过JDBC访问某关系型数据库表实现用户认证;
JNDIRealm:基于JNDI使用目录服务实现认证信息的获取;
MemoryRealm:查找tomcat-user.xml文件实现用户信息的获取;
UserDatabaseRealm:基于UserDatabase文件(通常是tomcat-user.xml)实现用户认证,它实现是一个完全可更新和持久有效的MemoryRealm,因此能够跟标准的MemoryRealm兼容;它通过JNDI实现;
Valve组件:
Valve类似于过滤器,它可以工作于Engine和Host/Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序。
AccessLogValve:访问日志Valve
ExtendedAccessValve:扩展功能的访问日志Valve
JDBCAccessLogValve:通过JDBC将访问日志信息发送到数据库中;
RequestDumperValve:请求转储Valve;
RemoteAddrValve:基于远程地址的访问控制;
RemoteHostValve:基于远程主机名称的访问控制;
SemaphoreValve:用于控制Tomcat主机上任何容器上的并发访问数量;
JvmRouteBinderValve:在配置多个Tomcat为以Apache通过mod_proxy或mod_jk作为前端的集群架构中,当期望停止某节点时,可以通过此Valve将用记请求定向至备用节点;使用此Valve,必须使用JvmRouteSessionIDBinderListener;
ReplicationValve:专用于Tomcat集群架构中,可以在某个请求的session信息发生更改时触发session数据在各节点间进行复制;
SingleSignOn:将两个或多个需要对用户进行认证webapp在认证用户时连接在一起,即一次认证即可访问所有连接在一起的webapp;
ClusterSingleSingOn:对SingleSignOn的扩展,专用于Tomcat集群当中,需要结合ClusterSingleSignOnListener进行工作;
GlobalNamingResources
应用于整个服务器的JNDI映射,此可以避免每个Web应用程序都需要在各自的web.xml创建,这在web应用程序以WAR的形式存在时尤为有用。它通常可以包含三个子元素:
Environment;
Resource;
ResourceEnvRef;
WatchedResource
WatchedResource可以用于Context中监视指定的webapp程序文件的改变,并且能够在监视到文件内容发生改变时重新装载此文件。
Listener
Listener用于创建和配置LifecycleListener对象,而LifecycleListener通常被开发人员用来创建和删除容器。
Loader
Java的动态装载功能是其语言功能强大表现之一,Servlet容器使用此功能在运行时动态装载servlet和它们所依赖的类。Loader可以用于Context中控制java类的加载。
Manager
Manger对象用于实现HTTP会话管理的功能,Tomcat6中有5种Manger的实现:
StandardManager:Tomcat6的默认会话管理器,用于非集群环境中对单个处于运行状态的Tomcat实例会话进行管理。当Tomcat关闭时,这些会话相关的数据会被写入磁盘上的一个名叫SESSION.ser的文件,并在Tomcat下次启动时读取此文件。
PersistentManager:当一个会话长时间处于空闲状态时会被写入到swap会话对象,这对于内存资源比较吃紧的应用环境来说比较有用。
DeltaManager:用于Tomcat集群的会话管理器,它通过将改变了会话数据同步给集群中的其它节点实现会话复制。这种实现会将所有会话的改变同步给集群中的每一个节点,也是在集群环境中用得最多的一种实现方式。
BackupManager:用于Tomcat集群的会话管理器,与DeltaManager不同的是,某节点会话的改变只会同步给集群中的另一个而非所有节点。
SimpleTcpReplicationManager:Tomcat4时用到的版本,过于老旧了。
Stores
PersistentManager必须包含一个Store元素以指定将会话数据存储至何处。这通常有两种实现方式:FileStore和JDBCStore。
Resources
经常用于实现在Context中指定需要装载的但不在Tomcat本地磁盘上的应用资源,如Java类,HTML页面,JSP文件等。
Cluster
专用于配置Tomcat集群的元素,可用于Engine和Host容器中。在用于Engine容器中时,Engine中的所有Host均支持集群功能。在Cluster元素中,需要直接定义一个Manager元素,这个Manager元素有一个其值为org.apache.catalina.ha.session.DeltaManager或org.apache.catalina.ha.session.BackupManager的className属性。同时,Cluster中还需要分别定义一个Channel和ClusterListener元素。
Channel:用于Cluster中给集群中同一组中的节点定义通信“信道”。Channel中需要至少定义Membership、Receiver和Sender三个元素,此外还有一个可选元素Interceptor。
Membership:用于Channel中配置同一通信信道上节点集群组中的成员情况,即监控加入当前集群组中的节点并在各节点间传递心跳信息,而且可以在接收不到某成员的心跳信息时将其从集群节点中移除。Tomcat6中Membership的实现是org.apache.catalina.tribes.membership.McastService。
Sender:用于Channel中配置“复制信息”的发送器,实现发送需要同步给其它节点的数据至集群中的其它节点。发送器不需要属性的定义,但可以在其内部定义一个Transport元素。
-
ransport:用于Sender内部,配置数据如何发送至集群中的其它节点。Tomcat6有两种Transport的实现:
PooledMultiSender:基于Java阻塞式IO,可以将一次将多个信息并发发送至其它节点,但一次只能传送给一个节点。
PooledParallelSener:基于Java非阻塞式IO,即NIO,可以一次发送多个信息至一个或多个节点。
Receiver:用于Channel定义某节点如何从其它节点的Sender接收复制数据,Tomcat6中实现的接收方式有两种BioReceiver和NioReceiver。
tomcat 实际使用
Context 组件和Host 组件
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="/bbs" docBase="bbs" />
<Context path="" docBase="/data/" />
</Host>
<Host name="www.test.com" appBase="/data/test">
<Context path="" docBase="ROOT" />
<Context path="/blog" docBase="blog" />
</Host>
[root@node1 data]# tree .
.
├── index.jsp
└── test
├── blog
│ └── index.jsp
└── ROOT
└── index.jsp
3 directories, 3 files
使用curl 查看路径:
[root@hpf-centos7 ~]# curl http://192.168.0.201:8080
<html>
<head>
<title>JSP Test Page</title>
</head>
<body>
hello world from /data
</body>
</html>
[root@hpf-centos7 ~]# curl http://192.168.0.201:8080/bbs/
<html>
<head>
<title>JSP Test Page</title>
</head>
<body>
hello world from bbs
</body>
</html>
[root@hpf-centos7 ~]# curl http://www.test.com:8080/
<html>
<head>
<title>JSP Test Page</title>
</head>
<body>
hello world from /data/ROOT
</body>
</html>
[root@hpf-centos7 ~]# curl http://www.test.com:8080/blog/
<html>
<head>
<title>JSP Test Page</title>
</head>
<body>
hello world from /data/blog
</body>
</html>
Value组件
tomcat 默认日志级别可以设置成common 与 combined ,也可以使用别的库设置日志模式,下面这两个预先设置好的格式对应的日志输出内容如下:
common 的值: %h %l %u %t "%r" %s %b
combined 的值: %h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"
举例:
系统默认的日志格式为common其输出如下:
192.168.0.101 - tomcat [03/Nov/2016:21:59:30 +0800] "GET /manager/html HTTP/1.1" 200 18928
192.168.0.101 - - [03/Nov/2016:21:59:30 +0800] "GET /manager/images/tomcat.gif HTTP/1.1" 200 2066
192.168.0.101 - - [03/Nov/2016:21:59:30 +0800] "GET /manager/images/asf-logo.gif HTTP/1.1" 200 7279
使用combined 形式输出日志:
192.168.0.100 - - [06/Nov/2016:23:34:13 +0800] "GET /3113082564649794e12313.jpg HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"
192.168.0.100 - - [06/Nov/2016:23:34:13 +0800] "GET /favicon.ico HTTP/1.1" 200 21630 "http://192.168.0.220:8080/3113082564649794e12313.jpg" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"
对 于各 fields 字段的含义请参照:
%a - Remote IP address
%A - Local IP address
%b - Bytes sent, excluding HTTP headers, or '-' if zero
%B - Bytes sent, excluding HTTP headers
%h - Remote host name (or IP address if resolveHosts is false)
%H - Request protocol
l - Remote logical username from identd (always returns '-')
%m - Request method (GET, POST, etc.)
%p - Local port on which this request was received
%q - Query string (prepended with a '?' if it exists)
%r - First line of the request (method and request URI)
%s - HTTP status code of the response
%S - User session ID
%t - Date and time, in Common Log Format
%u - Remote user that was authenticated (if any), else '-'
%U - Requested URL path
%v - Local server name
%D - Time taken to process the request, in millis
%T - Time taken to process the request, in seconds
%I - current request thread name (can compare later with stacktraces)
%{xxx}i for incoming headers
%{xxx}o for outgoing response headers
%{xxx}c for a specific cookie
%{xxx}r xxx is an attribute in the ServletRequest
%{xxx}s xxx is an attribute in the HttpSession
LNMT
在前端的http请求中不要直接将客户端的请求抛给tomcat,而是使用nginx或者httpd进行反向代理,这样tomcat 只处理动态的请求。下面是使用nginx反代tomcat中nginx的配置,很简单没啥技术含量。
location / {
proxy_pass http://localhost:8080/;
}
location ~* \.(jsp|do)$ {
proxy_pass http://localhost:8080;
}
LAMT
反向代理后端的tomcat 除了使用nginx以外还可以使用httpd,在使用httpd的时候可以有两种方式进行反代。
第一种方式:proxy_module, proxy_http_module
第二种方式:proxy_module, proxy_ajp_module
第一种方式的配置机制:
# yum install -y http httpd-devel
# vim /etc/httpd/conf.d/proxy_http.conf
<VirtualHost *:80>
ServerName www.test.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
<Location />
Require all granted
</Location>
</VirtualHost>
# systemctl start httpd
注意:这里Centos 7 中默认的httpd版本是2.4,由于httpd2.2和2.4有一定的差别这里配置时需要注意版本。
第二种配置虚拟主机:
将前面的的proxy_http.conf配置文件给更换成如下。
<VirtualHost *:80>
ServerName www.aaa.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / ajp://192.168.0.220:8009/
ProxyPassReverse / ajp://192.168.0.220:8009/
<Location />
Require all granted
</Location>
</VirtualHost>
注意:ajp协议的端口是8009,如果不更改端口则会报503的错误,具体错误如下:
Service Unavailable
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.