Tomcat相关问题

Tomcat作为Web服务器,它的处理性能直接关系到用户体验。

一、Tomcat固定的目录结构

二、Tomcat的配置

2.1 tomcat端口号的配置
  tomcat端口号的缺省值为8080,如果修改端口号,可以用以下方法:
  找到tomcat目录下的\conf\server.xml文件中下面的代码段,修改其中的port即可。

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

server.xml是Tomcat算是最基本的配置文件,WEB容器的基本配置都在这里,包括端口、虚拟机、线程池等配置信息。

2.2 如何加大tomcat内存
  如果tomcat内存不够用,则会造成内存溢出的问题。这时通常会抛出java.lang.OutOfMemoryError: PermGen space异常,是指内存的永久保存区域OutOfMemoryError,解决办法就是加大内存。找到tomcat目录下的/bin/catalina.sh,在文件的前面,增加如下设置:

  JAVA_OPTS='-Xms[初始化内存大小] -Xmx[可以使用的最大内存]'

【参数说明】
-Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的 快一点,但是也可能会导致机器暂时间变慢。
-Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占 用更多的内存,超出了这个设置值,就会抛出OutOfMemory 异常。

2.3 如何加大tomcat线程连接数
在tomcat配置文件server.xml中的配置中,和连接数相关的参数有:

<Connector port="9027"
  protocol="HTTP/1.1"
  maxHttpHeaderSize="8192"
  maxThreads="1000"         -- 客户请求最大线程数 
  minSpareThreads="100"     --Tomcat初始化时创建的 socket 线程数 
  maxSpareThreads="1000"    --Tomcat连接器的最大空闲 socket 线程数 
  minProcessors="100"       -- 服务器创建时的最小处理线程数
  maxProcessors="1000"      --最大连接线程数,即:并发处理的最大请求数,默认值为75
  enableLookups="false"     --是否反查域名
  URIEncoding="utf-8"       --URL统一编码
  acceptCount="1000"        --允许的最大连接数,应大于等于maxProcessors,默认值为100
  redirectPort="8443"       --在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口
  disableUploadTimeout="true"
    connectionTimeout=30000   --网络连接超时,单位:毫秒。设置为0表示永不超时
/>

其中和最大连接数相关的参数为maxProcessors和acceptCount。如果要加大并发连接数,应同时加大这两个参数。web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。

2.4 设置tomcat缓存
在tomcat配置文件server.xml中的配置中,和缓存相关的参数有:

<Connector port="9027"
  protocol="HTTP/1.1"
    -- 是否启用压缩 on为启用(文本数据压缩)
  compression="on"  
    -- 启用压缩的输出内容大小,这里面默认为2KB,只有当响应报文大小大于这个值的时候才会对报文进行压缩
  compressionMinSize="2048" 
    -- 配置想压缩的数据类型
   compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
    -- 定义建立客户连接超时的时间
  connectionTimeout="20000"
  disableUploadTimeout="true"/>

数据被压缩了,响应速度自然减少了。但是有时候你会发现compressionMinSize这个配置并不起作用,貌似只要客户端加了Accept-Encoding: gzip, deflate,响应就是压缩的,无论响应报文体有多大,这是怎么回事呢?
  Tomcat判断是否压缩的的依据是根据你响应里的Content-length来的,如果没有Content-length或者Content-length大于compressionMinSize就进行压缩。如果你的报文小于compressionMinSize,却被压缩了,那就是你的响应报文中并不含有Content-length。
  如果你的响应无论什么大小都被压缩了,那很有可能就是你在代码中使用了OutputStream.flush(),或者PrintWriter.flush()。使用flush()的意思是响应开始往外写了,Content-length已经来不及写了,tomcat会默认使用Transfer-Encoding: chunked形式帮你返回消息,响应肯定是要被压缩的。
  所以如果你的设置compressionMinSize的没有生效,很有可能是你的设置的compressionMinSize超出了tomcat的缓冲区大小,响应默认是chunked的形式返回的,这种情况是肯定压缩的。

三、Tomcat是如何加载的

Windows下JAVA用到的环境变量主要有3个,JAVA_HOME、CLASSPATH、PATH。

  • JAVA_HOME 指向的是JDK的安装路径。
          JAVA_HOME=C:\jdk1.5.0_06
  • PATH 环境变量原来Windows里面就有,你只需修改一下,使他指向JDK的bin目录,这样你在控制台下面编译、执行程序时就不需要再键入一大串路径了。
          PATH=%JAVA_HOME%\bin;%PATH%
    其中%PATH%是引用以前你设置的PATH环境变量
  • CLASSPATH 环境变量配置的是java类库的位置以及执行字节码文件时查找文件的路径。
    CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
    要注意的是最前面的".;",这个是告诉JDK,搜索CLASS时先查找当前目录的CLASS文件。

Tomcat用到的环境变量主要有CATALINA_HOME、CATALINA_BASE

  • CATALINA_HOME:Tomcat的安装目录
  • CATALINA_BASE:Tomcat的工作目录

JVM类加载

JVM的类加载采用父类委托机制

当JVM运行过程中,用户需要加载某些类时,会按照下面的步骤(父类委托机制):
1 用户自己的类加载器,把加载请求传给父加载器,父加载器再传给其父加载器,一直到加载器树的顶层。
2 最顶层的类加载器首先针对其特定的位置加载,如果加载不到就转交给子类。
3 如果一直到底层的类加载都没有加载到,那么就会抛出异常。
  因此,按照这个过程可以想到,假设两个包名和类名完全相同的class文件不再同一个jar包,如果一个class文件已经被加载java虚拟机里了,那么后面的相同的class文件就不会被加载了。

