五、优化默认执行队列线程
默认情况下,一个新的 WebLogic 实例配置了一个开发模式执行队列, weblogic.kernel.default, 它包含 15 个线程。另外, WebLogic 提供了 2 个预配置队列:
n weblogic.admin.HTTP——只在管理服务器上才有,这个队列供与管理控制台的通信用,你不能再配置它。
n weblogic.admin.RMI——管理服务器和被管理服务器上都有这个队列,它是供管理的交通之用,也不能再配置它。
如果你不配置额外的执行队列,并且指定应用给这些队列, web 应用程序和 RMI 对象就使用默认的队列 weblogic.kernel.default 。
注意;如果自带的执行包没有在你的平台上使用,你可能需要调整默认的执行队列线程数和担任 socket 读的线程的百分比,去实现最佳性能。
5 . 1 你应该更改默认的线程数吗 ?
增加更多的线程到默认的执行队列并不意味着你能处理更多的工作。即使增加更多的线程,仍然被处理器的能力限制。因为线程消耗内存,所以增加线程数属性的值不必要的降低了性能。一个高的执行线程数导致更多的内存被占用并且增加了上下文转换程序,它也会降低性能。
线程数属性的值与应用程序处理的工作的类型关系密切。例如,如果你的客户应用程序比较小,通过远程调用处理的工作较多,这样,客户端会花费更多的时间连接,因此,与能完成大量客户端任务的客户应用程序相比,会需要更多的线程数。
如果你的工作不需要使用超过15个线程(开发模式默认)或者25个线程(产品模式默认),就不要改变这个属性的值。通常,如果你的应用程序访问数据库花很长时间才返回结果,与访问数据库很短时间就返回的应用程序比较,你会需要更多的执行线程。从后者来看,用少点的线程数可能提高性能。
5 . 2 需要修改默认线程数的情形
为了给执行队列决定一个理想的线程数,当队列中所有应用程序都运行在最大负荷的情况下,监视队列的吞吐量。增加线程数,重复负载测试,直到达到最佳的吞吐量。(在某些情况下,增加线程数将产生足够多的上下文转换程序,使得队列中的吞吐量开始减少。)
注意: WebLogic 管理控制台显示的是所有服务器执行队列累积的吞吐量。为了得到这个值,后面将会介绍。
下表列出了在WebLogic 域中调整的线程及与CPU数量相关的情形,这些情况也假定WebLogic运行在最大负荷下,并且使用默认的执行队列满足所有的线程的请求。如果你配置了额外的执行队列并指派了应用程序到具体的队列,就需要依据一个个连接池得到结果。
如果… 结果 应该:
线程数<CPU的数量 线程数太少,如果:
CPU 正等着工作,但有工作被完成。
CPU 利用率不能达到100%。 增加线程数。
线程数=CPU的数量 理论上理想,但是CPU仍然低利用。 增加线程数。
线程数(适当的)>CPU的数量 实际中理想,有个适当的上下文转换程序数量和高的CPU利用率。 调整适当的线程数并且比较性能结果。
线程数(较大的)>CPU的数量 过多的上下文转换程序,能导致重大的性能降级。
当你降低线程数时,性能可以增强。 减少线程数,使它等于CPU的数量,然后仅仅增加已经得出的“堵塞”线程的数量。
例如,如果你有4个处理器,它们都同时运行,并出现堵塞线程,于是,你想要的执行线程就是4+堵塞线程的数
5 . 3 修改默认线程数的步骤
用管理控制台修改默认执行队列线程数如下:
1. 如果管理服务器没有运行,先启动。
2. 访问管理控制台。
3. 展开左边面板的Servers 节点,显示域服务。
4. 右击服务名称,在弹出菜单中选择View Execute Queues ,就会在右边面板显示有执行队列的表用来修改。
注意:你只能修改默认的执行队列或者用户定义的执行队列。
5. 在Name列,直接点击默认执行队列名称,显示配置标签用来修改执行队列数。
6. 填下适当的线程数。
7. 点击Apply,保存刚才的修改。
8. 重启服务器,使新的执行队列设置生效。
5 . 4 指派应用程序到执行队列
虽然可以配置默认的执行队列,为所有的 WebLogic 应用程序提供最佳的线程数,但是为关键的应用程序配置多个执行队列可以提供更多的管理控制。通过使用多执行队列,你可以保证应用程序有权占用固定的线程数,而不管 WebLogic 服务器有多大的负荷。
5 . 5 创建执行队列
一个执行队列代表执行线程的命名集,线程指向一个或多个 Servlet 、 JSP 、 EJB 、 RMI 对象。执行队列在 config.xml 文件中描述,作为服务器元素的一部分。如,在 config.xml 文件中描述一个有 4 个线程的队列,命名为 CriticalAppQueue ,如下:
...
<server Name="examplesServer" ListenPort="7001" NativeIOEnabled="true">
<executequeue Name="default" ThreadCount="15">
<executequeue Name="CriticalAppQueue" ThreadCount="4">
...
</server>
另一种创建队列的方法是通过管理控制台,配置步骤如下:
1 . 启动管理服务器,访问控制台。
2 . 展开左边面板中 Servers 节点,显示域中要配置的服务。
3 . 右击你要增加队列的服务实例,从弹出菜单中选择 View Execute Queues 。
4 . 在队列配置标签中,点击配置新执行队列链接。
5 . 在队列配置标签中,更改下列属性或接受系统的默认值:
n 线程名称( Name ):你可以输入线程名称,如 CriticalAppQueue 。
n 队列长度 (Queue Length) :通常保留默认值 65536 ,队列长度表明了同时发来请求的最大数, 65536 个请求是个很大的数,即使达到这个最大数,也是很少见的。
如果达到最大队列长度, WebLogic 会自动成倍增长队列大小,以处理额外的工作。
注意:超过 65536 个请求预示队列中的线程有问题,不仅仅只是队列本身的长度问题,实践表明在队列中有堵塞线程或线程数不足的情况存在。
n 队列长限制百分比( Queue Length Threshold Percent ):达到队列长度百分比( 1 - 99 )时,就构成了溢出条件的产生。实际队列大小在限制的百分比之下时才被认为是正常的;在限制百分比之上就会产生溢出。当出现溢出, WebLogic 日志就会产生一个错误消息,并且按线程数增量( Threads Increase )属性的值增加线程数,以帮助减少负载量。
默认的队列长限制百分比为 90 %。一般情况下,应保留 90 %或其左右,以应对一些潜在的情况,使得有额外的线程可以去处理一些请求中的异常。记住,队列长度限制百分比不是一定作为自动优化参数――因为正常运作情况下,这个限度从不会被触发。
n 线程数( Tread Count ):指派到这个队列的线程数。如果你不需要使用超过 15 个线程(默认),就不必更改这个属性值。
n 线程数增量( Threads Increase ):是指 WebLogic 探测到有溢出时,增加到执行队列的线程数。当你指定为 0 (默认),出现溢出时, WebLogic 会把运行良好状态改为“警告”,而且也不会指派额外的线程去减少负荷量。
注意:如果 WebLogic 实例的线程数响应了溢出,那么这些额外的线程就会滞留在执行队列,直到服务器重启。监视错误日志,以判断溢出产生的原因,以便根据需要重配置线程数,防止以后类似情况产生。不要同时使用线程数增量和队列长限制百分比作为自动优化的手段。如此做通常结果会产生比正常需要还多的线程被指派到执行队列,这样上下文转化程序的增多会使服务器遭受很差的性能。
n 最大线程数:是指执行队列中能运行的,这个值保护 WebLogic 为了响应频繁溢出,创建过多的线程数。默认情况下,最大线程数为 400 。
n 线程优先级:线程优先级与此队列相关。默认值为 5 。
6 . 点击 Create ,创建队列。
7 . 重启服务器。
5 . 6 指派 Servlet 和 JSP 到执行队列
你可以把 servlet 或 JSP 分配到指定的配置执行队列,只需在初始参数中标识执行队列的名称。初始参数出现在 Servert 或 JSP 的部署描述文件 web.xml 中的 init-param 元素里。为了分配一个队列,可以把队列名作为 wl-dispatch-policy 参数的值。如:
<servlet>
<servlet-name>MainServlet</servlet-name>
<jsp-file>/myapplication/critical.jsp</jsp-file>
<init-param>
<param-name>wl-dispatch-policy</param-name>
<param-value>CriticalAppQueue</param-value>
</init-param>
</servlet>
5 . 7 指派 EJB 和 RMI 对象到执行队列
为了把 EJB 分配到指定的队列,可以使用 weblogic-ejb-jar.xml 文件中 dispatch-policy 元素。
然而你也可以通过使用 appc 编译器 - dispatchPolicy 选项来设置派遣策略, BEA 强烈推荐使用部署描述元素。因为用这种方式,如果 EJB 重编译,在部署用例期间,这个设置不会被丢失。
为了把 RMI 对象分配到指定的队列,可以使用 rmic 编译器的- dispatchPolicy 选项,如:
java weblogic.rmic -dispatchPolicy CriticalAppQueue ...
5 . 8 分配执行队列担任 Socket 读
为了获得更好的 socket 性能, BEA 推荐你使用自有的 socket 读执行工具,它更优于纯 Java 执行工具。然而,如果你一定要在主机上用纯 Java 的 socket 读,你仍然可以通过配置恰当的执行线程数以提高 socket 通信性能,为每个服务器实例和客户机器担负 socket 读线程的任务。
Socket 读占线程池百分比( ThreadPoolPercentSocketReader )属性可以设置用来从 socket 读消息的执行线程的最大百分比。这个属性的最优值是根据应用程序的需要指定的。默认值是 33 ,有效范围在 1 - 99 之间。
分配执行线程担任 socket 读增加了服务器处理速度和接受客户请求的能力。有必要平衡执行线程数,使其专注于从 socket 读消息,也有必要平衡那些在服务器处理实际任务的执行线程。
5 . 9 为服务器实例设置 socket 读的线程数的操作
1 . 启动管理服务器,访问域控制台。
2 . 展开左边面板 Servers 节点,显示域服务配置。
3 . 点击你要配置的服务名称。
4 . 选择配置( Configuration )―― > 调整( Tuning )标签。
5 . 在 Socket Reader 中编辑 Java 读线程的百分比。 Java socket 读线程数是根据所有的执行线程数的百分比计算得到的。
6 . 应用( Apply )这个调整。
5 . 10 在客户机设置 Socket 读线程数
在客户机上,你可以配置运行在 JVM ( Java 虚拟机)上的 socket 读线程数。指定 Socket 读,需要通过用 java 命令行定义下列参数:
-Dweblogic.ThreadPoolSize=value
-Dweblogic.ThreadPoolPercentSocketReaders=value
5 . 11 优化溢出情况时的执行队列
你可以配置 WEBLOGIC 监测并且随时应对潜在的溢出,不管其发生在默认的执行队列还是用户定义的队列。一旦当前队列大小快达到用户定义的百分比, WebLogic 认为队列中有一个可能的溢出产生。
当这个限度到达时,服务器改变它的良好状态为“警告”,随即分配额外的线程去处理超负荷的工作,从而还原它的大小。
为了自动监测和应对溢出,你可以配置以下项:
1 . 队列长限制百分比,这个值是队列大小的百分比。
2 . 当溢出发生时,增加到队列的线程数。这些额外的线程以还原队列到正常的运行的大小。
3 . 线程的最大数,在特殊情况下,线程最大数用来保护服务器在响应过载情况下过度分配线程数。
5 . 12 优化执行队列的监测行为
当一个线程在队列中变成堵塞状态时, WebLogic 会自动监测到。因为堵塞线程不能完成它当前的工作或接受新的工作,服务器每次诊断一个堵塞线程,就记入一个消息到日志中。如果一个队列中所有的线程变成堵塞,服务器改变良好状态成“警告”或者“危机”,依赖于下列情况:
n 如果默认队列中所有的线程变成堵塞,服务器状态变成“危机”。(你可以设立节点管理器( Node Manager )应用去自动关闭及重启服务器。)
n 如果在 weblogic.admin.HTTP, weblogic.admin.RMI 或用户定义的队列中所有线程变成堵塞,服务器状态变成“警告”。
WebLogic 诊断到一个堵塞线程,如果它是在指定的时间内连续不断的工作(没有空闲)。你可以调整服务器线程监测行为,它是通过改变堵塞线程被诊断前的时间长度和服务器核查堵塞线程的频率。
注意:尽管你能改变标准 WebLogic 去决定一个线程是否堵塞,但,你不能改变默认行为,就是出现堵塞时把服务器设置成“警告”或“危机”的行为。
配置 WebLogic 堵塞线程监测行为的步骤:
1 . 启动 WebLogic ,访问管理控制台。
2 . 点击你想为改善堵塞线监测而修改的服务器实例的名称。
3 . 选择配置( Configuration )―― > 调整( Tuning )标签。
4 . 修改下列参数:
n 堵塞线程最大时间( Stuck Thread Max Time ):输入秒数,线程一定是不断的运行,服务器才会诊断这个线程作为堵塞。默认情况下, WebLogic 认为线程连续不断运行 600 秒后置为堵塞。
n 堵塞线程时间间隔( Stuck Thread Timer Interval ):输入秒数,这个时间是 WebLogic 周期性的扫描线程以察觉它们是否连续不断运行了某一线程的时间达到通过堵塞线程最大时间属性指定的时间长度。默认时间间隔为 600 秒。
5 . 应用( Apply )设置。
6 . 重启服务器。
六、优化连接缓存
Config.xml 文件中的元素接受缓存数( AcceptBacklog )属性是用来设定请求 WebLogic 实例的连接数,在拒绝额外的请求之前,能接受设定的缓存数。 AcceptBacklog 属性指定有多少 TCP 连接缓存在等待队列,这个固定的队列存放了 TCP 堆栈已经收到但应用程序还没有收到的连接请求。默认值是 50 ,最大值由操作系统决定。
在控制台调整接受缓存数的步骤:
1. 启动 WebLogic ,访问控制台。
2. 展开左边面板 Servers 节点。
3. 点击你要配置的服务器实例的名称。
4. 选择配置( Configuration )―― > 调整( Tuning )标签。
5. 根据需要修改默认的接受缓存数( Accept Backlog ):
n 在运行期间,如果许多客户端连接得不到响应或被拒绝,并且服务器端也没有错误消息,说明接受缓存的值可能太小。
n 在你访问 WebLogic 时,如果收到“拒绝连接( connection refused )”的提示,则应该增加接受缓存的默认值的 25 %。继续增加其值的 25 %,直到停止出现这样的提示。
6. 点击应用( Apply ),保存设置。
七、如何提高 JDBC 连接池的性能
创建一个带 DBMS 的 JDBC 连接是非常慢的。如果应用程序需要数据库不断的连接和断开,这种创建方式会造成一个重大的性能问题。 WebLogic 连接池提供了一种高效的解决方案来解决这个问题。
当启动 WebLogic ,就打开连接池,以便于所有客户连接。当一个客户关闭一个连接,这个连接就返回到连接池,供其他的客户使用。连接本身不会关闭。如此就用极少的代价实现了连接和断开连接池。
在连接池里应该创建多少连接呢?连接池会根据配置参数中的最大数与最小数之间增加或减少连接。最好的性能应该是连接数与当前客户会话( Session )数相同。
7 . 1 调整 JDBC 连接池的初始容量
在配置连接池时, JDBCConnectionPool 元素中的 InitialCapacity 属性能设定连接数,创建物理的数据库连接。如果服务器不能创建这个连接数,连接池的创建就会失败。
在开发期间,为了使服务器启动更快,可以很方便的设置 InitialCapacity 属性的值小一点。在产品系统中,就应该把 InitialCapacity 的值设为与 MaxCapacity 值相同,默认产品模式的值为 25 。这样,在服务器启动时,所有的连接就会被创建。如果你调整了 MaxCapacity 值后,一定要确信 InitialCapacity 值设置与 MaxCapacity 值相同。
如果 InitialCapacity 比 MaxCapacity 值少,当负荷增加时,服务器需要创建额外的数据库连接。当服务器处于低负荷时,所有的资源应该是尽快的完成请求,而不是创建新的数据库连接。
7 . 2 调整 JDBC 连接池的最大容量
JDBCConnectonPool 元素中的 MaxCapacity 属性设置连接池包含的最大的物理数据库连接数。不同的 JDBC 驱动程序和数据库服务器可能限制物理连接数。
默认的最大容量数与默认的线程数相等:开发模式为 15 ,产品模式为 25 。不过,在产品模式下,建议连接数与当前的客户会话( Session )数相等。在服务器端,连接池的容量与执行线程数是无关的,正在进行的用户会话比执行线程更多。
八、设置 Java 编译器
编译 JSP Servlet 的标准 Java 编译器是 javac 。你可以把 java 编译器设置为 si 或 jikes 代替 javac ,这样能极大的提高性能。下面讨论设置步骤及其要考虑的事项。
8 . 1 通过控制台改变编译器
1. 启动服务器,访问控制台。
2. 展开左边面板 Servers 节点。
3. 点击要配置的服务器实例的名称。
4. 选择配置( Configuration )―― > 常规( General ),在 Java Compiler 编辑框输入编译器的完全路径。如: c:/visualcafe31/bin/sj.exe
5. 点击高级选项( Advanced Option )―― >Show ,显示其他的属性。
6. 用添加( Append )把完全路径通过 Classpath 框输入到 JRE rt.jar 库。如: BEA_HOME /jdk141_02/jre/lib/rt.jar
7. 点击应用。
8. 重启服务器。
8 . 2 在 Weblogic.xml 文件中设置编译器
n 使用 compileCommand 参数指定 Java 编译器。
n 使用 procompile 参数配置 WebLogic ,在启动 WebLogic 时预编译 JSP 。
8 . 3 编译 EJB 容器类
使用 Weblogic.appc 的功能去编译 EJB2.0 和 1.1 容器类。如果编译 Jar 文件部署 EJB 容器,你必须使用 weblogic.appc 生成容器类。默认情况下, EJB 使用 javac 编译器。为了得到跟好的性能,使用- compiler 标志指定不同的编译器(如 Symantec 公司的 sj )
8 . 4 在 UNIX 环境下编译
在 UNIX 机器上编译 JSP 文件,如果收到下列错误消息:
failed : java.io.IOException:Not enough space
试试下列一些或所有的解决方法:
n 如果你只有 256MB 的内存,增加更大的内存。
n 提高文件描述文件的限制,如:
set rlim_fd_max=4096
set rlim_fd_cur=1024
n 启动 JVM 时,用- native 标志来使用自有的线程。
九、使用 WebLogic 集群提高性能
WebLogic 集群是指一组 WebLogic 实例在一起提供具有防过载和自有复制的功能,以用一个域为所有客户支持可伸缩的高可用性运行。集群对于客户是一个单一的服务器,但实际上是一组服务器来提高可靠性和可伸缩性。
9 . 1 可伸缩性和高的可用性
可伸缩性是系统增加一个或更多部件作为系统资源的能力。很典型的是,这些部件使并发用户得到支持,使并发事务能在特定的时间单位能被处理。
假定应用程序设计良好,它完全可以简单的增加更多的资源来提高性能。为了增加 WebLogic 处理的负荷量,只需增加一个 WebLogic 实例到你的集群――不需改变应用程序。集群提高两个关键的好处:可伸缩性和可用性,这是单一服务器无法比拟的。
WebLogic 集群给 J2EE 带来了可伸缩性和高的可用性,而且对于应用程序的开发者是透明的。可伸缩性扩展了中间层的能力,超过了单一的 WebLogic 服务器或单一的计算机能处理的。集群成员唯一的限制是所有 WebLogic 必须要用 IP 多点传送通信。新的 WebLogic 能动态的增加到集群,以增加处理能力。
WebLogic 集群保证高的可用性是通过多个服务器的冗余,减少客户的请求失败。集群中多个服务器能提供同一服务。如果一个服务器停止运行,另一个能接替运行。这种功能为客户增加了可用性。
警告:如果你要解决应用程序和环境的颈瓶问题,增加额外的服务器到集群,应该提供线性的可伸缩性。定基准和初始配置测试运行时,在移到集群环境之前,应把应用隔离在单独的服务器上测试。
9 . 2 在多 CPU 机器上运行多服务器实例,应考虑的性能问题
多处理器的机器上,必须考虑群集 WebLogic 实例数应与 CPU 的数量成比例。因为 WebLogic 没有内置限制的服务器实例数位于集群里,规模大的、多处理器服务器,如 Sun 公司的 Sun Enterprise 10000 ,有着当作非常大的集群或多集群主机的潜能。
在决定最佳的服务器与 CPU 比例前,彻底测试你的应用程序并确定如下:
n 网络要求 如果你发现 Web 应用程序是主要受网络 I/O 限制,在增加 CPU 数前,考虑测试网络的吞吐量。如果实际是网络 I/O 限制,安装一个更快的网络接口卡( NIC )可以提供性能,而不是增加额外的 CPU ,因为在等着读 socket 时,更多的 CPU 会处于闲置。
n 磁盘 I/O 要求 如果你发现 Web 应用程序主要受磁盘 I/O 限制。在配置额外的 CPU 前,就应该考虑增加磁盘转速或单个磁盘。
总之,在配置额外的 CPU 前,必须确定 Web 应用程序是受 CUP 限制,而不是受网络或磁盘 I/O 限制。
对于受 CPU 限制的应用,最初在每个 CPU 上对一个 WebLogic 实例进行性能测试。如果 CPU 利用率是一致的或者接近 100 %,然后增加 CPU 比重(例如,为一个 WebLogic 实例配置两个 CUP ),记住在产品模式下,应该有一些空闲的 CPU 周期存在去执行管理任务。
虽然 Web 应用程序的处理需求变化多端,但 BEA 公司发现 WebLogic 实例与 CPU 最理想的比例是 1 : 2 。
十、监视 WebLogic 域
监视 WebLogic 域的健康状况和性能的工具是管理控制台。通过控制台,你可以观察到 WebLogic 资源的状态和统计信息,如服务器, HTTP , JTA 子系统, JNDI, 安全, CORBA 连接池, EJB , JDBC 以及 JMS 。
举个例子,在 Server ―― >Monitoring ―― >Performance 为当前服务器实例提供了与等待和运行状态的请求有关的性能参考。它包括下列信息:
n 队列中空闲线程数。
n 队列中等待时间最长的请求。
n 吞吐量,根据已经处理的请求数来衡量的。
n 队列长度,根据队列中等待请求数来衡量的。
n JVM 堆还有的内存量。