原文来自,
[url]http://wiki.jboss.org/wiki/JBossASTuningSliming[/url]
,翻译的不当之处请谅解。
JBossAS
的调优
|
基于JBoss 3.2.6 。
FOR 4.0.4+修订版 JBoss4瘦身
前言
这个建议主要是如果对JBossAS进行调优和瘦身的. 这个概念在多数情况是交叉的。当通过瘦身减少闲置服务线程并不能带来大的性能影响的时候,允许你使用较少的内存和资源对其他性能方便进行调整。当然它可以缩短启动时间。而且,作为一般的安全观念――移除你不使用的服务。我们将分开两个种类: 瘦身和调优. 首先我们使用默认的配置并从那里开始瘦身(对于clustering的话题,将在以后的wiki页面进行讨论 ;-) ). 这个建议不牵扯开发者和管理角色交叉调优的区域开发者和管理角色 (应用程序调优象cache大小一样). 这主要是对于管理调优的建议.
这建议将做技术上非J2EE平台兼容(3.2.6无论如何不顺从)的JBoss实例的有关的那些注意,象除去J2EE关键 服务的那样将导致JBoss 失败TCK。多数性能调优/管理任务工作,在现实世界结构里,在技术上属于这个类别。
假设你已经复制server/default 文件夹并将它重新命名为server/slim.
调优
Java Virtual Machine Java虚拟机
l
对于你的机器和内存大小来调整VM垃圾收集或者调整 JDK 5 的垃圾收集
l
使用64位的机器和64位的VM,以便你能使用大的heap(堆)大小,通常比2-4GB的大。64位支持在所有最新的SPARC/Solaris 寄存器运行Solaris 9 或者以后的版本是有效的, Itanium 使用 JDK 1.4, 或者在Linux x64 上使用JDK 5.
l
如果你不使用上面的最大32位heap空间(2-4 GB 的heap),不要使用 –d64. 使用64位地址需要更多的内存来做同样的工作量,并且对于应用程序不需要如此多的内存来说并不能提供更大优势。
l
除了避免额外小的heaps外还要避免额外大的heaps. (我们不能告诉你具备什么资格,因为它取决于你正做什么). 这影响generational 垃圾收集和扫描heap的总的时间. 有效的调整一个小heap是困难的 (即使你的应用程序仅仅需要使用200MB,如果你使用并行垃圾收集+CMS,然后你将需要远高于512MB). 特大号的heaps为垃圾收集花费不必要的时间扫描内存。
l
避开 Sun 1.4 VM. JDK 5 主要是在垃圾收集方面非常的好.
l
使用 -server 参数除了使用其他-XX:ThreadStackSize=128k (Solaris) 或者 -Xss128k (其他任何平台). 在Solaris 上 -Xss128k 什么也没有做 (你只可以设置较大的线程栈大小). 这允许你每个线程通过使用较少的内存达到创建更多线程的目的。but might result in blown stacks with extremely recursive code. 然而, 128k 栈 is still nothing to shake a stick at.
l
你真的需要明白恰当的generational 垃圾收集调整和你真的已经进行了负载测试 (OpenSTA?, JMeter, 等等) 确认是有把握的.
l
你确实将使用一个超过2个处理器的多核心机器,及使用不同的平行和并行垃圾收集选择 (
我们谈及这先进的
JBoss
训练暗示伏笔
) 对于最大性能和高拉机回收吞吐量. 不过,你确实需要理解怎么调整才能使得垃圾收集很好的工作。JDK 5大部分是自我调整.
l
JDK 1.4的默认 NewSize? 不是好的猜想. 坏的经验法则: < 20% 是一个好的 NewSize?. 20%以上的消费是危险的,这是JDK令人讨厌的一个,能导致它psychotically运行所有满垃圾回收和从未 unsuspend 或者释放出 足够多的内存. JDK 5 似乎没有展示出这个bug,并且
似乎已回升更理智的默认值。
JBoss/Java on Linux
如果你正在运行JBoss AS在Linux服务器上,你应该看看这篇文章的作者: Andrew Oliver, Jboss事业部, Red Hat公司, 顾问 ,在 在Linux服务器上怎么优化Jboss/Java
Tomcat
l
编辑你的server/slim/jbossweb-tomcat5?.sar/server.xml 文件
l
检查你正在使用的连接器的XML文档. 例如, HTTP 连接器:
<
Connector
port
="8080"
address
="${jboss.bind.address}"
maxThreads ="150" minSpareThreads ="25" maxSpareThreads ="75"
enableLookups ="false" redirectPort ="8443" acceptCount ="100"
connectionTimeout ="20000" disableUploadTimeout ="true" />
maxThreads ="150" minSpareThreads ="25" maxSpareThreads ="75"
enableLookups ="false" redirectPort ="8443" acceptCount ="100"
connectionTimeout ="20000" disableUploadTimeout ="true" />
l
你应该有多于你最大预期25%(经验法则)的线程(maxThreads)来处理负载(将来一次性的并发访问)
l
你应该有minSpareThreads 等于恰好比你正常负载多一点
l
你应该有maxSpareThreads等于恰好比你峰值负载多一点
l
minSpareThreads 意思是 "启动准备就绪, 总是保持至少这些线程来等待处理"
l
maxSpareThreads means "如果我们总是超过minSpareThreads那么总是保持 maxSpareThreads 来等待处理"
l
移除任何不需要的值和日志。如果你不用JBoss的安全,移除这个安全值 (见下面).
l
Precompile(预编译) JSPs. (这个内置的编译器非常的会,它可能对于小型站点不值得做.)
l
在你的sever/slim/jbossweb-tomcat50.sar/conf/web.xml 里关闭开发("development")模式
RMI的远程调用
默认情况下, JBoss为进来的每个RMI请求创建一个新线程. 在一个大系统中这一般不是高效率的. 其次,它允许无限制的连接在性能或者通信峰值或者run-away 连接方面创建客户端可能是危险的。为了补救这个你应该考虑转向被集中的池请求.
编辑 server/slim/conf/standardjboss.xml
通过改变每个
XML
分段读数把所有代理绑定改变成被集中的
池请求:
<
invoker-mbean
>jboss:service=invoker,type=jrmp
invoker-mbean
>
到
<
invoker-mbean
>jboss:service=invoker,type=pooled
invoker-mbean
>
JBoss
也有大部分无文件证明的
PooledInvokerHA
你可以试试。
Log4j
日志在性能方面也有重要的影响. 改变日志级别跟踪能给JBossAS 带来蠕虫一样的速度。改变级别为 ERROR (或者WARN) 能引人注目的提升速度。
l
默认情况下, JBoss的日志被打印到控制台和server.log文件里并且它默认使用的日志级别是 "INFO".
l
考虑不记录到System.out (你也能仍旧想改变方向以抓取JVM 错误)
l
考虑改变日志的级别为ERROR. 观察JBoss的log4j配置文件的变化,你可以在其运行的时候改变这个配置。
l
给你的java class层次增加一个类别过滤器.
关掉打印到控制台的日志(console logging):
l
编辑 server/slim/conf/log4j.xml
l
改变下面的XML 片段:
<
root
>
< appender-ref ref=CONSOLE" />
< appender-ref ref ="FILE" />
root >
< appender-ref ref=CONSOLE" />
< appender-ref ref ="FILE" />
root >
修改成
<
root
>
< appender-ref ref ="FILE" />
root >
< appender-ref ref ="FILE" />
root >
l
然后你可以删除此片段:
<
appender
name
="CONSOLE"
class
="org.apache.log4j.ConsoleAppender"
>
< errorHandler class ="org.jboss.logging.util.OnlyOnceErrorHandler" />
< param name ="Target" value ="System.out" />
< param name ="Threshold" value ="INFO" />
< layout class ="org.apache.log4j.PatternLayout" >
< param name ="ConversionPattern" value ="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
layout >
appender >
< errorHandler class ="org.jboss.logging.util.OnlyOnceErrorHandler" />
< param name ="Target" value ="System.out" />
< param name ="Threshold" value ="INFO" />
< layout class ="org.apache.log4j.PatternLayout" >
< param name ="ConversionPattern" value ="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
layout >
appender >
改变日志的级别:
l
编辑 server/slim/conf/log4j.xml
l
移除/注释 这些XML 片段:
<
category
name
="org.apache"
>
< priority value ="INFO" />
category >
< category name ="org.jgroups" >
< priority value ="INFO" />
category >
< priority value ="INFO" />
category >
< category name ="org.jgroups" >
< priority value ="INFO" />
category >
l
改变这个XML片段以改变root类别:
<
root
>
< appender-ref ref ="CONSOLE" />
< appender-ref ref ="FILE" />
root >
< appender-ref ref ="CONSOLE" />
< appender-ref ref ="FILE" />
root >
看上去像这样
<
root
>
< priority value ="ERROR" />
< appender-ref ref ="CONSOLE" />
< appender-ref ref ="FILE" />
root >
< priority value ="ERROR" />
< appender-ref ref ="CONSOLE" />
< appender-ref ref ="FILE" />
root >
另外,如果你使用了hibernate的话:
l
编辑 server/slim/conf/log4j.xml
l
增加如下XML 片段
<
category
name
="org.hibernate"
>
< priority value ="INFO" />
category >
< priority value ="INFO" />
category >
最后, 在log4j中也许是最重要的事情,在你拥有的 class 结构上确保你的极限的日志级别. 假设你正在使用的log4j打算不向System.out打印任何东西. 这将大大的降低log4j的额外开销,并且允许你完全享受益处,像如果调用(log.isDebugEnabled())....如果你那么做,那么你的代码中的所有日志都将通过appender进行格式化, 这个threshold 在appender将被从日志消息中去除出去. 它能产生大量的垃圾信息。假设你的java package 以“a.b”开始的话, 在log4j.xml增加一些像这样的信息:
< category name ="a.b" >
< priority value ="INFO" />
category >
部署扫描器(Deployment Scanner )
l
部署扫描器每隔5秒扫描一次,在比较慢的文件系统上尤其吃周期 (*cough* NTFS *cough*).
l
见下面的瘦身stuff on ,怎么调整秒数以至于它发生的不那么频繁或者不全部发生。
无状态会话Beans(Stateless Session Beans )
l
EJB 1.x-2.x 无状态会话beans operate with an ill-advised pooling model (required by the specification). 如果你find你需要考虑设置比默认(10)实例要多的最小线程池的大小:
编辑 server/slim/conf/standardjboss.xml, 向下滚动:
<
container-configuration
>
< container-name >Standard Stateless SessionBean container-name >
< call-logging >false call-logging >
< invoker-proxy-binding-name >stateless-rmi-invoker invoker-proxy-binding-name >
< container-interceptors >
< container-name >Standard Stateless SessionBean container-name >
< call-logging >false call-logging >
< invoker-proxy-binding-name >stateless-rmi-invoker invoker-proxy-binding-name >
< container-interceptors >
并找到:
<
container-pool-conf
>
< MaximumSize >100 MaximumSize >
container-pool-conf >
container-configuration >
< MaximumSize >100 MaximumSize >
container-pool-conf >
container-configuration >
改变它为:
<
container-pool-conf
>
< MinimumSize >100 MinimumSize >
< MaximumSize >100 MaximumSize >
< strictMaximumSize />
< strictTimeout >30000 strictTimeout >
container-pool-conf >
container-configuration >
< MinimumSize >100 MinimumSize >
< MaximumSize >100 MaximumSize >
< strictMaximumSize />
< strictTimeout >30000 strictTimeout >
container-pool-conf >
container-configuration >
在很大程度上一种服务器环境中不希望这些池增长和缩减(因为它导致内存碎片,不如潜在的堆使用). 从性能上来说, nuber要足够的大以提供保证你的所有请求不阻塞的服务。
CMP 调整
l
读这个链接: [url]http://www.artima.com/forums/flat.jsp?forum=141&thread=24532[/url]
l
和这个链接: [url]http://www.onjava.com/pub/a/onjava/2003/05/28/jboss_optimization.html[/url]
l
现在ditch CMP 和使用JBossHibernate 代替
连接池(Connection Pools)
l
不要使用XA版本,除非你真的知道你需要使用它. XA连接的性能不好.
l
与其在可用的地方利用数据库特定的"ping"支持"check-connection"(检查连接),或者利用数据库特定驱动的fail-over支持倒不如从不checking connections. (记住并非所有的优化选项都适合你的环境,我们正在讨论的是最佳情况) 。