Tomcat类加载

Tomcat类加载

当tomcat启动时,会创建几种类加载器:

1 Bootstrap 引导类加载器
  是其他类加载器的父类,它用于加载Java核心库,并且是唯一一个用本地代码编写的类加载器(位于jre/lib/ext下)

2 System 系统类加载器
  加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于CATALINA_HOME/bin下。


**3 Common 通用类加载器 **
  加载tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下,比如servlet-api.jar

4 webapp 应用类加载器
  每个应用在部署后,都会创建一个唯一的类加载器。该类加载器会加载位于 WEB-INF/lib下的jar文件中的class 和 WEB-INF/classes下的class文件。WEB-INF为项目的根目录,基本地包含一下文件夹:

  • classes文件夹:放置已编译的java类
  • config文件夹:放置项目使用的配置文件
  • lib文件夹:放置jar库文件(许多class文件的集合)
  • web.xml

当应用需要到某个类时,则会按照下面的顺序进行类加载:
  1 使用bootstrap引导类加载器加载
  2 使用system系统类加载器加载
  3 使用应用类加载器在WEB-INF/classes中加载
  4 使用应用类加载器在WEB-INF/lib中加载
  5 使用common类加载器在CATALINA_HOME/lib中加载

从上面的加载机制我们就可以知道,src下面的java文件优先于jar包中的class,这是因为src文件夹中的java类以及webContent中的JSP都会在tomcat启动时编译成class文件放置在WEB-INF/classes中;而项目外部引用的jar包则是放置在WEB-INF/lib下。
  同时要注意,在同一个文件夹下,jar包是按顺序从上到下依次加载,如果已经找到,则不会再后续jar包中进行查找。另外如果在 CATALINA_HOME/lib 以及 WEB-INF/lib 中放置了不同版本的jar包,此时就会导致某些情况下报加载不到类的错误。

四、Tomcat的部署方式

(1)静态部署

  • 将web项目文件件拷贝到webapps 目录中
  • 在server.xml中指定
      在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加:
<Context path="/hello" docBase="D:\ workspace\hello\WebRoot" debug="0" privileged="true"/> 

【参数说明】
path:虚拟路径
docBase :应用程序的物理路径
debug :设定debug level, 0表示提供最少的信息,9表示提供最多的信息
privileged:设置为true的时候,才允许Tomcat的Web应用使用容器内的Servlet

  • 创建一个Context文件
      在conf目录中,新建 Catalina\localhost目录,在该目录中新建一个xml文件,名字不可以随意取,要和path后的那个名字一致,按照下边这个path的配置,xml的名字应该就应该是hello(hello.xml),该xml文件的内容为:
<Context path="/hello" docBase="D:\ workspace\hello\WebRoot" debug="0" privileged="true"/> 

这个方法有个优点,可以定义别名。服务器端运行的项目名称为path,外部访问的URL则使用XML的文件名。这个方法很方便的隐藏了项目的名称,对一些项目名称被固定不能更换,但外部访问时又想换个路径,非常有效。

(2)动态部署
  可以用tomcat在线后台管理器,一般tomcat都打开了,直接上传war就可以。

五、Tomcat的运行模式

Tomcat如何处理多个用户同时请求的问题呢?有以下三种方式:
(1)BIO:默认的模式,性能非常低下,没有经过任何优化处理和支持。bio模式同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。

(2)NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
想运行在该模式下,直接修改server.xml里的Connector节点,修改protocol为nio:

<Connector port=”80″ protocol=”org.apache.coyote.http11.Http11NioProtocol” 
    connectionTimeout=”20000″ 
    URIEncoding=”UTF-8″ 
    useBodyEncodingForURI=”true” 
    enableLookups=”false” 
    redirectPort=”8443″ />

(3)APR:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能。

BIO、NIO、AIO适用场景分析:
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

六、Tomcat的优化

(1)内存优化
  默认情况下Tomcat的相关内存配置较低,这对于一些大型项目显然是不够用的,这些项目运行就已经耗费了大部分内存空间,何况大规模访问的情况。可以用-Xmx -Xms -XX:MaxPermSize等参数对内存不同功能块进行划分。内存分配不足,就导致虚拟机一直处于full GC,从而导致处理能力严重下降。

(2)线程优化
  默认情况下 Tomcat只支持200线程访问,超过这个数量的连接将被等待甚至超时放弃,所以我们需要提高这方面的处理能力,优化Connector(连接器)。

(3)IO优化
在server.xml中

<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" 
    connectionTimeout="20000" 
    URIEncoding="UTF-8" 
    useBodyEncodingForURI="true" 
    enableLookups="false" 
    redirectPort="8443" />

实现对Tomcat的IO切换.

(4)利用缓存和压缩
  硬盘主要问题就是读写性能,当大量文件进行读写时,磁盘极容易成为性能瓶颈。最好的办法还是利用下面提到的缓存。
  对于静态页面最好是能够缓存起来,这样就不必每次从磁盘上读。这里我们采用了Nginx作为缓存服务器,将图片、css、js文件都进行了缓存,有效的减少了后端tomcat的访问。
  另外,为了能加快网络传输速度,开启gzip压缩也是必不可少的。但考虑到tomcat已经需要处理很多东西了,所以把这个压缩的工作就交给前端的Nginx来完成。

(5)采用集群
  单个服务器性能总是有限的,最好的办法自然是实现横向扩展,那么组建tomcat集群是有效提升性能的手段。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容