tomcat 的优化

本贴最后更新于 2493 天前,其中的信息可能已经沧海桑田

1 概述
本文档主要介绍了 Tomcat 的性能调优的原理和方法。可作为公司技术人员为客户 Tomcat 系统调优的技术指南,也可以提供给客户的技术人员作为他们性能调优的指导手册。

2 调优分类
由于 Tomcat 的运行依赖于 JVM,从虚拟机的角度我们把 Tomcat 的调整分为外部环境调优和自身调优两类来描述。
2.1 外部环境调优

调整 Tomcat 运行环境的操作系统参数和运行 Tomcat 的 java 虚拟机参数。
2.1.1 JAVA 虚拟机性能优化

    Tomcat需要依赖Java虚拟机运行。根据客户选用的主机的操作系统选择对应的 JDK的版本。无论哪个厂商的JDK,都建议使用最新的版本。 
    虚拟机可通过命令行的方式改变虚拟机使用内存的大小。如下表所示有两个参数用来设置虚拟机使用内存的大小。 
    参数                               描述 
    -Xms                JVM初始化堆的大小 
    -Xmx                JVM堆的最大值 
    Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。 

  [LD1] Windows 下,在文件 tomcat_home/bin/catalina.bat,Unix 下,在文件 tomcat_home/bin/catalina.sh 的前面,增加如下设置:
  JAVA_OPTS=‘-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】’'
需要把这个两个参数值调大。例如:

  1. JAVA_OPTS='-Xms256m -Xmx512m'

表示初始化内存为 256MB,可以使用的最大内存为 512MB。
另外需要考虑的是 Java 提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关,应该通过分析实际的垃圾收集的时间和频率来调整。
如果堆的空间很大,那么完全垃圾收集(FULL GC)就会很慢,但是频度会降低。如果在客户系统中把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。对于 SUN 和 HP 等虚拟机,推荐将最小堆大小和最大堆大小设置为同一值,因为这样可以避免浪费用于时常调整堆大小所需的 VM 资源。
当然,客户系统如果用到 IBM 虚拟机,要特别的注意设置-Xms 和-Xmx 一样大小会耽误垃圾回收的开始直到堆满,这样第一次垃圾回收就会变成非常昂贵的操作。推荐把-Xms 设置为应用所需的最小值,这样会产生高效的垃圾回收。

2.1.2 操作系统性能优化

以客户系统为 HP-UX 为例。
HP 系统中对 Tomcat 有影响的参数:
其中:
max_thread_proc: 一个进程所能创建的线程的最大数
nkthread: 在系统上同时允许的核心线程的最大数
maxfiles 上表给的建议是不是不合适?
如果在输出里看到消息:java.lang.OutOfMemoryError: unable to create new native thread,则说明名为 max_thread_proc 的 Unix 内核设置过小。max_thread_proc 是单个进程中的最大线程数。 它必须大到能够容纳 Java 应用程序中的所有线程以及虚拟机本身中的部分额外线程。

查看核心参数:$ulimit -a

     显示[LD2] 输出中的 nofiles 是指用户的进程能同时打开的最大文件句柄数。如果日志中出现”two many open files”的异常,需要重点检查这个参数。coredump 参数是 core 文件最大值的,限制当进程 coredump 时将产生 core文件的大小不能超过这个最大值。如果在日志文件检查时,发现 core文件不完整,需要增大这个参数值。执行 ulimit  -n 命令可以设置 nofiles 参数,执行ulimit -c命令设置 core 文件最大值。
    如果是在Windows操作系统上使用Tomcat,那么最好选择服务器版本。因为在非服务器版本上,最终用户授权数或者操作系统本身所能承受的用户数、可用的网络连接数或其它方面的一些方面都是有限制的。并且基于安全性的考虑,必须经常给操作系统打上最新的补丁。

2.1.3 Tomcat 与其它 web 服务器整合使用

    虽然tomcat也可以作web服务器,但其处理静态html的速度比不上apache,且其作为web服务器的功能远不如apache,因此我们想把 apache和tomcat集成起来,将html与jsp的功能部分进行明确分工,让tomcat只处理jsp部分,其它的由apache,IIS等这些 web服务器处理,由此大大节省了tomcat有限的工作线程[LD3] 。

