Tomcat面试题

1、Tomcat 的缺省端口是多少,怎么修改?

1)找到 Tomcat 目录下的conf 文件夹

2)进入 conf 文件夹里面找到 server.xml 文件

3)打开 server.xml 文件

4)在 server.xml 文件里面找到下列信息 port="8080"改成你想要的端口

2、tomcat 有哪几种 Connector 运行模式(优化)?

bio:传统的Java I/O操作,同步且阻塞IO。

maxThreads="150"//Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最 大的线程数。默认值200。可以根据机器的时期性能和内存大小调整,一般可以在400-500。最大可以在800左右。

minSpareThreads="25"—Tomcat初始化时创建的线程数。默认值4。如果当前没有空闲线 程,且没有超过maxThreads,一次性创建的空闲线程数量。Tomcat初始化时创建的线程数量也由 此值设置。

maxSpareThreads="75"—一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线 程。默认值50。一旦创建的线程超过此数值,Tomcat会关闭不再需要的线程。线程数可以大致上 用 “同时在线人数每秒用户操作次数系统平均操作时间” 来计算。

acceptCount="100"—指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队 列中的请求数,超过这个数的请求将不予处理。默认值10。如果当前可用线程数为0,则将请求放入处理队列中。这个值限定了请求队列的大小,超过这个数值的请求将不予处理。

connectionTimeout="20000" —网络连接超时,默认值20000,单位:毫秒。设置为0表示永 不超时,这样设置有隐患的。通常可设置为30000毫秒。

nio:JDK1.4开始支持,同步阻塞或同步非阻塞IO。

指定使用NIO模型来接受HTTP请求

protocol="org.apache.coyote.http11.Http11NioProtocol" 指定使用NIO模型来接受 HTTP请求。默认是BlockingIO,配置为protocol="HTTP/1.1" acceptorThreadCount="2" 使用NIO模型时接收线程的数目

aio(nio.2):JDK7开始支持,异步非阻塞IO。

apr:Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络 传输操作,从而大大地 提高Tomcat对静态文件的处理性能。

<!--
<Connector connectionTimeout="20000" port="8000" protocol="HTTP/1.1" redirectPort="8443" uriEncoding="utf-8"/>
-->
     <!-- 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"
     />

其他配置

maxHttpHeaderSize="8192" http请求头信息的最大程度,超过此长度的部分不予处理。一般 8K。

URIEncoding="UTF-8" 指定Tomcat容器的URL编码格式。

disableUploadTimeout="true" 上传时是否使用超时机制

enableLookups="false"–是否反查域名,默认值为true。为了提高处理能力,应设置为 false

compression="on" 打开压缩功能

compressionMinSize="10240" 启用压缩的输出内容大小,默认为2KB

noCompressionUserAgents="gozilla, traviata" 对于以下的浏览器,不启用压缩

compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 哪些资源类型需要压缩

 

 

3、Tomcat 有几种部署方式?

1)直接把 Web 项目放在webapps 下,Tomcat 会自动将其部署

2)在 server.xml 文件上配置<Context>节点,设置相关的属性即可

3)通过 Catalina 来进行配置:进入到 conf\Catalina\localhost 文件下,创建一个 xml 文件,该文件的名字就是站点的名字。

编写 XML 的方式来进行设置。

 

4、tomcat 容器是如何创建 servlet 类实例?用到了什么原理?

当容器启动时,会读取在webapps 目录下所有的 web 应用中的 web.xml文 件,然后对 xml 文件进行解析,

并读取 servlet 注册信息。然后,将每个应用中注册的 servlet 类都进行加载, 并通过反射的方式实例化。

(有时候也是在第一次请求时实例化)在 servlet 注册时加上如果为正数,则在 一开始就实例化,

如果不写或为负数,则第一次请求实例化

 

5、一个Tomcat最多支持多少用户的并发?

omcat 默认配置的最大请求数是150,也就是说同时支持150 个并发,当然了,也可以将其改大。

当某个应用拥有250 个以上并发的时候,应考虑应用服务器的集群。

具体能承载多少并发,需要看硬件的配置,CPU 越多性能越高,分配给JVM 的内存越多性能也就越高,但也会加重GC 的负担。

操作系统对于进程中的线程数有一定的限制:

Windows 每个进程中的线程数不允许超过2000

