Tomcat
Apache Tomcat® 是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和JavaServer Page(JSP)的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。
由于Tomcat本身也内含了一个HTTP服务器,它也可以被视作一个单独的Web服务器。
但是,不能将Tomcat和Apache HTTP服务器混淆,Apache HTTP服务器是一个用C语言实现的HTTPWeb服务器;
这两个HTTP web server不是捆绑在一起的。Apache Tomcat包含了一个配置管理工具,也可以通过编辑XML格式的配置文件来进行配置。
快速开始
下载
文件夹说明
LICENSE NOTICE RELEASE-NOTES RUNNING.txt bin conf lib logs temp webapps work
/bin
——启动、关闭和其他脚本。.sh文件(用于Unix系统)是的函数副本。bat文件(用于Windows系统)。因为Win32命令行缺少某些功能,所以这里有一些额外的文件。
/conf
配置文件和相关dtd。这里最重要的文件是 server.xml。
它是容器的主配置文件。
/logs
默认情况下,日志文件在这里。
/webapps
这是你的网络应用程序要去的地方。
Docker tomcat
TODO
Tomcat 系统架构
架构
- server
Server是管理Service接口的,是Tomcat的一个顶级容器。管理着多个Service
- service
Service 是服务,管理这一个Container和多个Connector,Service的存在依赖于Server
- container
Container: 一个或者多个Container 可以对应一个Connector,这样就组成了一个Service,Service生命周期的由Server进行管理。
Container和Connector之间的交互媒介是Service,一个Service可以对应多个Connector,但是只能有一个Container容器
Server
Server 管理着所有的Service。它的主要作用是提供一个接口可以让其它程序能够访问这个Service集合,同时维护所有service的生命周期等。
Server在Tomcat中的标准实现是StandardServer。看一下其内部的addServiec方法
@Override
public void addService(Service service) {
service.setServer(this);
synchronized (servicesLock) {
Service results[] = new Service[services.length + 1];
System.arraycopy(services, 0, results, 0, services.length);
results[services.length] = service;
services = results;
if (getState().isAvailable()) {
try {
service.start();
} catch (LifecycleException e) {
// Ignore
}
}
// Report this property change to interested listeners
support.firePropertyChange("service", null, service);
}
}
可以看到,在添加Service到Server的时候,它是将原有数组的长度加一并将数组添加到最后。然后启动最新添加的Service
Service
Service 在Tomcat中的标准实现是StandardService,Service 可以说是一个标准的服务,拥有独立的端口号。
在 Service 中可以含有多个Connector和唯一的一个Container。
这样的设计模式可以允许例如SSL加密过的请求和没有经过SSL加密的请求在一个APP中同时存在。
Container
Container 由四个子容器组成:
Engine
表示整个Catalina Servlet引擎,是Container 只用最高层,用来管理Host 或者Context的实现
如果你想拦截每一个到Servlet的请求,可以通过
Host
表示一个Engine管理下的一个虚拟主机,比如你访问的Localhost就是一个虚拟主机。
作用是运行多个应用
其处理过程可以总结如下:
-
为特定的请求URL选择一个Context容器
-
把Context容器绑定到线程中
-
判断是否是一个异步请求
-
让Context去处理这个请求
-
Context执行invoke方法,进入管道中,由StandardContextValve(是ContextValve的标准实现类)处理
Context
Context 是用来管理Servlet的容器,Context就对应一个应用。所以我们部署应用时需要创建一个Context容器,Context负责管理Wrapper.
Wrapper
用来管理一个 Servlet 的生命周期
Connector
Connector 是Tomcat的连接器,主要任务是负责处理浏览器发送过来的请求,并创建一个Request和Response对象,用于和前端Client交换数据, 然后产生一个线程,并将Request对象和Response对象传递给线程,后面对这两个线程的处理就是Container的事情了。
-
实例化Connector,构造一个Connector对象
-
调用Connector的initIntenal方法,初始化Connetor
-
调用ProtocolHanlder的init方法,完成ProtocolHanlder的初始化。这个过程包括了创建线程池并创建一个线程处理浏览器请求
-
调用Connector的startIntenal方法,启动Connector
-
调用ProtocolHandler的start方法,启动Protocolhanlder
-
调用MapperListener的start方法,启动监听器程序
不同于Container ,Connector是一个实现类.其相当于一个容器处理基于Http的请求 。CoyoteAdapter,是connector和container的桥梁,经过这一步,请求就从connector传递到container中里了。Adapter
要注意的是:最先处理请求的Request是org.apache.coyote.Request类型,这是一个Tomcat中一个轻量级对象,完成基本的请求处理后很容易被JVM回收,那为什么不直接交给Connector.Request对象处理呢?由于后者是Servlet容器真正传递的对象其完成的职责比前者复杂,这里使用org.apache.coyote.Request主要减轻后者的任务负担,出于性能考虑才这么设计。
从 connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
这句代码中可以知道下一步的处理需要交给Container容器了。
Tomcat 实际使用
端口号及其修改
- conf/server.xml
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改 port 端口号即可。
ps: 一般真实环境,不建议使用默认,容易被攻击。
Connector 运行模式优化
-
bio(blocking I/O)
-
nio(non-blocking I/O)
-
apr(Apache Portable Runtime/Apache可移植运行库)
bio: 传统的Java I/O操作,同步且阻塞IO。
nio: JDK1.4开始支持,同步阻塞或同步非阻塞IO
aio(nio.2): JDK7开始支持,异步非阻塞IO
apr: Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地 提高Tomcat对静态文件的处理性能
- 调整
配置Tomcat运行模式改成是NIO模式,并配置连接池相关参数来进行优化:
<!--
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- protocol 启用 nio模式,(tomcat8默认使用的是nio)(apr模式利用系统级异步io) -->
<!-- minProcessors最小空闲连接线程数-->
<!-- maxProcessors最大连接线程数-->
<!-- acceptCount允许的最大连接数,应大于等于maxProcessors-->
<!-- enableLookups 如果为true,requst.getRemoteHost会执行DNS查找,反向解析ip对应域名或主机名-->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443
maxThreads=“500”
minSpareThreads=“100”
maxSpareThreads=“200”
acceptCount="200"
enableLookups="false"/>
开启 zip 优化
HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。
相对于普通的浏览过程HTML,CSS,Javascript , Text ,它可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,压缩效率惊人。
-
编码调优
-
jvm 调优
Tomcat 部署方式
-
直接把Web项目放在webapps下,Tomcat会自动将其部署
-
在 server.xml 文件上配置
<Context>
节点,设置相关的属性即可 -
通过Catalina来进行配置:进入到conf\Catalina\localhost文件下,创建一个xml文件,该文件的名字就是站点的名字。编写XML的方式来进行设置。
参考资料
- docker tomcat
- 架构
https://www.jianshu.com/p/3ede935ce8fe
http://blog.51cto.com/13732225/2164585
- 性能调优
https://blog.yoodb.com/yoodb/article/detail/1279
http://www.voidcn.com/article/p-tsumgpfk-bd.html