一、原理
1. 浏览器拜访服务器流程
-
- 用户输出申请到浏览器
- 浏览器发送 TCP 连贯申请
- 服务器接管到(疏忽 Nginx 等状况)申请并三次握手建设连贯
- 浏览器生成 HTTP 的数据包并发送
- 服务器收到并解析
- 服务器执行申请并封装后果发送
- 浏览器收到 HTTP 格局数据包并解析渲染
2. Tomcat 申请解决流程
首先,Tomcat 是一个 HTTP 服务器
Tomcat 中的 HTTP 服务器(Connectot 组件)在接管到申请之后把申请交给 Servlet 容器(Conntainer 组件)来解决(解耦),Servlet 容器通过 Servlet 接口调用业务类,Servlet 容器这一套内容叫做 Servlet 标准
3. Servlet 容器解决流程
- HTTP 服务器把申请信息应用 ServletRequest 对象封装
- 依据配置,找到 url 和 Servlet 的映射,调用 Servlet 容器中的某个具体 Servlet
- 如果 Servlet 还没有加载,就用反射机制创立这个 Servlet,并调用 Servlet 的 init 办法来实现初始化
- 调用这个 Servlet 的 service 办法解决申请,处理结果用 ServletResponse 对象封装
- ServletResponse 对象返回给 HTTP 服务器,HTTP 服务器把响应发给客户端
二、组件
1. 连接器组件 Coyote
客户端通过 Coyote 与服务器建设连贯,发送并响应申请
- Coyote 封装底层网络通信(Socket 申请及响应解决)
- Coyote 使 Catalina 容器(容器组件)与具体的申请及 I / O 操作解耦
- Coyote 将 Socket 输出封装 Request 对象,容器解决后,Catelina 通过 Response 对象将后果写入输入流
-
Coyote 去 负责具体应用层协定和传输层 io 相干内容
### 2. Servlet 容器 Catalina
Tomcat 由一系列可配置(server.xml)的组件形成的 web 容器,Catalina 是它的 Servlet 容器。某种方面说,Tomcat 就是一个 Servlet 容器,Catalina 是它的外围组件。
三、外围配置
配置文件 server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 根元素,定义一个 Server 实例,本人标签:Listener、GlobalNamingResources、Service-->
<!-- 监听 8005,状态为敞开状态 这里不须要改 -->
<Server port="8005" shutdown="SHUTDOWN">
<!-- 定义监听器 以下都无需更改 -->
<!-- 打印 JVM、操作系统相干日志 无需更改 -->
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- 加载销毁 Apr 无需更改 -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- 防止 JRE 内存溢出 -->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<!-- 加载和进行全局命名服务 -->
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<!-- 在 Context 进行时重建 Executor 池中的线程,防止 ThreadLocal 相干的内存透露 -->
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- 定义全局 JNDI 资源 个别无需批改 -->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<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 服务容器,一个 server 能够有很多 service -->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!-- 配置 Service 共享线程池 -->
<!-- 默认状况下,Service 并未增加共享线程池配置。如果咱们想增加一个线程池,能够在 <Service> 下增加如下配置:
name: 线程池名称,用于 Connector 中指定
namePrefix: 所创立的每个线程的名称前缀,一个独自的线程名称为 namePrefix+threadNumber
maxThreads: 池中最大线程数
minSpareThreads: 沉闷线程数,也就是外围池线程数,这些线程不会被销毁,会始终存在
maxIdleTime: 线程闲暇工夫,超过该工夫后,闲暇线程会被销毁,默认值为 6000(1 分钟),单位毫秒
maxQueueSize: 在被执行前最大线程排队数目,默认为 Int 的最大值,也就是狭义的有限。除非非凡状况,这个值 不须要更改,否则会有申请不会被解决的状况产生 prestartminSpareThreads: 启动线程池时是否启动 minSpareThreads 局部线程。默认值为 false,即不启动
threadPriority: 线程池中线程优先级,默认值为 5,值从 1 到 10
className: 线程池实现类,未指定状况下,默认实现类为 org.apache.catalina.core.StandardThreadExecutor。如果想应用自定义线程池首先须要实现 org.apache.catalina.Executor 接口
-->
<Executor
name="commonThreadPool"
namePrefix="thread-exec-"
maxThreads="200"
minSpareThreads="100"
maxIdleTime="60000"
maxQueueSize="Integer.MAX_VALUE"
prestartminSpareThreads="false"
threadPriority="5"
className="org.apache.catalina.core.StandardThreadExecutor"
/>
<!-- 一个 Service 容器能够有多个连接器,每个连贯启动一个线程 -->
<!--
port: 端口号,Connector 用于创立服务端 Socket 并进行监听,以期待客户端申请链接。如果该属性设置为 0,Tomcat 将会随机抉择一个可用的端口号给以后 Connector 应用
protocol: 以后 Connector 反对的拜访协定。默认为 HTTP/1.1,并采纳主动切换机制抉择一个基于 JAVA NIO 的链接器或者基于本地 APR 的链接器依据本地是否含有 Tomcat 的本地库断定)
connectionTimeOut: Connector 接管链接后的期待超时工夫,单位为毫秒。-1 示意不超时。redirectPort: 以后 Connector 不反对 SSL 申请,接管到了一个申请,并且也合乎 security-constraint 束缚,须要 SSL 传输,Catalina 主动将申请重定向到指定的端口。executor: 指定共享线程池的名称,也能够通过 maxThreads、minSpareThreads 等属性配置外部线程池。URIEncoding: 用于指定编码 URI 的字符编码,Tomcat8.x 版本默认的编码为 UTF-8 , Tomcat7.x 版本默认为 ISO-8859-1
-->
<!--org.apache.coyote.http11.Http11NioProtocol,非阻塞式 Java NIO 链接器 -->
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!-- 应用共享线程池, 不明确线程池就会有本人保护的线程池,造成资源节约 -->
<!--
<Connector port="8080"
protocol="HTTP/1.1"
executor="commonThreadPool"
maxThreads="1000"
minSpareThreads="100"
acceptCount="1000"
maxConnections="1000"
connectionTimeout="20000"
compression="on"
compressionMinSize="2048"
disableUploadTimeout="true"
redirectPort="8443"
URIEncoding="UTF-8" /> -->
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Servlet 引擎 -->
<!--
name: 用于指定 Engine 的名称,默认为 Catalina
defaultHost: 默认应用的虚拟主机名称,当客户端申请指向下边配置 Host 的主机有效时,将交由默认的虚拟主机解决,默认为 localhost
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<!-- Host 标签用于配置虚拟主机 -->
<!-- 默认解决,appbase 是相对路径,unpackWARs 解压 war 包,autoDeploy 主动部署 -->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- 拜访申请日志的 阀,寄存门路为相对路径 -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
<!-- 监听 www.abc.com:8080 -->
<Host name="www.abc.com" appBase="webapps1"
unpackWARs="true" autoDeploy="true">
<!--
docBase:Web 利用目录或者 War 包的部署门路。能够是绝对路径,也能够是绝对于 Host appBase 的 相对路径。path:Web 利用的 Context 门路。如果咱们 Host 名为 localhost,则该 web 利用拜访的根门路为: http://localhost:8080/web_demo。-->
<Context docBase="/Users/yingdian/web_demo" path="/web3"></Context>
<!-- 拜访申请日志的 阀,寄存门路为相对路径 -->
<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>
</Server>