2.2 自身调优

本节将说明 Tomcat 性能调优的技巧和方法,这些技巧和方法与操作系统或 Java 虚拟机的种类无关。以下方法都是针对 Tomcat 性能自身调整的最佳方式。
2.2.1 禁用 DNS 查询
当 web 应用程序要记录客户端的信息时,它也会记录客户端的 IP 地址或者通过域名服务器查找机器名转换为 IP 地址。DNS 查询需要占用网络,并且包括可能从很多很远的服务器或者不起作用的服务器上去获取对应的 IP 的过程,这样会消耗一定的时间。为了消除 DNS 查询对性能的影响我们可以关闭 DNS 查询,方式是修改 server.xml 文件中的 enableLookups 参数值:
不同的 tomcat 版本稍有不同。
Tomcat4

[html] view plain copy

  1. **** className=“org.apache.coyote.tomcat4.CoyoteConnector”port=“80”

  2. minProcessors=“5” maxProcessors=“75” enableLookups=“false”  
    
  3. redirectPort=“8443” acceptCount=“100” debug=“0” connectionTimeout=“20000”  
    
  4. useURIValidationHack=“false” disableUploadTimeout=“true” **/>**   
    

Tomcat5

[html] view plain copy

  1. **** port=“80” maxThreads=“150” minSpareThreads=“25”

  2. maxSpareThreads=“75” enableLookups=“false” redirectPort=“8443”  
    
  3. acceptCount=“100” debug=“0” connectionTimeout=“20000”  
    
  4. disableUploadTimeout=“true” **/>**   
    
     除非客户需要连接到站点的每个HTTP客户端的机器名,否则我们建议在生产环境上关闭DNS查询功能。可以通过Tomcat以外的方式来获取机器名。这样不仅节省了网络带宽、查询时间和内存,而且更小的流量会使日志数据也会变得更少,显而易见也节省了硬盘空间。对流量较小的站点来说禁用DNS查询可能没有大流量站点的效果明显。
    

2.2.2 调整线程数
另外一个可通过应用程序的连接器(Connector)进行性能控制的参数是创建的处理请求的线程数。Tomcat 使用线程池加速响应速度来处理请求。在 Java 中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出 CPU 最大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。
Tomcat4 中可以通过修改 minProcessors 和 maxProcessors 的值来控制线程数。这些值在安装后就已经设定为默认值并且是足够使用的,但是随着站点的扩容而改大这些值。minProcessors 服务器启动时创建的处理请求的线程数应该足够处理一个小量的负载。也就是说,如果一天内每秒仅发生 5 次单击事件,并且每个请求任务处理需要 1 秒钟,那么预先设置线程数为 5 就足够了。但在你的站点访问量较大时就需要设置更大的线程数,指定为参数

maxProcessors 的值。maxProcessors 的值也是有上限的,应防止流量不可控制(或者恶意的服务攻击),从而导致超出了虚拟机使用内存的大小。如果要加大并发连接数,应同时加大这两个参数。web server 允许的最大连接数还受制于操作系统的内核参数设置,通常 Windows 是 2000 个左右,Linux 是 1000 个左右。

    在Tomcat5对这些参数进行了调整,请看下表: 


最好的方式是多设置几次并且进行测试,观察响应时间和内存使用情况。在不同的机器、操作系统或虚拟机组合的情况下可能会不同,而且并不是所有的 web 站点的流量都是一样的,因此没有一刀切的方案来确定线程数的值。