Linux 每个进程中的线程数不允许超过1000

另外,在Java 中每开启一个线程需要耗用1MB的JVM 内存空间用于作为线程栈之用。

Tomcat的最大并发数是可以配置的,实际运用中,最大并发数与硬件性能和CPU数量都有很大关系的。更好的硬件,更多的处理器都会使Tomcat支持更多的并发。

Tomcat 默认的HTTP 实现是采用阻塞式的Socket 通信,每个请求都需要创建一个线程处理。这种模式下的并发量受到线程数的限制,但对于Tomcat 来说几乎没有BUG 存在了。

Tomcat 还可以配置NIO 方式的Socket通信,在性能上高于阻塞式的,每个请求也不需要创建一个线程进行处理,并发能力比前者高。但没有阻塞式的成熟。

这个并发能力还与应用的逻辑密切相关,如果逻辑很复杂需要大量的计算,那并发能力势必会下降。如果每个请求都含有很多的数据库操作,那么对于数据库的性能也是非常高的。

对于单台数据库服务器来说,允许客户端的连接数量是有限制的。

并发能力问题涉及整个系统架构和业务逻辑。

系统环境不同,Tomcat版本不同、JDK版本不同、以及修改的设定参数不同。并发量的差异还是满大的。

 

Tomcat配置

Tomcat/conf/server.xml修改配置

redirectPort="8443"

URIEncoding="UTF-8"

minSpareThreads="100"

maxSpareThreads="500"

maxThreads="1000"

acceptCount="700"

connectionTimeout="30000"

enableLookups="false"/>

 

参数说明

maxIdleTime: 最大空闲时间,超过这个空闲时间,且线程数大于minSpareThreads的,都会被回收,默认值1分钟(60000ms);

minSpareThreads:最小空闲线程数,任何情况都会存活的线程数,即便超过了最大空闲时间,也不会被回收,默认值4;

maxSpareThreads:最大空闲线程数,在最大空闲时间(maxIdleTime)内活跃过,此时空闲,当空闲时间大于maxIdleTime则被回收,小则继续存活,等待被调度,默认值50;

maxThreads:最大线程数,大并发请求时,tomcat能创建来处理请求的最大线程数,超过则放入请求队列中进行排队,默认值为200;

acceptCount:当最大线程数(maxThreads)被使用完时,可以放入请求队列排队个数,超过这个数返回connection refused(请求被拒绝),一般设置和maxThreads一样,不过这个具体需要根据自己的应用实际访问峰值和平均值来权衡,默认值为100;

connectionTimeout:网络连接超时,假设设置为0表示永不超时,这样设置隐患巨大,通常可设置为30000ms,默认60000ms。

Windows Tomcat允许每个进程maxThreads(最大线程数)2000

Linux Tomcat允许每个进程maxThreads(最大线程数)1000

 

6、tomcat 有哪几种 Connector 运行模式(优化)

bio:传统的 Java I/O 操作,同步且阻塞 IO。

maxThreads=”150”//Tomcat 使用线程来处理接收的每个请求。这个值表示 Tomcat 可创建的最大的线程数。默认值 200。可以根据机器的时期性能和内存 大小调整,一般可以在 400-500。最大可以在 800 左右。 minSpareThreads=”25”—Tomcat 初始化时创建的线程数。默认值 4。如果 当前没有空闲线程,且没有超过 maxThreads,一次性创建的空闲线程数量。 Tomcat 初始化时创建的线程数量也由此值设置。  maxSpareThreads=”75”–一旦创建的线程超过这个值,Tomcat 就会关闭不 再需要的 socket 线程。默认值 50。一旦创建的线程超过此数值,Tomcat 会关 闭不再需要的线程。线程数可以大致上用 “同时在线人数每秒用户操作次数系 统平均操作时间” 来计算。  acceptCount=”100”—-指定当所有可以使用的处理请求的线程数都被使用 时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。默认值 10。如果当前可用线程数为 0,则将请求放入处理队列中。这个值限定了请求 队列的大小,超过这个数值的请求将不予处理。  connectionTimeout=”20000” –网络连接超时,默认值 20000,单位:毫 秒。设置为 0 表示永不超时,这样设置有隐患的。通常可设置为 30000 毫秒。

 

