apache tomcat=Apache http server + Tomcat
Apache http server:网页服务器,只支持静态网页。C语言开发的。
Tomcat:是应用(java)服务器,它只是一个servlet容器,是Apache的扩展,处理动态网页部分。Java语言开发的。
Tomcat是Apache Jakarta的子项目之一,是Sun公司推荐的JSP、Servlet容器。是开源的轻量级Web应用服务器,使用非常广泛,作为一款优秀的应用服务器,Tomcat提供了数据库连接池、SSL、Proxy等许多通用组件功能,其中连接池是4.0以上版本的新增功能,应用非常广泛。其中,server.xml的每一个元素都对应了Tomcat中的一个组件;通过对xml文件中元素的配置,可以实现对Tomcat中各个组件的控制。
server.xml中各个标签的具体含义和使用可以参考:
https://www.cnblogs.com/kismetv/p/7228274.html#title2
总体上来说核心组件:
Server:Server元素在最顶层,代表整个Tomcat容器,因此它必须是server.xml中唯一一个最外层的元素。一个Server元素中可以有一个或多个Service元素。Server的主要任务,就是提供一个接口让客户端能够访问到这个Service集合,同时维护它所包含的所有的Service的声明周期,包括如何初始化、如何结束服务、如何找到客户端要访问的Service。
Service:Service的作用,是在Connector和Engine外面包了一层,把它们组装在一起,对外提供服务。一个Service可以包含多个Connector,但是只能包含一个Engine;其中Connector的作用是从客户端接收请求,Engine的作用是处理接收进来的请求。
Connector:Connector的主要功能,是接收连接请求,创建Request和Response对象用于和请求端交换数据;然后分配线程让Engine来处理这个请求,并把产生的Request和Response对象传给Engine。
Engine:Engine组件在Service组件中有且只有一个;Engine是Service组件中的请求处理组件。Engine组件从一个或多个Connector中接收请求并处理,并将完成的响应返回给Connector,最终传递给客户端。
HOST:Host是Engine的子容器。Engine组件中可以内嵌1个或多个Host组件,每个Host组件代表Engine中的一个虚拟主机。Host组件至少有一个,且其中一个的name必须与Engine组件的defaultHost属性相匹配。Host虚拟主机的作用,是运行多个Web应用(一个Context代表一个Web应用),并负责安装、展开、启动和结束每个Web应用。
Context:Context元素代表在特定虚拟主机上运行的一个Web应用。Context是Host的子容器,每个Host中可以定义任意多的Context元素。(一般会将应用放在webapp目录下进行自动部署,所以不用专门配置该项了,如果要将应用程序放到别的地方,就需要配置该项)
Engine、Host和Context都是容器,但它们不是平行的关系,而是父子关系:Engine包含Host,Host包含Context。
写在优化前面:Connector的主要功能,是接收连接请求,创建Request和Response对象用于和请求端交换数据;然后分配线程让Engine(也就是Servlet容器)来处理这个请求,并把产生的Request和Response对象传给Engine。当Engine处理完请求后,也会通过Connector将响应返回给客户端。Servlet容器处理请求,是需要Connector进行调度和控制的,Connector是Tomcat处理请求的主干。
Tomcat处理请求的过程:在accept队列中接收连接(当客户端向服务器发送请求时,如果客户端与OS完成三次握手建立了连接,则OS将该连接放入accept队列);在连接中获取请求的数据,生成request;调用servlet容器处理请求;返回response。
一:Tomcat内存优化,启动时告诉JVM我要一块大内存(调优内存是最直接的方式)
Windows 下的catalina.bat
Linux 下的catalina.sh 如:
JAVA_OPTS=’-Xms256m -Xmx512m’
-Xms JVM初始化堆的大小
-Xmx JVM堆的最大值 实际参数大小根据服务器配置或者项目具体设置.
二:Tomcat 线程优化 在server.xml中
详解tomcat的连接数与线程池:
http://www.cnblogs.com/kismetv/p/7806063.html
maxThreads=“X” 表示最多同时处理X个连接
minSpareThreads=“X” 初始化X个连接
maxSpareThreads=“X” 表示如果最多可以有X个线程,一旦超过X个,则会关闭不在需要的线程
acceptCount=“X” 当同时连接的人数达到maxThreads时,还可以排队,队列大小为X.超过X就不处理
Executor元素代表Tomcat中的线程池,可以由其他组件共享使用;要使用该线程池,组件需要通过executor属性指定该线程池。Executor是Service元素的内嵌元素。一般来说,使用线程池的是Connector组件;为了使Connector能使用线程池,Executor元素应该放在Connector前面。Executor与Connector的配置举例如下:
<Executor name="tomcatThreadPool" namePrefix ="catalina-exec-" maxThreads="150" minSpareThreads="4" />
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" acceptCount="1000" />
线程池的主要属性:
name:该线程池的标记
maxThreads:线程池中最大活跃线程数,默认值200(Tomcat7和8都是)
minSpareThreads:线程池中保持的最小线程数,最小值是25
maxIdleTime:线程空闲的最大时间,当空闲超过该值时关闭线程(除非线程数小于minSpareThreads),单位是ms,默认值60000(1分钟)
daemon:是否后台线程,默认值true
threadPriority:线程优先级,默认值5
namePrefix:线程名字的前缀,线程池中线程名字为:namePrefix+线程编号
三:Tomcat IO优化
目前,Tomcat支持三种接收请求的处理方式:BIO、NIO、APR。
Tomcat7中支持这3种,Tomcat8增加了对NIO2的支持,而到了Tomcat8.5和Tomcat9.0,则去掉了对BIO的支持
1、同步阻塞IO(JAVA BIO) 同步并阻塞,服务器实现模式为一个连接一个线程(one connection one thread 想想都觉得恐怖,线程可是非常宝贵的资源),当然可以通过线程池机制改善。此种方式Tomcat使用的是传统Java I/O操作(即java.io包及其子包)。Tomcat7以下版本默认情况下是以bio模式运行的,由于每个请求都要创建一个线程来处理,线程开销较大,不能处理高并发的场景,在三种模式中性能也最低。启动tomcat看到如下日志,表示使用的是BIO模式:
信息: Starting ProtocolHandler ["http-bio-7070"]
三月 08, 2019 11:16:16 上午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-bio-8010"]
注意:从Tomcat7以及以上就开始支持APR:
信息: Starting ProtocolHandler ["http-apr-7070"]
三月 08, 2019 11:16:16 上午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-apr-8010"]
2、JAVA NIO:又分为同步非阻塞IO,异步阻塞IO 与BIO最大的区别one request one thread.可以复用同一个线程处理多个connection(多路复用).。Tomcat 8以及以上默认使用该模式。但是Tomcat 7需要手动配置:
将:
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
修改为:
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
四种IO模型的关系:
org.apache.coyote.http11.Http11Protocol:BIO
org.apache.coyote.http11.Http11NioProtocol:NIO
org.apache.coyote.http11.Http11Nio2Protocol:NIO2
org.apache.coyote.http11.Http11AprProtocol:APR
关于默认的选择:
如果没有指定protocol,则使用默认值HTTP/1.1,其含义如下:在Tomcat7中,自动选取使用BIO或APR(如果找到APR需要的本地库,则使用APR,否则使用BIO);在Tomcat8中,自动选取使用NIO或APR(如果找到APR需要的本地库,则使用APR,否则使用NIO)。
3、异步非阻塞IO(Java NIO2又叫AIO) 主要与NIO的区别主要是操作系统的底层区别.可以做个比喻:比作快递,NIO就是网购后要自己到官网查下快递是否已经到了(可能是多次),然后自己去取快递;AIO就是快递员送货上门了(不用关注快递进度)。
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解.
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及其子包)。是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,它拥有比传统I/O操作(bio)更好的并发运行性能。要让Tomcat以nio模式来运行比较简单,只需要在Tomcat安装目录/conf/server.xml文件中将如下配置:
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持.
总结:
在server.xml中
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"
enableLookups="false"
redirectPort="8443" />
protocol进行IO切换。
真正能大幅度提高Tomcat性能是APR:简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和响应性能, 也是Tomcat运行高并发应用的首选模式。
四、APR
再说一遍:
简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和响应性能, 也是Tomcat运行高并发应用的首选模式。
https://blog.csdn.net/goldenfish1919/article/details/78859620
APR:Apache Protable Runtime是一个高可移植库,它是Apache HTTP Server 2.x的核心。能更好地和其它本地web技术集成,总体上让Java更有效率作为一个高性能web服务器平台而不是简单作为后台容器。
在产品环境中,特别是直接使用Tomcat做WEB服务器的时候,应该使用Tomcat Native来提高其性能。如果不配APR,基本上300个线程狠快就会用满,以后的请求就只好等待.但是配上APR之后,并发的线程数量明显下降,从原来的300可能会马上下降到只有几十,新的请求会毫无阻塞的进来。
在局域网环境测,就算是400个并发,也是一瞬间就处理/传输完毕,但是在真实的Internet环境下,页面处理时间只占0.1%都不到,绝大部分时间都用来页面传输。如果不用APR,一个线程同一时间只能处理一个用户,势必会造成阻塞。所以生产环境下用apr是非常必要的。
实际生产环境下,需要将Tomcat部署在Linux环境,需要安装APR库。
https://blog.csdn.net/z562743237/article/details/78190008
补充:
1.Tomcat支持两种协议:http和ajp.(sever.xml中配置)
HTTP:该连接器监听8080端口,负责建立HTTP连接。
AJP:Apache JServ Protocol,定向包协议,连接器监听8009端口,负责和其他的HTTP服务器建立连接。AJP连接器可以通过AJP协议和另一个web容器进行交互。在把Tomcat与其他HTTP服务器集成时,就需要用到这个连接器。AJP连接器可以通过AJP协议和一个web容器进行交互。
Web客户访问Tomcat服务器的两种方式:
2、Tomcat中server.xml中的Realm标签作用
可以把Realm理解为“域”,也可以理解为“组”,其实可以看成是一个包含了用户及密码的数据库,而且每个用户还会包含了若干角色。
3、如何查看Tomcat的状态?
有两种方案:工具、Linux命令
(1)JDK自带的jconsole工具可以方便的查看线程信息(此外还可以查看CPU、内存、类、JVM基本信息等),Tomcat自带的manager,收费工具New Relic等。
(2)Linux命令查看:(默认Tomat的监听端口是8080)
查看连接数:netstat –nat | grep 8080,可以通过LISTEN列查看各个连接的状态
ps命令可以查看进程状态:ps –e | grep java
查该进程内有多少个线程:ps –o nlwp 进程号(nlwp含义是number of light-weight process)
通过nlwp命令只能看到一共有多少个,包括idle的,可以通过以下命令来查看正在running的线程:
ps -eLo pid ,stat | grep tomcat的进程号 | grep running | wc -l
说明:其中ps -eLo pid ,stat可以找出所有线程,并打印其所在的进程号和线程当前的状态;两个grep命令分别筛选进程号和线程状态;wc统计个数。
4、Linux中启动Tomcat时,指定输出日志的目录:
/bin] # ./startup.sh | tail -f …/logs/catalina.out
当然也可以不用指定,因为Tomcat默认的就是将日志写入到…/logs/catalina.out中。
基于以上的介绍,具体对Tomcat的优化,可以参考:
https://blog.csdn.net/educast/article/details/78835954
https://blog.csdn.net/u010195563/article/details/80966025
Tomcat 7.0官方文档
http://tomcat.apache.org/tomcat-7.0-doc/config/http.html
Tomcat 8.0官方文档
http://tomcat.apache.org/tomcat-8.0-doc/config/http.html
Tomcat 8.5官方文档
http://tomcat.apache.org/tomcat-8.0-doc/config/http.html
Tomcat maxThreads maxConnections acceptCount参数说明
https://www.jianshu.com/p/2bc3fca12623
tomcat架构分析(connector BIO 实现)
https://gearever.iteye.com/blog/1841586
tomcat架构分析 (connector NIO 实现)
https://gearever.iteye.com/blog/1844203