2.2.3 加速 JSP 编译速度
当第一次访问一个 JSP 文件时,它会被转换为 Java servlet 源码,接着被编译成 Java 字节码。客户工程师可以控制使用哪个编译器,默认情况下,Tomcat 使用命令行 javac 进行使用的编译器。也可以使用更快的编译器,这里将介绍如何优化它们。
[LD4] 另外一种方法是不要把所有的实现都使用 JSP 页面,而是使用一些不同的 java 模板引擎变量。
在 Tomcat 4.0 中可以使用流行而且免费的 Jikes 编译器。Jikes 编译器的速度要高于 Sun 的 Java 编译器。首先要安装 Jikes(可访问 http://oss.software.ibm.com/pub/jikes 获得更多的信息),接着需要在环境变量中设置 JIKESPATH 包含系统运行时所需的 JAR 文件。装好 Jikes 以后还需要设置让 JSP 编译 servlet 使用 Jikes,需要修改 web.xml 文件中 jspCompilerPlugin 的值:

[html] view plain copy


  1. ****jsp****  
    
  2. ****  
    
  3.     org.apache.jasper.servlet.JspServlet   
    

  4. ****  
    
  5.     ****logVerbosityLevel****  
    
  6.     ****WARNING****  
    
  7. ****  
    
  8. ****  
    
  9.     ****jspCompilerPlugin****  
    
  10.     ****org.apache.jasper.compiler.JikesJavaCompiler****  
    
  11. ****  
    
  12. ****  
    
  13.     ****classpath****  
    
  14.     ****  
    
  15.         /usr/local/jdk1.3.1-linux/jre/lib/rt.jar:  
    
  16.         /usr/local/lib/java/servletapi/servlet.jar   
    

  17. ****  
    
  18. ****3****  
    

  19. 在Tomcat 4.1(或更高版本),JSP的编译由包含在Tomcat里面的Ant程序控制器直接执行。客户开发人员需要在元素中定义一个名字叫”compiler”,并且在value中有一个支持编译的编译器名字,示例如下:
    

[html] view plain copy


  1. ****jsp****  
    
  2. ****  
    
  3.     org.apache.jasper.servlet.JspServlet   
    

  4. ****  
    
  5.     ****logVerbosityLevel****  
    
  6.     ****WARNING****  
    
  7. ****  
    
  8. ****  
    
  9.     ****compiler****  
    
  10.     ****jikes****  
    
  11. ****  
    
  12. ****3****  
    

Ant 可用的编译器

由于 JSP 页面在第一次使用时已经被编译,那么你可能希望在更新新的 jsp 页面后马上对它进行编译。实际上,这个过程完全可以自动化,因为可以确认的是新的 JSP 页面在生产服务器和在测试服务器上的运行效果是一样的。
在 Tomcat4 的 bin 目录下有一个名为 jspc 的脚本。它仅仅是运行翻译阶段,而不是编译阶段,使用它可以在当前目录生成 Java 源文件。它是调试 JSP 页面的一种有力的手段。
可以通过浏览器访问再确认一下编译的结果。这样就确保了文件被转换成 servlet,被编译了可直接执行。这样也准确地模仿了真实用户访问 JSP 页面,可以看到给用户提供的功能。也抓紧这最后一刻修改出现的 bug 并且修改它。
Tomcat 提供了一种通过请求来编译 JSP 页面的功能。客户可以在浏览器地址栏中输入 http://localhost: 8080/examples/jsp/dates/date.jsp?jsp_precompile=true,这样 Tomcat 就会编译 data.jsp 而不是执行它。此举唾手可得,不失为一种检验页面正确性的捷径。

2.2.4 NIO 配置
NIO (No-blocking I/O)从 JDK 1.4 起,NIO API 作为一个基于缓冲区,并能提供非阻塞 I/O 操作的 API 被引入[LD6] 。

TOMCAT 可以支持高并发的企业级应用。其中有个很大的原因就是,配置良好的 tomcat 都会使用 APR(Apache Portable Runtime),APR 是 Apache HTTP Server2.x 的核心,它是高度可移植的本地库,它使用高性能的 UXIN I/O 操作,低性能的 java io 操作,但是 APR 对客户开发人员而言可能稍稍有点难度,在很多 OS 平台上,可能需要重新编译 APR。但是从 Tomcat6.0 以后, 客户开发人员很容易就可以用 NIO 的技术来提升 tomcat 的并发处理能力。但是为什么 NIO 可以提升 tomcat 的并发处理能力呢,我们先来看一下 java 传统 io 与 java NIO 的差别。
Java 传统的 IO 操作都是阻塞式的(blocking I/O), 如果有 socket 的编程基础,你会接触过堵塞 socket 和非堵塞 socket,堵塞 socket 就是在 accept、read、write 等 IO 操作的时候,如果没有可用符合条件的资源,不马上返回,一直等待直到有资源为止。而非堵塞 socket 则是在执行 select 的时候,当没有资源的时候堵塞,当有符合资源的时候,返回一个信号,然后程序就可以执行 accept、read、write 等操作,一般来说,如果使用堵塞 socket,通常我们通常开一个线程 accept socket,当读完这次 socket 请求的时候,开一个单独的线程处理这个 socket 请求;如果使用非堵塞 socket,通常是只有一个线程,一开始是 select 状,当有信号的时候可以通过多路复用(Multiplexing)技术传递给一个指定的线程池来处理请求,然后原来的线程继续 select 状态。 最简单的多路复用技术可以通过 java 管道(Pipe)来实现。换句话说,如果客户端的并发请求很大的时候,客户系统可以使用少于客户端并发请求的线程数来处理这些请求,而这些来不及立即处理的请求会被阻塞在 java 管道或者队列里面,等待线程池的处理。
在 web 服务器上阻塞 IO(BIO)与 NIO 一个比较重要的不同是,客户系统使用 BIO 的时候往往会为每一个 web 请求引入多线程,每个 web 请求一个单独的线程,所以并发量一旦上去了,线程数就上去了,CPU 就忙着线程切换,所以 BIO 不合适高吞吐量、高可伸缩的 web 服务器;而 NIO 则是使用单线程(单个 CPU)或者只使用少量的多线程(多 CPU)来接受 Socket,而由线程池来处理堵塞在 pipe 或者队列里的请求.这样的话,只要 OS 可以接受 TCP 的连接,web 服务器就可以处理该请求。大大提高了 web 服务器的可伸缩性。
客户只需要在 server.xml 里把 HTTP Connector 做如下更改:

[html] view plain copy

  1. **** port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

    改为

[html] view plain copy

  1. **** port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />

然后启动服务器,如果出现 org.apache.coyote.http11.Http11NioProtocol start 的提示信息,表示 NIO 已经启动。其他的配置请参考官方配置文档。
2.2.5 其它
前面我们提到过操作系统通过一些限制手段来防止恶意的服务攻击,同样 Tomcat 也提供了防止恶意攻击或禁止某些机器访问的设置。
Tomcat 提供了两个参数供你配置:RemoteHostValve 和 RemoteAddrValve。
通过配置这两个参数,可以让你过滤来自请求的主机或 IP 地址,并允许或拒绝哪些主机/IP。与之类似的,在 Apache 的 httpd 文件里有对每个目录的允许/拒绝指定。
例如你可以把 Admin Web application 设置成只允许本地访问,设置如下:

[html] view plain copy

  1. **** path=“/path/to/secret_files”>

  2. **** className=“org.apache.catalina.valves.RemoteAddrValve” allow=“127.0.0.1”deny=““ **/>**  
    

  3.  如果没有给出允许主机的指定,那么与拒绝主机匹配的主机就会被拒绝,除此之外的都是允许的。与之类似,如果没有给出拒绝主机的指定,那么与允许主机匹配的主机就会被允许,除此之外的都是拒绝的。
    

3 负载均衡
在负载均衡的思路下,多台服务器为对等方式,每台服务器都具有同等的地位,可以单独对外提供服务而无须其他服务器的辅助。通过负载分担技术,将外部发送来的请求按一定规则分配到对称结构中的某一台服务器上,而接收到请求的服务器都独立回应客户机的请求。
提供服务的一组服务器组成了一个应用服务器集群(cluster),集群下的对等多机环境可以增加系统的并发处理能力,和单台机器出现故障系统的错误冗余能力;同时实现了负载均衡和系统高可靠性。

四种实现负载均衡的方式:
第一是通过 DNS,但只能实现简单的轮流分配,不能处理故障;
第二如果是基于 MS IIS,Windows 2003 server 本身就带了负载均衡服务;
第三是硬件方式,通过交换机的功能或专门的负载均衡设备可以实现;
第四种是软件方式,通过一台负载均衡服务器进行,上面安装软件。使用 Apache Httpd Server 做负载平衡器。
客户系统一般采用 Apache httpd 作为 web 服务器,即作为 Tomcat 的前端处理器,根据具体情况而定,有些情况下是不需要 Apache httpd 作为 web 服务器的,如系统展现没有静态页面那就不需要 Apache httpd,那时可以直接使用 Tomcat 作为 web 服务器来使用。使用 Apache httpd 主要是它在处理静态页面方面的能力比 Tomcat 强多了。

3.1.1 配置负载均衡器
在 apache 下配置负载均衡器分为三步,注意每次修改 httpd.conf 和 workers2.properties 时不要忘了重新启动 apache。
第一步,安装和调试 apache
负载均衡器 jk2 模块是 apache www 服务的插件,所以配置负载均衡器就得先安装 apache。假设客户下载的是 windows 版本 2.0.43,执行 setup.exe 并回答一些简单问题就可完成 apache 的任务。值得注意的是,安装并启动 apache 后如果 apache 对 http://localhost/ 地址没反应,你得修改 apache 安装路径下 htdocs 目录下的 index.html.xx 文件,比如把 index.html.en 改成 index.html。
第二步,安装 jk2
把下载到的 mod_jk2-2.0.43.dll 改成 mod_jk2.dll 放到 apache 的 modules 目录下,修改 apache 的 httpd.conf,即在 LoadModule foo_module modules/mod_foo.so 行下插入 mod_jk2 模块的装载信息[LD7] :

[html] view plain copy

  1. Example:

  2. LoadModule foo_module modules/mod_foo.so

  3. LoadModule jk2_module modules/mod_jk2.dll

第三步,配置 jk2

jk2 的配置全在一个配置文件中,文件名为 workers2.properties,和 apache 的 httpd.conf 放在同一个目录下。以下是这个文件的内容:

[html] view plain copy

  1. #++++++++++++++++++++++++++++++++++++

  2. only at beginnin. In production uncomment it out

  3. [logger.apache2]

  4. level=DEBUG

  5. #shm 必须配

  6. [shm]

  7. file=D:\Program Files\Apache Group\Apache2\logs\shm.file

  8. size=1048576

  9. 第一个 tomcat 的地址

  10. Example socket channel, override port and host.

  11. [channel.socket:tomcat1]

  12. port=11009

  13. host=127.0.0.1

  14. 定义第一个工作者指向第一个 tomcat

  15. define the worker

  16. [ajp13:tomcat1]

  17. channel=channel.socket:tomcat1

  18. #第二个 tomcat 得地址

  19. Example socket channel, override port and host.

  20. [channel.socket:tomcat2]

  21. port=12009

  22. host=10.1.36.123

  23. 定义第二个工作者指向第二个 tomcat

  24. define the worker

  25. [ajp13:tomcat2]

  26. channel=channel.socket:tomcat2

  27. #定义负载均衡器,使其包含两个工作者

  28. [lb:lb1]

  29. worker=ajp13:tomcat2

  30. worker=ajp13:tomcat1

  31. #指定负载均衡器完成单一地址映射,使得 apache 服务所在的 uri 全部指向 两个 tomcat 上的 root

  32. Uri mapping

  33. [uri:/*]

  34. group=lb:lb1

  35. #++++++++++++++++++++++++++++++++++++++++++

3.1.2 配置 tomcat

    同属于一个集群下的两个服务实体,要求功能的同一性,所以我们可先安装和配置第一个tomcat,接着拷贝形成第二个tomcat,最后配置第二个tomcat。 

安装 tomcat 非常简单,本文就不再描述。我们假设第一个 tomcat 的安装路径为 d:\tomcat1。
配置第一个 tomcat:

tomcat 中的 jk2 connector 缺省端口为 8009,为了在一台机器上运行两个 tomcat,修改 D:\Tomcat1\conf\jk2.properties,设置 jk2 connector 的端口为 11009,整个文件内容如下:

[html] view plain copy

  1. #++++++++++++++

  2.            channelSocket.port=11009   
    
  3.          #++++++++++++++   
    

为了让一台机器上运行两个 tomcat,修改 server.conf 的 tomcat 停止指令监听端口:

[html] view plain copy

  1. **** port="8005" shutdown="SHUTDOWN" debug="0">

改为

[html] view plain copy

  1. **** port="11005" shutdown="SHUTDOWN" debug="0">

然后打开 JK2 AJP connector ,关闭其它 connector,下面是 JK2 AJP 1.3 的样子,这里已把它的端口改为 11009:

  1. **** className="org.apache.coyote.tomcat4.CoyoteConnector"

  2. port="11009" minProcessors="5" maxProcessors="75" enableLookups="true"  
    
  3. redirectPort="8443" acceptCount="10" debug="0" connectionTimeout="20000"  
    
  4. useURIValidationHack="false" protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler" **/>**   
    

接着配置需要集群支持的 webapp(比如 examples) 的 context,添加如下 manager:

[html] view plain copy

  1. **** className="org.apache.catalina.session.InMemoryReplicationManager"

  2. protocolStack="UDP(mcast_addr=228.1.2.3;mcast_port=45566;ip_ttl=32):PING(timeout=3000; num_initial_members=6):FD(timeout=5000):VERIFY_SUSPECT(timeout=1500): pbcast.STABLE(desired_avg_gossip=10000):pbcast.NAKACK(gc_lag=10; retransmit_timeout=3000):UNICAST(timeout=5000;min_wait_time=2000): MERGE2:FRAG:pbcast.GMS(join_timeout=5000;join_retry_timeout=2000; shun=false;print_local_addr=false)"**>**  
    

注意 protocolStack 的值必须在一行内写完。
配置第二个 tomcat:
把已经配好的第一个 tomcat 复制一份,形成第二个 tomcat,假设路径为 d:\tomcat2。
修改 D:\Tomcat2\conf\jk2.properties,设置 jk2 connector 的端口 12009,整个文件内容如下:

[html] view plain copy

  1. #++++++++++++++

  2. channelSocket.port=12009

  3. #++++++++++++++

修改 server.conf
有了第一个 tomcat 的配置我们只需修改 server.conf 的 tomcat 停止指令监听端口:
改为

然后设置 JK2 AJP connector 端口为 12009。
3.1.3 运行测试
启动 apache,tomcat1 和 tomcat2。

我们先准备两个文件,第一个文件为 test.jsp,拷贝到第一个 tomcat 的根 web 应用的目录即 d:\tomcat1\webapps\ROOT 下:


  1. **** bgcolor="red"**>**  
    
  2.     ****  
    
  3.         **<**%= request.getSession().getId() %**>**  
    
  4.         ****Tomcat 1****  
    
  5. ****  
    

第二个文件也为 test.jsp,拷贝到第二个 tomcat 的根 web 应用的目录即 d:\tomcat2\webapps\ROOT 下:

[html] view plain copy


  1. **** bgcolor="blue"**>**  
    
  2.     ****  
    
  3.         **<**%= request.getSession().getId() %**>**  
    
  4.         ****Tomcat 2****  
    
  5. ****  
    

从不同的浏览器中多次输入地址 http://localhost/test.jsp 会看到不同的颜色,这表明 apache 中的 jk2 模块起到了负载均衡的作用。
4 容量计划
容量计划是在生产环境中使用 Tomcat 不得不提的提高性能的另一个重要的话题。如果你没有对预期的网络流量下的硬件和带宽做考虑的话那么无论你如何做配置修改和测试都无济于事。
这里先对提及的容量计划作一个简要的定义:容量计划是指评估硬件、操作系统和网络带宽,确定应用服务的服务范围,寻求适合需求和软件特性的软硬件的一项活动。因此这里所说的软件不仅包括 Tomcat,也包括与 Tomcat 结合使用的任何第三方 web 服务器软件。
如果在购买软硬件或部署系统前你对容量计划一无所知,不知道现有的软硬件环境能够支撑多少的访问量,甚至更糟直到你已经交付并且在生产环境上部署产品后才意识到配置有问题时再进行变更可能为时已晚。此时只能增加硬件投入,增加硬盘容量甚至购买更好的服务器。如果事先做了容量计划那么就不会搞的如此焦头烂额了。
我们这里只介绍与 Tomcat 相关的内容。
首先为了确定 Tomcat 使用机器的容量计划,你应该从一下列表项目种着手研究和计划:
4.1.1 硬件
采用什么样的硬件体系?需要多少台计算机?使用一个大型的,还是使用多台小型机?每个计算机上使用几个 CPU?使用多少内存?使用什么样的存储设备,I/O 的处理速度有什么要求?怎样维护这些计算机?不同的 JVM 在这些硬件上运行的效果如何(比如 IBM AIX 系统只能在其设计的硬件系统上运行)?
4.1.2 网络带宽
带宽的使用极限是多少?web 应用程序如何处理过多的请求?
4.1.3 服务端操作系统
采用哪种操作系统作为站点服务器最好?在确定的操作系统上使用哪个 JVM 最好?例如,JVM 在这种系统上是否支持本地多线程,对称多处理?哪种系统可使 web 服务器更快、更稳定,并且更便宜。是否支持多 CPU?
4.1.4 Tomcat 容量计划
以下介绍针对 Tomcat 做容量计划的步骤:
1) 量化负载。如果站点已经建立并运行,可以使用工具模仿用户访问,确定资源的需求量。
2) 针对测试结果或测试过程中进行分析。需要知道那些请求造成了负载过重或者使用过多的资源,并与其它请求做比较,这样就确定了系统的瓶颈所在。例如:如果 servlet 在查询数据库的步骤上耗用较长的时间,那么就需要考虑使用缓冲池来降低响应时间。