nio:JDK1.4 开始支持,同步阻塞或同步非阻塞 IO。

指定使用 NIO 模型来接受 HTTP 请求 protocol=”org.apache.coyote.http11.Http11NioProtocol” 指定使用 NIO 模型 来接受 HTTP 请求。默认是 BlockingIO,配置为 protocol=”HTTP/1.1”  acceptorThreadCount=”2” 使用 NIO 模型时接收线程的数目

 

apr:Tomcat 将以 JNI 的形式调用 Apache HTTP 服务器的核心动态链接库来 处理文件读取或网络传输操作,从而大大地 提高 Tomcat 对静态文件的处理性 能。

<!--       <Connector connectionTimeout="20000" port="8000" protocol="HTTP/1.1" redirectPort="8443" uriEncoding="utf-8"/>    -->     <!-- 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"            /> 其他配置maxHttpHeaderSize="8192" http 请求头信息的最大程度,超过此长度的部分 不予处理。一般 8K。 URIEncoding="UTF-8" 指定 Tomcat 容器的 URL 编码格式。 disableUploadTimeout="true" 上传时是否使用超时机制 enableLookups="false"--是否反查域名,默认值为true。为了提高处理能力, 应设置为 false  compression="on"   打开压缩功能  compressionMinSize="10240" 启用压缩的输出内容大小,默认为 2KB noCompressionUserAgents="gozilla, traviata"   对于以下的浏览器,不启用 压缩 compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"哪些资源类型需要压缩 

 

7、tomcat 容器是如何创建 servlet 类实例?用到了什么原理

当容器启动时,会读取在webapps 目录下所有的 web 应用中的 web.xml文 件,然后对 xml 文件进行解析,

并读取 servlet 注册信息。然后,将每个应用中注册的 servlet 类都进行加载, 并通过反射的方式实例化。

(有时候也是在第一次请求时实例化)在 servlet 注册时加上如果为正数,则在 一开始就实例化,

如果不写或为负数,则第一次请求实例化。

 

8、tomcat 如何优化

1、优化连接配置.这里以tomcat7 的参数配置为例,需要修改 conf/server.xml 文件,修改连接数,关闭客户端 dns 查询。

 

参数解释:

 

URIEncoding=”UTF-8″ :使得 tomcat 可以解析含有中文名的文件的 url,真 方便,不像 apache 里还有搞个 mod_encoding,还要手工编译

 

maxSpareThreads : 如果空闲状态的线程数多于设置的数目,则将这些线程中 止,减少这个池中的线程总数。

 

minSpareThreads : 最小备用线程数,tomcat 启动时的初始化的线程数。

 

enableLookups : 这个功效和 Apache 中的HostnameLookups 一样,设为关 闭。

 

connectionTimeout : connectionTimeout为网络连接超时时间毫秒数。

 

maxThreads : maxThreads Tomcat 使用线程来处理接收的每个请求。这个值 表示 Tomcat 可创建的最大的线程数,即最大并发数。

 

acceptCount : acceptCount 是当线程数达到maxThreads 后,后续请求会被放 入一个等待队列,这个 acceptCount 是这个队列的大小,如果这个队列也满 了,就直接 refuse connection

 

maxProcessors 与 minProcessors : 在 Java 中线程是程序运行时的路径,是 在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同

的地址空间。多线程帮助程序员写出 CPU 最 大利用率的高效程序,使空闲时 间保持最低,从而接受更多的请求。

 

通常 Windows 是 1000 个左右,Linux 是2000 个左右。

 

useURIValidationHack:

 

我们来看一下 tomcat 中的一段源码:

 

【security】

 

