共计 5846 个字符,预计需要花费 15 分钟才能阅读完成。
一、原理
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> |
正文完