3)确定性能最低标准。例如,你不想让用户花 20 秒来等待结果页面的返回,也就是说甚至在达到访问量的极限时,用户等待的时间也不能超过 20 秒种(从点击链接到看到返第一条返回数据)。这个时间中包含了数据库查询时间和文件访问时间。同类产品性能在不同的公司可能有不同的标准,一般最好采取同行中的最低标准或对这个标准做出评估。
4)确定如何合理使用底层资源,并逐一进行测试。底层资源包括 CPU、内存、存储器、带宽、操作系统、JVM 等等。在各种生产环境上都按顺序进行部署和测试,观察是否符合需求。在测试 Tomcat 时尽量多采用几种 JVM,并且调整 JVM 使用内存和 Tomcat 线程池的大小进行测试。同时为了达到资源充分合理稳定地使用的效果,还需针对测试过程中出现的硬件系统瓶颈进行处理确定合理的资源配置。这个过程最为复杂,而且一般由于没有可参考的值所以只能靠理论推断和经验总结。
5) 如果通过第 4 步的反复测试如果达到了最优的组合,就可以在相同的生产环境上部署产品了。

此外应牢记一定要文档化你的测试过程和结果,因为此后可能还会进行测试,这样就可以拿以前的测试结果作为参考。另外测试过程要反复多次进行,每次的条件可能都不一样,因此只有记录下来才能进行结果比较和最佳条件的选择。

这样客户系统通过测试找到了最好的组合方式,各种资源得到了合理的配置,系统的性能得到了极大的提升。

  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    915 引用 • 931 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
zgzhang
论一个笨蛋的自我修养。 北京

推荐标签 标签

  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 399 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 2 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 18 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    51 引用 • 37 回帖
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    9 引用 • 32 回帖 • 166 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 2 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 609 关注
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 588 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 687 关注
  • Hprose

    Hprose 是一款先进的轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库。它不仅简单易用,而且功能强大。你无需专门学习,只需看上几眼,就能用它轻松构建分布式应用系统。

    9 引用 • 17 回帖 • 597 关注
  • 安装

    你若安好,便是晴天。

    128 引用 • 1184 回帖
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 512 关注
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖 • 6 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 291 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    16 引用 • 53 回帖 • 123 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 429 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    330 引用 • 614 回帖
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    28 引用 • 108 回帖
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 19 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 39 关注
  • 倾城之链
    23 引用 • 66 回帖 • 101 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    10 引用 • 85 回帖
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    7 引用 • 26 回帖 • 2 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1398 回帖 • 1 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    76 引用 • 390 回帖