if (connector.getUseURIValidationHack()) {

 

String uri = validate(request.getRequestURI());

 

if (uri == null) {

 

res.setStatus(400);

 

res.setMessage(“Invalid URI”);

 

throw new IOException(“Invalid URI”);

 

} else {

 

req.requestURI().setString(uri);

 

// Redoing the URI decoding

 

req.decodedURI().duplicate(req.requestURI());

 

req.getURLDecoder().convert(req.decodedURI(), true);

 

可以看到如果把useURIValidationHack 设成”false”,可以减少它对一些 url 的不必要的检查从而减省开销。

 

enableLookups=”false”: 为了消除 DNS 查询对性能的影响我们可以关闭 DNS 查询,方式是修改 server.xml 文件中的 enableLookups 参数值。

 

disableUploadTimeout:类似于 Apache 中的 keeyalive 一样

 

给 Tomcat 配置 gzip 压缩(HTTP 压缩)功能

 

compression=”on” compressionMinSize=”2048″

 

 compressableMimeType=”text/html,text/xml,text/JavaScript,text/css,text/plain”

 

HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页 后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解 压缩并浏览。相对于普通的浏览过程 HTML,CSS,javascript , Text ,它可以节 省 40%左右的流量。更为重要的是,它可以对动态生成的,包括 CGI、PHP , JSP , ASP , Servlet,SHTML 等输出的网页也能进行压缩,压缩效率惊人。

 

1)compression=”on” 打开压缩功能

 

2)compressionMinSize=”2048″启用压缩的输出内容大小,这里面默认为 2KB

 

3)noCompressionUserAgents=”gozilla, traviata” 对于以下的浏览器,不启 用压缩

 

4)compressableMimeType=”text/html,text/xml” 压缩类型

 

最后不要忘了把 8443 端口的地方也加上同样的配置,因为如果我们走 https 协 议的话,我们将会用到 8443 端口这个段的配置,对吧?

 

<!–enable tomcat ssl–>

 

<Connector port=”8443″ protocol=”HTTP/1.1″

 

URIEncoding=”UTF-8″ minSpareThreads=”25″ maxSpareThreads=” 75″

 

enableLookups=”false” disableUploadTimeout=”true” connectionTimeout=”20000″

 

acceptCount=”300″ maxThreads=”300″ maxProcessors=”1000″ minProcessors=”5″

 

useURIValidationHack=”false”

 

compression=”on” compressionMinSize=”2048″

 

compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”

 

SSLEnabled=”true”

 

scheme=”https” secure=”true”

 

 clientAuth=”false” sslProtocol=”TLS”

 

keystoreFile=”d:/tomcat2/conf/shnlap93.jks” keystorePass=”aaaaaa”

 

/>

 

好了,所有的 Tomcat 优化的地方都加上了。

 

9、内存调优

内存方式的设置是在catalina.sh 中,调整一下 JAVA_OPTS 变量即可,因为后 面的启动参数会把 JAVA_OPTS 作为 JVM 的启动参数来处理。  具体设置如下:  JAVA_OPTS="$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k XX:NewRatio=4 -XX:SurvivorRatio=4"  其各项参数如下:  -Xmx3550m:设置 JVM 最大可用内存为 3550M。 -Xms3550m:设置 JVM 促使内存为3550m。此值可以设置与-Xmx 相同,以 避免每次垃圾回收完成后 JVM 重新分配内存。 -Xmn2g:设置年轻代大小为 2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为 64m,所以增大年轻代后,将会减小年老 代大小。此值对系统性能影响较大,Sun 官方推荐配置为整个堆的 3/8。 -Xss128k:设置每个线程的堆栈大小。JDK5.0 以后每个线程堆栈大小为 1M, 以前每个线程堆栈大小为 256K。更具应用的线程所需内存大小进行调整。在相 同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的 线程数还是有限制的,不能无限生成,经验值在3000~5000 左右。 -XX:NewRatio=4:设置年轻代(包括 Eden 和两个 Survivor 区)与年老代的比 值(除去持久代)。设置为 4,则年轻代与年老代所占比值为 1:4,年轻代占 整个堆栈的1/5  -XX:SurvivorRatio=4:设置年轻代中 Eden 区与 Survivor 区的大小比值。设置 为 4,则两个 Survivor 区与一个Eden 区的比值为 2:4,一个 Survivor 区占整 个年轻代的 1/6 -XX:MaxPermSize=16m:设置持久代大小为 16m。  -XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为 0 的话,则年 轻代对象不经过 Survivor 区,直接进入年老代。对于年老代比较多的应用,可 以提高效率。如果将此值设置为一个较大值,则年轻代对象会在 Survivor 区进 行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收 的概论。

 

10、垃圾回收策略调优

 

垃圾回收的设置也是在catalina.sh 中,调整 JAVA_OPTS 变量。  具体设置如下:  JAVA_OPTS="$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k

