从tomcat配置文件,看tomcat的原理

在tomcat的配置文件server.xml中,我们可以看到server service connector engine host context valve等元素。在日常工作中,常用到修改端口,日志格式等配置,对于其他这些元素的意义并未深入了解,今天有机会查找相关资料,总结如下。

 

tomcat的架构和常用组件

 

1 server组件

配置文件中内容  <Server port="8005" shutdown="SHUTDOWN">

tomcat会启动一个server实例(即一个JVM),它监听8005端口以接收shutdown命令,使用telnet连接8005端口可以直接用shutdown命令关闭tomcat,不过出于安全考虑,一般不允许远程连接。在同一台物理机上启动多个server实例,需要使用不同的端口。

server的相关属性:

className:用于实现此server容器的完全限定类的名称,默认为org.apache.catalina.core.StandardServer;

port:接收shutdown命令的端口,默认端口为8005,默认仅允许本机连接。

shutdown:发往server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN;

 

2 service组件

service用于关联一个引擎和与此引擎相关的连接器,连接器通过一个特定的端口和协议接收入站请求,并将请求转发至关联的引擎进程处理。所以,一个service要包含一个引擎和一个或多个连接器。

配置文件中 <Service name="Catalina">

这定义了一个名称为Catalina的service,这个名字也会在产生相关的日志信息时记录到日志文件中。

相关属性:

className: 用于实现service的类名,一般都是org.apache.catalina.core.StandardService。

name:此服务的名称,默认为Catalina;

 

3 connector组件

进入tomcat的请求可以根据tomcat的工作模式分类如下两类:

(1)tomcat作为应用服务器,请求来自前端的web服务器,如nginx apache iis等;

(2)tomcat作为独立服务器,请求来自web浏览器;

tomcat要根据不同情况、不同的工作模式定义好合适的连接器,才能正确的接收来自客户端的请求。一个引擎可以有一个或多个连接器,以适应多种请求方式。一般来说,常见于server.xml中的连接器有4种。

(1)http连接器   (2)ssl连接器  (3)AJP连接器  (4)proxy连接器

配置文件中 

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

连接器有很多属性,定义http连接器时必须定义的只有“port”,定义AJP连接器时必须定义的属性只有“protocol”(因为默认的协议为http)。

常用的属性有:

address:指定连接器监听的地址,默认为所有地址,即0.0.0.0;

maxthreads:支持最大并发连接数,默认为200;

port:监听端口;

protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3;

redirectPort:如果连接器支持的协议时http,当接收到https协议时,则转发到此属性定义的端口;

connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000;

enablelookups:是否通过request.getRemoteHost()进行dns查询以获取客户端的主机名,默认为true;

acceptCount:等待队列的最大长度,当tomcat的所有现场都处于繁忙时,新增的请求会进入等待队列;

 

4 engine组件

engine是servlet处理器的一个实例,及servlet引擎,默认为定义在server.xml中的catalina。engine需要defaultHost属性来为其定义一个接受所有发往非明确定义虚拟主机的请求的host组件。

配置文件中

<Engine name="Catalina" defaultHost="localhost">

常用属性:

defaultHost:Tomcat支持基于FQDN的虚拟主机,这些虚拟主机可以通过在Engine容器中定义多个不同的Host组件来实现;但如果此引擎的连接器收到一个发往非非明确定义虚拟主机的请求时则需要将此请求发往一个默认的虚拟主机进行处理,因此,在Engine中定义的多个虚拟主机的主机名称中至少要有一个跟defaultHost定义的主机名称同名;

name:组件的名称,用户日志和错误信息记录时区分不同的引擎;

engine容器中可以包含realm、host、listener和valve子容器。

 

5 host组件

位于engine中,接受并处理请求的主机或虚拟主机。

配置文件中 

<Host name=”localhost” appBase=”webapps”
unpackWARs=”true” autoDeploy=”true”
xmlValidation=”false” xmlNamespaceAware=”false”>
</Host>

常用的属性有

appBase:此host的webapps目录;

autoDeploy:在tomcat处于运行状态时,放置与appBase中的应用程序文件是否自动deploy;默认为true;

unpackWars:是否对war格式的归档文件自动进行解压;默认为true;

tomcat配置中的 autodeploy 和reloadable的区别是什么?

<Context docBase="xxx" path="/xxx" reloadable="true"/> 

<Context docBase="xxx" path="/xxx" autoDeploy="true"/>  

替换WEB-INF/lib目录中的jar文件或WEB-INF/classes目录中的class文件时,reloadable="true"会让修改生效(但代价不小),该选项适合调试。

在webapps目录中增加新的目录、war文件、修改WEB-INF/web.xmlautoDeploy="true"会新建或重新部署应用,该选项方便部署。

主机别名定义:

如果一个主机有两个或两个以上的主机名,额外的名称均可以以别名的形式进行定义,如下:
<Host name=”www.ttlsa.com” appBase=”webapps” unpackWARs=”true”>
<Alias>feiyu.com</Alias>
</Host>

 

6 context组件

一个context定义用于标识tomcat实例中的一个web应用程序;

配置文件中

 <Context path="" docBase="ning" debug="0" reloadable="true"/>

一般情况下,context定义与host标签下,在tomcat6以后的版本中,每个context的定义,也可以使用单独的xml文件。可以用于Context中的XML元素有Loader,Manager,Realm,Resources和WatchedResource。

常用属性

docBace:响应的web应用程序所在路径,也可以使用相对路径,其实路径为context所在的host中的appBase定义的路径;

path:相对于web服务器的根路径的URL,如果为空“”,表示为此webapp的根路径。

reloadable:是否允许自动加载此context相关的web应用程序的类,默认为true;

 

7、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实现;
 
 

下面是一个常见的使用UserDatabase的配置:

<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
resourceName=”UserDatabase”/>

下面是一个使用JDBC方式获取用户认证信息的配置:

<Realm className=”org.apache.catalina.realm.JDBCRealm” debug=”99″
driverName=”org.gjt.mm.mysql.Driver”
connectionURL=”jdbc:mysql://localhost/authority”
connectionName=”test” connectionPassword=”test”
userTable=”users” userNameCol=”user_name”
userCredCol=”user_pass”
userRoleTable=”user_roles” roleNameCol=”role_name” />

 

8 valve组件

Valve类似于过滤器,它可以工作于Engine和Host/Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序。Tomcat6中实现了多种不同的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进行工作;
 

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>

 

定义在host里的valve实现了日志功能

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />

 

 

tomcat的请求过程

1、用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。

2、Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。

3、Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。

4、Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。

5、path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。

6、构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。

7、Context把执行完之后的HttpServletResponse对象返回给Host。

8、Host把HttpServletResponse对象返回给Engine。

9、Engine把HttpServletResponse对象返回Connector。

10、Connector把HttpServletResponse对象返回给客户Browser。

 

参考地址**https://www.cnblogs.com/hggen/p/6264475.html**

posted @ 2019-01-29 11:43  lemonning  阅读(676)  评论(1编辑  收藏  举报