tomcat
1. 认识tomcat
1.1 什么是tomcat
tomcat 是由Apache Software Foundation(ASF)开发的一个开源Java WEB应用服务器。类似功能的还有:Jetty、Resin、Websphere、weblogic、JBoss、Glassfish、GonAS等,它们的市场占有率如下,可以看到Tomcat是最受欢迎的Java WEB应用服务器。Tomcat是用Java语言编写的,需要运行在Java虚拟机上,所以一般需要先安装JDK,以提供运行环境。
Tomcat 服务器是一个免费的开放bai源代码的Web 应用服务器,属于轻量级应用服务器。
在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
tomcat标椎的来说是服务器的中间件。
1.2 tomcat的下载
这里不做过多的解释,网上一堆。这里提供tomcat的一个官网
网址 : http://tomcat.apache.org/
1.3 tomcat 文件目录的介绍
下载完成后在tomcat下有 bin conf lib logs temp wabapps work … 文件 其主要作用如下图:
2. tomcat 的基本操作
2.1 添加用户自定义的账号和密码
tomcat虽然功能是一个服务器中间件,但是归根结底也是一个Java应用程序,所以也有自己的管理界面,如果要想登陆则需要有账号和密码。
配置账号密码;
- 在tomcat安装目录下找到conf/tomcat-users.xml
- 配置 :
<role rolename="manager"/> <user username="admin" password="admin" roles="tomcat"/>
- 运行tomcat 访问点击可以登录
2.2 protocol
protocol: 协议的意思,在计算机网络中有很多种协议,而tomcat则支持http和AJP
tomcat的协议:
- HTTP/1.1 协议 , 用于监听浏览器发送的请求. 其走的端口默认为80 ,可以直接在浏览器上使用http://localhost进行访问
- AJP/1.3 协议 : 用于监听其他服务器转发过来的请求(其实是一个二进制传输协议)
- connectionTimeout: 连接超时时间
2.3 tomcat 修改端口
-
第一个端口 :
<Server port="8005" shutdown="SHUTDOWN">
:tomcat 监听的关闭端口
-
第二的端口 :
-
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
:用于监听通过浏览器进行访问请求8080端口;但是当用户用http请求某个资源,而该资源本身(例如账号密码)又被设置了必须要https方式访问,此时Tomcat会自动重定向到这个redirectPort设置的https端口。
-
-
第三个端口 :
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
: 当用户通过AJP协议进行访问的时候tomcat就监听的端口为8009
-
修改端口:
- 如果修改单个tomcat的话只是需要修改2.2的端口即可
- 如果修改多个tomcat的话修改将每一个tomcat的三个端口都同时修改了,这样才会避免错误
3. 调整tomcat的线程参数
3.1 Connector的protocol
Connector在处理HTTP请求时,会使用不同的protocol。不同的Tomcat版本支持的protocol不同,其中最典型的protocol包括BIO、NIO和APR(Tomcat7中支持这3种,Tomcat8增加了对NIO2的支持,而到了Tomcat8.5和Tomcat9.0,则去掉了对BIO的支持)。
BIO是Blocking IO,顾名思义是阻塞的IO;NIO是Non-blocking IO,则是非阻塞的IO。而APR是Apache Portable Runtime,是Apache可移植运行库,利用本地库可以实现高可扩展性、高性能;Apr是在Tomcat上运行高并发应用的首选模式,但是需要安装apr、apr-utils、tomcat-native等包。
3.2 如何指定protocol
Connector使用哪种protocol,可以通过元素中的protocol属性进行指定,也可以使用默认值。
指定的protocol取值及对应的协议如下:
- HTTP/1.1:默认值,使用的协议与Tomcat版本有关
- 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.3 acceptCount、maxConnections、maxThreads
-
acceptCount:
accept队列的长度;当accept队列中连接的个数达到acceptCount时,队列满,进来的请求一律被拒绝。默认值是100。
-
maxConnections:
Tomcat在任意时刻接收和处理的最大连接数。当Tomcat接收的连接数达到maxConnections时,Acceptor线程不会读取accept队列中的连接;这时accept队列中的线程会一直阻塞着,直到Tomcat接收的连接数小于maxConnections。如果设置为-1,则连接数不受限制。
默认值与连接器使用的协议有关:NIO的默认值是10000,APR/native的默认值是8192,而BIO的默认值为maxThreads(如果配置了Executor,则默认值是Executor的maxThreads)。
在windows下,APR/native的maxConnections值会自动调整为设置值以下最大的1024的整数倍;如设置为2000,则最大值实际是1024。
-
maxThreads:
请求处理线程的最大数量。默认值是200(Tomcat7和8都是的)。如果该Connector绑定了Executor,这个值会被忽略,因为该Connector将使用绑定的Executor,而不是内置的线程池来执行任务。
maxThreads规定的是最大的线程数目,并不是实际running的CPU数量;实际上,maxThreads的大小比CPU核心数量要大得多。这是因为,处理请求的线程真正用于计算的时间可能很少,大多数时间可能在阻塞,如等待数据库返回数据、等待硬盘读写数据等。因此,在某一时刻,只有少数的线程真正的在使用物理CPU,大多数线程都在等待;因此线程数远大于物理核心数才是合理的。
换句话说,Tomcat通过使用比CPU核心数量多得多的线程数,可以使CPU忙碌起来,大大提高CPU的利用率。
3.4 参数设置
- maxThreads的设置既与应用的特点有关,也与服务器的CPU核心数量有关。通过前面介绍可以知道,maxThreads数量应该远大于CPU核心数量;而且CPU核心数越大,maxThreads应该越大;应用中CPU越不密集(IO越密集),maxThreads应该越大,以便能够充分利用CPU。当然,maxThreads的值并不是越大越好,如果maxThreads过大,那么CPU会花费大量的时间用于线程的切换,整体效率会降低。
- maxConnections的设置与Tomcat的运行模式有关。如果tomcat使用的是BIO,那么maxConnections的值应该与maxThreads一致;如果tomcat使用的是NIO,maxConnections值应该远大于maxThreads。
- 通过前面的介绍可以知道,虽然tomcat同时可以处理的连接数目是maxConnections,但服务器中可以同时接收的连接数为maxConnections acceptCount 。acceptCount的设置,与应用在连接过高情况下希望做出什么反应有关系。如果设置过大,后面进入的请求等待时间会很长;如果设置过小,后面进入的请求立马返回connection refused。
3.5 线程池Executor
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" />
Executor的主要属性包括:
- name:该线程池的标记
- maxThreads:线程池中最大活跃线程数,默认值200(Tomcat7和8都是)
- minSpareThreads:线程池中保持的最小线程数,最小值是25
- maxIdleTime:线程空闲的最大时间,当空闲超过该值时关闭线程(除非线程数小于minSpareThreads),单位是ms,默认值60000(1分钟)
- daemon:是否后台线程,默认值true
- threadPriority:线程优先级,默认值5
- namePrefix:线程名字的前缀,线程池中线程名字为:namePrefix 线程编号
3.6 tomcat的线程池在哪里?
tomcat的线程池是在tomcat-util.jar包中,包中包含了两种线程池:
- 基于JNI技术实现的APR的pool
- 基于Java实现的Threadpool(默认是这个)
3.7 tomcat ThreadPool的工作原理
- 服务启动时,创建一个一维线程数组(maxThread=200个),并创建空闲线程(minSpareThreads=5个)随时等待用户请求。
- 当有用户请求时,调用 threadpool.runIt(ThreadPoolRunnable)方法,
- 将一个需要执行的实例传给ThreadPool中。其中用户需要执行的实例必须实现ThreadPoolRunnable接口。
- ThreadPool首先查找空闲的线程,
- 如果有则用它运行要执行ThreadPoolRunnable;
- 如果没有空闲线程并且没有超过 maxThreads,就一次性创建minSpareThreads个空闲线程;
- 如果已经超过了maxThreads了,就等待空闲线程了。总之,要找到空闲的线程 ,以便用它执行实例。找到后,将该线程从线程数组中移走。接着唤醒已经找到的空闲线程,
- 用它运行执行实例(ThreadPoolRunnable)。运行完ThreadPoolRunnable后, 就将该线程重新放到线程数组中,作为空闲线程供后续使用 .
简而言之:先创建一些线程准备着,用的时候先紧着这些来用,如果用完了就继续开启新的线程,直到达到最大值
3.8 访问量例如10000 个怎么办
-
这时候要使用到nginx实现一个负载均衡,这样的话就可以解决高并发了
-
可以设置不同的连接类型:BIO ,NIO ,APR
-
BIO模式下:默认最大连接数是它的最大线程数(缺省是200),要求的版本为tomcat7或者以下,系统要求win7,且适应于业务模式比较简单,连接人数比较少的小项目
-
NIO模式下:默认是10000,要求的版本为tomcat7以上,系统要求win10,且适应于业务模式比较复杂,连接人数比较多的中型项目具体代码为:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />
-
APR模式:则是8192(windows上则是低于或等于maxConnections的1024的倍数),如果设置为-1则表示不限制(直到服务器宕机崩溃); 要求的版本为tomcat8或者以上,系统要求win10,且适用于业务比较复杂,高并发的访问的情况,,但是配置比计较复杂(是运维工程师的活)
-
BIO<NIO<APR
4 . tomcat优化
4.1 修改Tomcat内存
tomcat默认的内存大小为128MB,但是有些项目启动的时候要大于这个数字,所以修改tomcat的内存大小就成为了必要的操作.
- Windows 下的catalina.bat中大概45左右添加一行话:
set JAVA_OPTS=-Xms256m -Xmx512m
- Linux 下的catalina.sh中中大概45左右添加一行话:
set JAVA_OPTS=-Xms256m -Xmx512m
- 查看依靠JDK中自带的工具:
C:\Program Files\Java\jdk1.7.0_51\bin\jvisualvm.exe
4.2 优化tomcat
- Tomcat内存优化,启动时告诉JVM我要一块大内存(调优内存是最直接的方式):加大内存条
- Tomcat 线程连接优化:合理设置tomcat的线程参数
- Tomcat IO优化:使用高版本的tomcat
- Tomcat缓存优化:将静态资源拉入缓存中不用来回加载浪费时间
- 禁用AJP连接器实现动静分离