XX:+UseParallelGC  -XX:MaxGCPauseMillis=100"  具体的垃圾回收策略及相应策略的各项参数如下:  串行收集器(JDK1.5 以前主要的回收方式)  -XX:+UseSerialGC:设置串行收集器  并行收集器(吞吐量优先)  示例:  java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC XX:MaxGCPauseMillis=100 

 

-XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有 效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。  -XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程 一起进行垃圾回收。此值最好配置与处理器数目相等。 -XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0 支持 对年老代并行收集 -XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法 满足此时间,JVM 会自动调整年轻代大小,以满足此值。  -XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代 区大小和相应的 Survivor 区比例,以达到目标系统规定的最低相应时间或者收 集频率等,此值建议使用并行收集器时,一直打开。  并发收集器(响应时间优先)  示例:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k XX:+UseConcMarkSweepGC  -XX:+UseConcMarkSweepGC:设置年老代为并发收集。测试中配置这个以 后,-XX:NewRatio=4 的配置失效了,原因不明。所以,此时年轻代大小最好 用-Xmn 设置。 -XX:+UseParNewGC: 设置年轻代为并行收集。可与 CMS 收集同时使用。 JDK5.0 以上,JVM 会根据系统配置自行设置,所以无需再设置此值。 -XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压 缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值 设置运行多少次 GC 以后对内存空间进行压缩、整理。  -XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性 能,但是可以消除碎片 

 

11、Tomcat 一个请求的完整过程

 

Ng:(nginx)

 

upstream yy_001{         server 10.99.99.99:8080;          server 10.99.99.100:8080; 

 

        hash $**; 

 

        healthcheck_enabled;          healthcheck_delay 3000;          healthcheck_timeout 1000;          healthcheck_failcount 2;          healthcheck_send 'GET /healthcheck.html HTTP/1.0' 'Host: wo.com' 'Connection: close';      }

 

     server {

        include base.conf;         server_name  wo.de.tian;          ...         location /yy/ {              proxy_pass http://yy_001;         } 首先 dns 解析 wo.de.tian 机器,一般是 ng 服务器 ip 地址  然后 ng 根据 server 的配置,寻找路径为 yy/的机器列表,ip 和端口 最后 选择其中一台机器进行访问—->下面为详细过程

 

1) 请求被发送到本机端口 8080,被在那里侦听的 Coyote HTTP/1.1 Connector 获得 

2) Connector 把该请求交给它所在的 Service 的 Engine 来处理,并等待来自 Engine 的回应 

3) Engine 获得请求 localhost/yy/index.jsp,匹配它所拥有的所有虚拟主机 Host 

4) Engine 匹配到名为 localhost 的 Host(即使匹配不到也把请求交给该 Host 处理,因为该 Host 被定义为该 Engine 的默认主机) 

5) localhost Host 获得请求/yy/index.jsp,匹配它所拥有的所有 Context 

6) Host 匹配到路径为/yy 的 Context(如果匹配不到就把该请求交给路径名 为”“的 Context 去处理) 

7) path=”/yy”的Context 获得请求/index.jsp,在它的mapping table 中寻找 对应的 servlet 

8) Context 匹配到 URL PATTERN 为*.jsp 的 servlet,对应于 JspServlet 类 

9) 构造HttpServletRequest 对象和 HttpServletResponse 对象,作为参数调用 JspServlet 的 doGet 或 doPost 方法 

10)Context 把执行完了之后的 HttpServletResponse 对象返回给 Host 

11)Host 把 HttpServletResponse 对象返回给 Engine 

12)Engine 把HttpServletResponse 对象返回给 Connector 

13)Connector 把HttpServletResponse 对象返回给客户 browser

 

12、Tomcat 工作模式?

 

Tomcat 是一个 JSP/Servlet 容器。其作为 Servlet 容器,有三种工作模式:独 立的 Servlet 容器、进程内的 Servlet 容器和进程外的 Servlet 容器。

 

进入 Tomcat 的请求可以根据 Tomcat 的工作模式分为如下两类:

 

Tomcat 作为应用程序服务器:请求来自于前端的 web 服务器,这可能是 Apache, IIS, Nginx 等;

 

Tomcat 作为独立服务器:请求来自于 web 浏览器

 

 

posted @ 2022-05-10 11:51  java面试站  阅读(146)  评论(0)    收藏  举报