随笔 - 14, 文章 - 0, 评论 - 15, 引用 - 0
数据加载中……

2005年3月8日

收藏一篇java中的正则表达式

     摘要: JAVA与正则表达式(一年级) [ 作者: | 转贴自:CSDN 文档| 点击数: 1840] §1黑暗岁月        有一个String,如何查询其中是否有y和f字符?最黑暗的办法就是: 程序1:我知道if、for语句和charAt()啊。 class Test{   publ...  阅读全文

posted @ 2005-06-28 11:27 Boris-Java 阅读(1622) | 评论 (1)编辑 收藏

虽然目前不是很懂,但是值得关注的一些东西

jProbe
jProbe是由Quest公司开发的一个强大的java性能分析,调优工具,实际上,jProbe的功能还不止在性能方面,jProbe由以下几个产品组成:
JProbe Memory Debugger-检查Java软件的内存使用情况。可以统计出当前运行的java代码那些对象在消耗内存,消耗了多少等等。
JProbe Profiler-剖析Java软件的性能。可以统计出当前运行的java程序共运行了那些方法,每个方法使用了多少次,每次的平均时间以及累积时间等,还能绘制出方法间相互调用的示意图,并以不同的颜色表达耗时的区别。
JProbe Threadalyzer-识别线程级的死锁和错误的访问冲突
JProbe Coverage-通过提供的语句级执行信息验证测试框架的完整性。可以统计出在一段时间内,共运行了那些方法,这些方法的代码覆盖率有多少,并可以在源文件中标示出那些代码被运行了,哪些没有。

网址:http://www.quest.com/jprobe/

Tapestry
Tapestry是一个新一代的webapp开发框架。主页:http://jakarta.apache.org/tapestry/index.html
是一种抛弃了jsp的应用框架

HiveMind
HiveMind是一个代码构架框架,基本的思想也是ioc,越看越像spring,不过应该应用在不同的场合吧,学习中。主页:http://jakarta.apache.org/hivemind

Commons下的组件:
Commons下很多组件都很有用,也许你会发现辛辛苦苦写了半天的东西在这里面就有了!比如DBCP,BeanUtils,Mail和FileUpload等等。

地址:http://jakarta.apache.org/commons
Components 
Attributes Attributes provides a runtime API to metadata attributes such as doclet tags, inspired by the Nanning and XRAI projects as well as JSR 175 and C# attrbutes. 
BeanUtils Commons-BeanUtils provides easy-to-use wrappers around the Java reflection and introspection APIs.
Betwixt Betwixt provides services for mapping JavaBeans to XML documents, and vice versa.
Chain Chain provides a "Chain of Responsibility" pattern implemention for organizing complex processing flows. 
CLI CLI provides a simple API for working with Comamnd Line arguments, options, option groups, mandatory options and so forth. 
Codec Codec contains some general encoding/decoding algorithms. Includes some phonetic encoders, Hex, Base64, and a URL encoder. 
Collections Commons-Collections provides a suite of classes that extend or augment the Java Collections Framework. 
Configuration Commons-Configuration Tools to assist in the reading of configuration/preferences files in various formats. 
Daemon An alternative invocation mechanism for unix-daemon-like java code. 
DBCP Commons-DBCP provides database connection pooling services. 
DbUtils DbUtils is a JDBC helper library that factors out mundane resource cleanup code for common database tasks. 
Digester Commons-Digester is an XML-to-Java-object mapping utility commonly used for parsing XML configuration files. 
Discovery Commons-Discovery provides tools for locating resources (including classes) by mapping service/reference names to resource names using a variety of schemes. 
EL Commons-EL provides an interpreter for the Expression Language which is defined by the JavaServer Pages(TM) specification, version 2.0. 
Email Email provides a simple library for sending e-mail from Java. 
FileUpload FileUpload makes it easy to add robust, high-performance, file upload capability to your servlets and web applications. 
HttpClient Commons-HttpClient provides a framework for working with the client-side of the HTTP protocol. 
IO IO is a collection of I/O utilities. 
Jelly Jelly is an XML based scripting and processing engine. Jelly borrows many good ideas from both JSP custom tags, Velocity, Cocoon and the scripting engine inside XDoclet. Jelly can be used from the command line, inside Ant or inside a Servlet.
Jexl Jexl is an expression language which entends the Expression Language of the JSTL by bringing in some of the lessons leaned by the Velocity community. 
JXPath Commons-JXPath provides utilities for manipulating Java classes that conform to the JavaBeans naming conventions using the XPath syntax. It also supports maps, DOM and other object models. 
Lang Commons-Lang provides a very common set of utility classes that provide extra functionality for classes in java.lang. 
Latka Commons-Latka is an HTTP functional testing suite for automated QA, acceptance and regression testing. 
Launcher The Launcher Component is designed to be a cross platform Java application launcher. Commons-launcher eliminates the need for a batch or shell script to launch a Java class. The original Java classes come from the Jakarta Tomcat 4.0 project. 
Logging Commons-Logging is a wrapper around a variety of logging API implementations. 
Math Math is a library of lightweight, self-contained mathematics and statistics components addressing the most common practical problems not immediately available in the Java programming language. 
Modeler Commons-Modeler provides mechanisms to create Model MBeans compatible with the Java Management Extensions (JMX) specification. 
Net Net is a a collection of network utilities, based on the NetComponents codebase, including FTP clients etc. 
Pool Commons-Pool provides a generic object pooling interface, a toolkit for creating modular object pools and several general purpose pool implementations. 
Primitives Commons-Primitives provides smaller, faster and easier to work with types supporting Java primitive types. Currently Primitives is primarily focused on collections of primitives. 
Resources Resources provides a lightweight framework for defining and looking up internationalized message strings keyed by a java.util.Locale and a message key. 
Transaction Commons Transaction provides implementations for multi level locks, transactional collections and transactional file access and some other utility classes commonly used in transacional Java programming. 
Validator The commons-validator package provides a simple, extendable framework to define validators (validation methods) and validation rules in an xml file. There is support for internationalization of validation rules and error messages. 
VFS VFS is a Virtual File System component for treating files, FTP, SMB, ZIP and such like as a single logical file system.

The Sandbox
This project also contains a workspace that is open to all Jakarta committers. It's a place to try out new ideas and prepare for inclusion into the Commons portion of the project or into another Jakarta project. Users are free to experiment with the components developed in the sandbox, but sandbox components will not necessarily be maintained, particularly in their current state.
Sandbox 


Cache Cache provides object caching services. 
Clazz Clazz focuses on introspection and class manipulation. 
Compress Commons Compress defines an API for working with tar, zip and bzip2 files. 
Contract This component makes all the nice features available to the java programming language that come along with contract based programming. 
Convert Commons-Convert aims to provide a single library dedicated to the task of converting an object of one type to another. 
Events Commons-Events provides additional classes for firing and handling events. It focusses on the Java Collections Framework, providing decorators to other collections that fire events. 
Feedparser Generic FeedParser interface and concrete implementations for Atom, FOAF, OPML and RSS. 
Functor A functor is a function that can be manipulated as an object, or an object representing a single, generic function. 
I18n This component adds the feature of localized message bundles that consist of one or many localized texts that belong together. Think of an error message that consists of title, text, summary and error details. 
Id Id is a component used to generate identifiers. 
Javaflow Continuation implementation to capture the state of the application. 
JCI Java Compiler Interface 
JJar Jakarta JAR Archive Repository 
Mapper Mapper is a thin abstraction layer around a project's chosen data mapping technology (a.k.a. DAO pattern). 
Messenger Messenger is an easy to use and lightweight framework for working with JMS in the web tier. 
Pipeline This component provides a set of pipeline utilities designed around work queues that run in parallel to sequentially process data objects data objects. 
Scaffold Scaffold is a toolkit for building web applications. 
SQL Commons SQL is a component for working with databases and generating DDL. It contains a simple set of beans that represent a relational database schema such as a Database, Table, Column etc. 
ThreadPool ThreadPool is a simple component for asynchronously dispatching work to another thread in a pool for simple multi threaded programming. 

Workflow Workflow provides a framework for building workflow management systems. 

XMLIO Simple and fast importer for XML configuration or import files. 

posted @ 2005-06-17 17:02 Boris-Java 阅读(1342) | 评论 (1)编辑 收藏

linux下weblogic81集群配置实例

     摘要: Linux 下 Weblogic 集群配置 域,集群,管理服务器和被管服务器之间的关系        Weblogic 域是一个服务器 / 集群的管理组,用户可以通过某个中央位置来管理、监控整个服务器域,这个中心就是管理服务器,相对的,受控服务器或者叫被管服务器是指域中除...  阅读全文

posted @ 2005-06-16 10:32 Boris-Java 阅读(4058) | 评论 (7)编辑 收藏

weblogic培训笔记(三)java虚拟机配置

     摘要: u       JRockit是BEA公司开发的Intel平台之上的高性能以及高可管理性的jvm产品,在Intel平台上使用JRockit无疑会大大的提高效率。使用向导建立server的配置的时候,可以选择JRockit作为该server的虚拟机,另外,也可以在域的startWebLogic.cmd或者startWebLogic.sh脚本...  阅读全文

posted @ 2005-06-10 16:41 Boris-Java 阅读(3691) | 评论 (0)编辑 收藏

BEA WebLogic JRockit的使用和性能调优(收藏)

一.JRockit调优简介
JRockit是一个自适应的JVM,它能够自动调整自己去适应底层硬件,因此对它的调优主要集中在一些需要人工干预的参数上,比如说:需要划分多少RAM给JRockit使用等。JRockit有一组非标准的-X启动选项,我们可以用它来调节JVM。JRockit有两组主要的子系统可以被优化--内存管理系统(包括垃圾回收)和线程系统。在内存管理子系统方面,有很多调优的工作可以做。


二.Tuning WebLogic JRockit JVM
1.设置初始堆尺寸
可以通过-Xms:<size>m来设置初始堆大小,如果-Xmx的值小于128MB,则-Xms缺省取值为16MB;如果-Xmx设置大于128MB,则-Xms缺省值为物理内存的25%,最大不超过64M。例子:
-Xgc:gencon -xms:64m -Xmx:64m myClass
2.设置最大堆尺寸
可以通过-Xmx:<size>m来设置最大堆尺寸。在IA32构架下,由于操作系统给每个进程的最大内存寻址空间为1.8G,因此最大堆尺寸不能超过1.8G。在IA64构架下,就没有1.8G的限制。
如果你的JAVA应用程序在运行时出现了Out of memory的错误,你就需要调大最大堆尺寸。如果没有设置最大堆尺寸,则缺省值为:
1. 如果设置了-Xgc:gencopy,由最大堆尺寸是min{400, 物理内存*75%};
2. 如果没有设置-Xgc:gencopy,由最大堆尺寸是min{1536, 物理内存*75%};
最好手工把最大堆尺寸设置为物理内存(1024M)的75%:
-Xgc:gencon -xms:64m -Xmx:768m myClass
3.设置Nursery的尺寸
可以使用-Xns:<size>来设置Nursery的尺寸,我们要在保证垃圾回收停顿时间(garbage collection-pause)尽可能短的同时,尽量加大Nursery的尺寸,这在创建了大量的临时对象时尤其重要。缺省值为:
1. 对于-Xgc:gencopy,缺省的Nursery大小为320KB/CPU,对于10个CPU的系统来说,Nursery大小为3200KB(3.2M)
2. 对于-Xgc:gencon,缺省的Nursery大小为10M/CPU,对于10个CPU的系统来说,Nursery大小为100M
4.定义内存空间的清理时机
可以使用-Xcleartype:<gc|local|alloc>来定义已经被垃圾回收的内存空间在什么时候可以被清理,支持以下三种方式:
1. gc,在垃圾回收的同时清理内存;
2. local,在分配了一块thread-local区域时清理内存,仅在把参数-Xallocationtype设置成local时才有用;
3. alloc,在这块内存被分配给其它对象时清理。在IA64上目前还不支持。
缺省值为:
1. IA32上缺省值为alloc
2. IA64上缺省值为gc
5.定义线程分配的类型
可以使用-Xallocationtype:<global|local>来定义线程分配的类型。
1. global,在最大堆尺寸比较小时(小于128M)或者应用程序大量使用了线程时使用。
2. local,在最大堆尺寸比较大时(大于128M)或者应用程序少量使用了线程时使用。
缺省值:
1. 如果设置了-Xgc:gencopy,缺省值为global
2. 如果设置了-Xgc:siglecon,-Xgc:gencon和-Xgc:parallel,缺省值为local
6.定义线程栈尺寸
可以使用-Xss<size>[k|K][m|M]来定义线程栈大小。最小线程尺寸定义如下:
1. thin threads:最小线程栈尺寸为8K,缺省为64K;
2. native threads:最小线程栈尺寸为16K
如果-Xss设置小于最小值,则自动使用最小值。
缺省值:
1. IA32系统,WIN32:64K,LINUX32:128K
2. IA64系统,WIN64:320K,LINUX64:1M

二.Basic Tuning Tips and Techniques
尽管JRockit提供了一组缺省的OOTB配置选项,但最好根据实际应用情况来对JRockit作一些调整。
1.决定你要在哪方面调优
要考虑的因素有:
1. 要为JRockit分配多少内存空间;
2. 你要调优的目的是什么,是要得到更好的响应性还是更好的性能;
2.设置堆尺寸
对于堆尺寸来说,当然是越大越好了。如果设得不够大,就会造成Out-of-memory和内存分页错。如果同时运行了多个应用程序,建议把最小和最大堆尺寸设置成一样大。
3.在高响应性方面的调优
要得到更好的响应性能,应该设置
1. 使用并发垃圾回收器。-Xgc:gencon
2. 设置初始和最大堆大小。-Xms512m,-Xmx768m,由于使用了并发垃圾回收器,所以堆大小不会造成长时间的等待。
3. 设置nursery尺寸。如果用到了大量的临时对象,则需要适当的调大nursery尺寸。调大nursery尺寸会导致垃圾回收的停顿时间加长,因此要注意,确保垃圾回收的停顿时间在可忍受的范围内,这个停顿时间可以通过设置-Xgcpause来查看。
4.在高性能方面的调优
如果要得到更好的性能,你应该:
1. 选用并行垃圾回收器,由于并行垃圾回收器不使用nursery,因此你不必再设置-Xns,方法是加上-Xgc:parallel
2. 把初始和最大堆尺寸设置调到尽可能的大。方法是-Xms512m, -Xmx768m。
5.分析垃圾回收和停顿时间
1. 使用-Xgcreport生成报表,显示垃圾回收的统计信息,从中可以看出你是不是最有效地使用了垃圾回收器。
2. 使用-Xverbose:memory来显示在运行期间每一次垃圾回收的停顿时间。本选项仅用于调试,会产生大量的控制台输出。
6.调整线程选项
当大量地使用了线程时(超过100个),需要调整线程选项:
1. 使用thin线程选项。-Xthinthreads。瘦线程模式在LINUX下非常有效。注意:瘦线程在JRockit中只是一个试验选项,不推荐广泛使用;
2. 关闭本地分配线程的选项。-Xallocationtype:global。每个本地线程区都要消耗大约2K的内存,如果大量地使用了线程,本地线程不但会造成内存空间浪费,而且还会造成堆碎片。使用全局线程机制会减少堆碎片,但在内存分配方面速度要慢一些。
7.分析并改善应用程序设计
找出瓶颈方法:
1. 使用Intel VTune工具;
2. 使用-Xjvmpi:allocs=off,monitors=off,entryexit=off选项。

三.Command Line Options by Name
启动JRockit时,可以带一些-X选项,这些选项是非JVM标准的,专门用于配置JRockit的性能。
选项
描述

-X

显示扩展Java选项

-Xallotype

-Xallocationtype

可取值global和local,定义使用本地线程还是全局线程。

-Xbootclasspath

指定类搜索路径,可以是ZIP和JAR文件,以;或:分隔

-Xcleartype

定义内存清理时机,可取值gc, local, alloc。gc表示在垃圾回收时清理内存;local表示时分配一块local线程区时清理;alloc表示内存区要被分配给其它对象时清理

-Xgc

选择要使用的垃圾回收器的类型,可取值:

gencopy:generational copying

singlecon:single spaced concurrent,单空间并发

gencon:generational concurrent

parallel:parallel

如果-Xmx小于128M,缺省使用gencopy,否则使用gencon

-Xgcpause

打印由垃圾回收器造成的停顿时间

-Xgcreport

打印垃圾回收报表

-Xjvmpi

是否允许JVMPI事件,这些事件有:

entryexit(缺省ON)

allocs(缺省ON)

monitors(缺省ON)

arenasdelete(缺省OFF)

-Xmanagement

激活JVM中的管理服务器,在JVM的管理控制台能连接到它之前,必须先激活。

-Xms

设置初始堆大小,单位有K、M、G

-Xmx

设置最大堆大小,单位有K、M、G

-Xnativethreads

使用本地线程系统,这是缺省选项

-Xnoclassgc

禁止对类作垃圾回收

-Xnohup

告诉JRockit,忽略CTRL_LOGOFF_EVENT和SIGHUP事件

-Xns

设置nursery尺寸,单位有K、M、G

-Xss

设置线程栈尺寸,单位有K、M、G

-Xthinthreads

使用JRockit的高性能线程系统,在IA64上不可用。

-Xverbose

让JRockit打印更多的信息,可选的参数有:

codegen、cpuinfo、gc、load、memory、Opt

-Xverify

作完整的bytecode一级的校验

四.用JRockit8.1中的Method Profiler调优WebLogic
1.关于Method Profiler工具
BEA WebLogic JRockit 8.1提供了一个Profiling工具:Method Profiler来调优WebLogic应用。
2.利用Method Profiler调优WebLogic应用
JRockit 8.1所带的Method Profiler工具能够将所有在JRockit Java虚拟机上执行的成员方法的调用次数、执行的总时间和每次调用的执行时间都统计出来,如图1所示。这样的功能一来可以让我们对跑在WebLogic上的应用进行tuning(代码级的),二来也大大方便了我们确定系统瓶颈在何处。这也可以说是JRockit JVM相对于其他JVM在功能上的一大优势。

在一次对WebLogic Server 8.1的压力测试中,对一组包含了CMP特性的样本进行压力测试时,就利用JRockit的Method Profiler诊断出了系统的瓶颈所在,现介绍如下。CMP这组样本中原先对CMP Entity Bean的操作除了用ejbCreate插入一条记录之外,紧跟着用setName方法设置其name属性,即UPDATE其对应数据库记录中name域的值,代码如下:
public void ejbCreate() //Stateful4CMPBean中的方法
throws CreateException
{
try
{
Context ctx = new InitialContext();
SheepHome home = (SheepHome)ctx.lookup("Sheep");
Sheep sheep = null;
int x = getNextId(); // getNextId()也包含对数据库的操作
sheep = home.create(x);
if(sheep != null)
{
sheep.setName("sheep1".concat(String.valueOf(String.valueOf(x))));
m_strMsg = "create sheep".concat(String.valueOf(String.valueOf(x)));
} else
{
m_strMsg = "The sheep name is not created.";
}
}
catch(Exception e)
{
m_strMsg =
"*** some exception occured! (CMP) ".concat(String.valueOf(String.valueOf(e.getMessage())));
}
}
此时测出来的数据,TPS平均值非常低,且测试时Response Time总是随着时间的增长几乎呈线性攀升。于是用Method Profiler进行诊断:
(1) 在JRockit的启动参数中加入-Xmanagement,以便启动JRockit的时候同时启动其Management Server。
(2) 启动JRockit Management Console,并且将其连接到启动了的Management Server上。(在做压力测试时用JRockit Management Console进行观察对性能的损耗可以忽略不计)
(3) 在JRockit Management Console中,将ToolsàPreferences菜单中的Mode of operation属性设为developer。
(4) 在Method Profiler属性页中添加你所需要观察的类的成员方法。
(5) 按Start按钮让Method Profiler开始进行统计。
Time/Inv(ns)指标的显示结果表明Stateful4CMPBean.ejbCreate()代码所含逻辑成为了系统的瓶颈。结果又显示getNextId()和home.create()操作消耗的时间只占Stateful4CMPBean.ejbCreate()的一小部分,而sheep.setName()操作消耗的时间却占了Stateful4CMPBean.ejbCreate()的剩下的(指除去getNextId()和home.create()操作消耗的时间)绝大部分。
于是又用Method Profiler作了一系列实验,结果如下:用1个用户做压力测试,sheep.setName()操作消耗的时间为X,getNextId()操作消耗的时间为Y,home.create()操作消耗的时间为Z;用2个用户做压力测试,sheep.setName()操作消耗的时间约为2X,getNextId()操作消耗的时间约为Y,home.create()操作消耗的时间约为Z;用3个用户做压力测试,sheep.setName()操作消耗的时间约为3X,getNextId()操作消耗的时间约为Y,home.create()操作消耗的时间约为Z。可以比较肯定地判断,sheep.setName()执行的是一个串行化的逻辑。检查Oralce中UPDATE的ISOLATION-LEVEL,果然为SERIALIZABLE。
将sheep.setName("sheep1".concat(String.valueOf(String.valueOf(x)))); 这句代码删掉。
重新测试,TPS平均值有很大幅度的提高,Response Time在压力测试开始一段时间后也趋于平稳,几乎呈水平线走势。

posted @ 2005-06-10 16:38 Boris-Java 阅读(1783) | 评论 (0)编辑 收藏

weblogic培训笔记(二)web应用程序的相关配置

1、单线程模式servlet

默认情况下,一个servlet实例将会产生多个线程来同时响应多个请求。

如果某个servlet实现SingleThreadMod旗标接口,那么这个servlet将会自动拒绝多路并行请求的模式。在这种情况下,weblogic会产生一个servlet实例池来满足单线程的要求。

目前,应该尽量避免使用单线程模式的servlet,如果需要在大容量的系统中使用单线程模式的servlet,那么应该调整如下的参数:

Single Threaded Servlet Pool Size 这个参数可在weblogic.xml或者在weblogic控制台上webapplication菜单---configuration---Descriptor  子页中进行设置。

默认为5

2、Weblogic生产模式下会自动监测servletjsp的更改情况,在产品模式下,不需要这些检查,可以通过下面的参数更改:

JSPPage Check SecsServlet Reload Check Secs均设为-1这两项是weblogic检查jspservlet的时间间隔。设置为-1weblogic将不再检查。

关闭JSPKeep GeneratedJSPVerbose,产品模式下也不需要这两个选项。

Enable JSP Line Numbers 这个选项是启用jsp行号的选项,启用行号的目的是用来支持调试,有些IDE可以在jsp生成的java源代码中设置断点用于调试。生产模式中也不需要。

注意:在产品发布模式下,请禁止对servlet和jsp的变更检查,这样除了能提高效率以外,还可以防止用上传文件的方式对服务器的攻击。如果需要更改servlet和jsp,可以重新部署应用。

3、Sessioncookie的相关配置

概念会话cookie:如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的 cookie被称为会话cookie

Session Cookie Max Age Secs 就是会话cookie的超时时间,设置小于0表示不限制。

Session Invalidation Interval Secs 检查过期session的周期

Session Timeout Secs session的超时时间

4、Jdbc连接池的配置

URL 连接池地址

Driver Classname jdbc驱动类名

Properties :属性,例如user=examples

Password :密码

Initial Capacity :初始连接数

Maximum Capacity :最大连接数

Capacity Increment :连接池每次增加连接的数量

 

Statement Cache Type prepared statements缓存的策略,LRU算法在有新的语句到来时,将最不经常被用得语句调整出缓存。FIXED算法为先进先出的算法

Statement Cache Size :缓存中语句的最大数量,调整这个数值的大小,有利于提高系统的效率。

posted @ 2005-06-10 13:21 Boris-Java 阅读(2349) | 评论 (0)编辑 收藏

weblogic培训笔记(一)weblogic Server内部结构和相关的配置

weblogic Server内部结构图:

r_3333.jpg
(一) 
原理简单说明

服务器启动,就会绑定到相应的端口,并为一个端口分配一个线程以接受连接请求,一旦服务器接受到连接请求并建立好连接以后,监听线程将处理权交给套接字复用器,套接字复用器进行一定的处理,并会负责选择利用那个执行队列并将请求置入其中。当有一个请求进入执行队列,就会有一个空闲的执行县城从该队列里面取走并向调用者返回结果。

(二)  执行队列和执行线程的相关配置

执行线程数量有一定的限制,在服务器启动的时候,就已经形成了一个含有一定数量执行线程的池,执行线程可能跨servletejbjdbc等,由于执行线程仅当程序成功结束或者出现异常才能被释放继续处理其他请求,所以如果执行线程执行的不够快,而请求又多的情况下,就会造成执行队列的阻塞。

相关的配置信息有:

server菜单configuration---〉高级配置---Config Execute Queues中的配置项如下:

1、Queue Length队列长度,执行队列的长度

2、Queue Length Threshold Percent 一个百分数,当request的数量达到队列长度的这个比例的时候,weblogic会发出overflow的标志信息。

3、Thread Count 服务器初始创建的执行线程的数量

4、Thread Increase 如果weblogic发出overflow的标志信息,weblogic会尝试增加这个数量的执行线程,以解决处理矛盾。

5、Threads Maximum最大执行线程数

6、Threads Minimum最小执行线程数

7、Thread Priority线程优先级

另外server菜单configuration---tuning子页中还有一些相关的配置:

1、  Stuck Thread Max Time 黏联线程时间,超过这个时间没有返回的执行线程,系统将认为是黏联线程。

2、  Stuck Thread Timer Interval 系统检查黏联线程的时间间隔

如果weblogic认为某个队列中的所有的线程全部黏联的话,weblogic将会增加执行线程的数量。

注意:执行线程的数量一旦增加,目前weblogic不会去减少他,如果增加了一些线程以后再次出现overflow的警告,weblogic会继续增加执行线程的数量,一直到达到上限为止。

(三)  套接字复用器的相关配置

Weblogic带有两个版本的套接字复用器,纯java版和本地接口版(jni),一般来说在访问量小的情况下,java版比jni版性能要好一些,因为jniAPI调用会损失一部分性能,但是访问量大的情况,一般都是jni版的性能比较好,所以尽量保证weblogic实用本地接口版的套接字复用器

相关的配置参数有两个,在server菜单configuration---tuning子页中的第一个和第二个配置项。

Enable Native IO :启用本地IO,勾选这个配置以后,weblogic就会启用本地接口版的套接字复用器

Socket Readers :如果不选上一个选项,则这个选项可用,也就是说java版的套接字复用器会被启用,并且,java版的复用器会从执行线程中抽出这个比例的线程用于处理socket的请求。(java客户端访问有关?

 

posted @ 2005-06-10 13:15 Boris-Java 阅读(3368) | 评论 (3)编辑 收藏

BEA WebLogic平台下J2EE调优攻略(收藏)

作者:zhouhg (dev2dev ID)
摘要:

  随着近来J2EE软件广泛地应用于各行各业,系统调优也越来越引起软件开发者和应用服务器提供商的重视。而对于最终客户来说,在一个高效、稳定地实现他们的业务需求已经是他们的基本要求。所以J2EE调优显得非常重要,而BEA WebLogic Server是业界领先的应用服务器,BEA WebLogic平台下的J2EE调优也就尤为重要,她将为我们提供普遍的J2EE调优方案。最近网络、杂志上的J2EE调优文章层出不穷。本人也将自己平时工作中的一些经验积累分享给大家,抛砖引玉。


目录

前 言
第一章 应用程序调优
1.1.1 通用代码调优
1.1.2 减小没有必要的操作
1.1.3 使用合适的类型
1.1.4 尽量使用pool,buffer和cache
1.2 JDBC代码调优
1.2.1 严格资源使用
1.2.2 实用技巧
1.2.3 优化SQL语句
1.3 Web代码调优
1.3.1 HttpSession的使用
1.3.2 JSP代码调优
1.3.3 Servlet代码调优
1.4 JMS代码调优
1.4.1 注意必要的事项,避免使用不必要的特征
1.4.2 消息类型的选择
1.4.3 确认方式的选择和JMS事务
1.5 EJB代码调优
1.5.1 有效使用设计模式
1.5.2 使用EJB和WebLogic的特性
1.5.3 缓存资源
1.5.4 如何选择和使用Entity Bean
1.5.5 其他的一些小技巧
第二章 应用服务器调优
2.1 JVM调优
2.1.1 垃圾收集和堆大小
2.1.2 jRockit调优
2.2 Server调优
2.2.1 尽量使用本地I/O库
2.2.2 调整默认执行线程数
2.2.3 调整连接参数
2.2.4 创建新的执行队列
2.3 JDBC调优
2.3.1 调整连接池配置
2.4 WEB调优
2.4.1 调整WEB应用描述符
2.5 JMS调优
2.6 EJB调优
2.6.1 调整pool和cache
2.6.2 优化事务隔离级别和事务属性
2.6.3 其他一些小技巧
第三章 数据库调优
3.1.1 Oracle性能优化
3.1.2 Oracle的其他调整
第四章 操作系统调优
4.1 操作系统调整
4.1.1 HP-UX
4.1.2 Solaris
4.1.3 AIX
4.1.4 Linux
4.1.5 Windows
第五章 性能监控和性能分析
5.1 性能瓶颈
5.2 操作系统监控
5.3 数据库监控
5.4 WebLogic监控
5.4.1 JVM监控
5.4.2 Console监控
5.4.3 实用工具分析
5.5 应用程序分析
总结
参考文献
关于作者

前 言 (目录)

  随着近来J2EE软件广泛地应用于各行各业,系统调优也越来越引起软件开发者和应用服务器提供商的重视。而对于最终客户来说,在一个高效、稳定地实现他们的业务需求已经是他们的基本要求。所以J2EE调优显得非常重要,而BEA WebLogic Server是业界领先的应用服务器,BEA WebLogic平台下的J2EE调优也就尤为重要,她将为我们提供普遍的J2EE调优方案。最近网络、杂志上的J2EE调优文章层出不穷。本人也将自己平时工作中的一些经验积累分享给大家,抛砖引玉。

  本文从J2EE应用架构(下图)来分别剖析系统调优,首先我们一般会从应用程序出发,去审核代码,做到代码级的优化,然后再调整应用服务器(BEA WebLogic8.1)和数据库 (Oracle9i)的参数,最后当然是调整操作系统和网络的性能(包括硬件升级)。诚然,在我遇到的很多项目中,都是出现了性能问题后才想到调优,而且一般都是先进行系统参数调整,实在解决不了才会对代码进行检查.实际上,我们应当将代码级的调优放在应用设计时来做,测试生产时修改代码将是一件极其痛苦的事情。


WebLogic平台J2EE应用架构


第一章 应用程序调(目录)
1.1.1 通用代码调优

1.1.2 减小没有必要的操作
  对象的创建是个很昂贵的工作,所以我们应当尽量减少对象的创建,在需要的时候声明它,初 始化它,不要重复初始化一个对象,尽量能做到再使用,而用完后置null有利于垃圾收集。让类实现Cloneable接口,同时采用工厂模式,将减少类的创建,每次都是通过clone()方法来获得对象。另外使用接口也能减少类的创建。对于成员变量的初始化也应尽量避免, 特别是在一个类派生另一个类时。

  异常抛出对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为, fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。 异常只能用于错误处理,不应该用来控制程序流程。

  此外, 建议关闭Debug输出,尽量少用串行化、同步操作和耗时昂贵的服务(如Date())。

1.1.3 使用合适的类型

  当原始类型不能满足我们要求时,使用复杂类型。String和StringBuffer的区别自不必说了,是我们使用最多的类型,在涉及到字符运算时,强烈建议使用StringBuffer。在做String匹配时使用intern()代替equal()。

  带有final修饰符的类是不可派生的, 如果指定一个类为final,则该类所有的方法都是final。

  Java编译器会寻找机会内联所有的final方法,这将能够使性能平均提高50%。类的属性和方式使用final或者static修饰符也是有好处的。

  调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。所以尽量使用局部变量。

  ArrayList和Vector,HashMap和Hashtable是我们经常用到的类,前者不支持同步,后者支持同步,前者性能更好,大多数情况下选择前者。

1.1.4 尽量使用pool,buffer和cache
  使用pool、buffer和cache能大大提高系统的性能,这在J2EE的大部分技术中都是适用的。

  在WebLogic中就大量使用了池:JDBC Connection Pool、Socket Pool、Object Pool和Thread Pool。I/O操作中,buffer是必须的,特别是对大文件的操作,不然容易造成内存溢出。字节操作最快,所以尽可能采用write(byte[]),Buffered FileOutputStream比Buffered FileWriter要快,因为FileWriter需要Unicode到Byte的转换。

  而后面讲到的JDBC、JSP、EJB和JMS我们都非常建议使用buffer和cache。为HttpServletResponse设置buffersize,使用wl-cache,缓存在JNDI树上获取的对象等等。

  此外,使用JDK 1.4的非阻塞I/O对性能也有很大提高。

1.2 JDBC代码调优
1.2.1 严格资源使用
  JDBC代码调优最大的原则就是使用WebLogic的连接池,而不是自己直连数据库。在我接触的很多自己实现连接池的项目中,大部分遇到死锁和连接泄漏的问题,最后得不得修改代码。而WebLogic提供了功能强大,性能良好的数据库连接池,我们要做的只是封装一个连接管理类,从JNDI树上获取数据源并缓存,得到连接,并提供一系列关闭数据库资源的方法。

  对任何资源使用的原则是用完即关,不管是数据库资源、上下文环境,还是文件。数据库资源的泄漏极易造成内存泄漏,乃至系统崩溃。在使用完数据库资源后依次关闭ResultSet,Statement和Connection,而在一个数据库连接多次进行数据库操作时要特别注意ResultSet和Statement依次关闭。

try{
  //open connection
  pstmt =conn.prepareStatement(strSql1);
  pstmt.executeUpdate();
  pstmt.close();
  pstmt =conn.prepareStatement(strSql2);
  rs=pstmt.executeQuery();
  while (rs.next()){
  //process
 }
rs.close();
pstmt.close();
 }catch(Exception e){
  //close rs,psmt,con
}finally{
  //close rs,psmt,con
}

1.2.2 实用技巧
  在JDBC操作中还有一些小的技巧跟大家分享:由于获取连接时默认自动提交方式,使用connection.setAutoCommit(false)关闭自动提交,使用PreparedStatement,批量更新,业务复杂或者大数据量操作时使用存储过程,尽量使用RowSet,此外设置记录集读取缓存FetchSize和设置记录集读取方向FetchDirection对性能也有一定的提高。

1.2.3 优化SQL语句
  SQL语句的优化牵涉到很多数据库的知识,需要与索引配合,因此需要DBA对代码中的SQL进行检查测试。常见的,select *不提倡使用,效率极差,建议显式获取列,即使是所有字段也应罗列,而取总数时使用count(*),为提高cache的命中率,尽量做到SQL重用。对于大数据量的查询,可以充分利用Oracle数据库的特性,每次取出m-n行的数据,实现分页查询。另外,提高性能的好选择可能就是把所有的字符数据都保存为Unicode,Java以Unicode形式处理所有数据,因此,数据库驱动程序不必再执行转换过程。

1.3 Web代码调优
1.3.1 HttpSession的使用
  应用服务器保存很多会话时,容易造成内存不足,所以尽量减少session的使用,放置session
里的对象不应该是大对象,最好是简单小对象,实现串行化接口。当会话不再需要时,应当及时调用invalidate()方法清除会话。而当某个变量不需要时,及时调用removeAttribute()方法清除变量。请勿将EJB对象放置在session中。

1.3.2 JSP代码调优
  目前,在JSP页面中引入外部资源的方法主要有两种:include指令,以及include动作。 include指令:例如<%@ include file="copyright.html" %>,该指令在编译时引入指定的资源。在编译之前,带有include指令的页面和指定的资源被合并成一个文件。被引用的外部资源在编译时就确定,比运行时才确定资源更高效。
include动作:例如<jsp:include page="copyright.jsp" />。该动作引入指定页面执行后生成的结果。由于它在运行时完成,因此对输出结果的控制更加灵活。但是,只有当被引用的内容频繁地改变时,或者在对主页面的请求没有出现之前,被引用的页面无法确定时,使用include动作才合算。

  对于那些无需跟踪会话状态的jsp,关闭自动创建的会话可以节省一些资源。使用如下page指令: <%@ page session="false"%> ;尽量不要将JSP页面定义为单线程,应设置为<%@page isThreadSafe=”true”%>;在JSP页面最好使用输出缓存功能,如: <%@page buffer="32kb"%>;尽量用wl:cache定制标记来缓存静态或相对静态的内容,缓存jsp:include操作的结果能显著提高应用程序的运行性能。

1.3.3 Servlet代码调优
  Servlet代码调优比较简单:在Servlet之间跳转时,forward比sendRedirect更有效;设置HttpServletResponse 缓冲区,如:response.setBufferSize(20000);在init()方法里缓存静态数据,而在destroy()中释放它;建议在Servlet里使用ServletOutputStream输出图片等对象;避免在Servlet和Jsp中定界事务等。

1.4 JMS代码调优
1.4.1 注意必要的事项,避免使用不必要的特征
  JMS提供了强有力的消息处理机制,但是为了最大限度的提高JMS系统的性能,应避免使用不需要使用的特征,同时也要注意必要的事项。比如:尽量使用接收程序能直接使用的最简单、最小的消息类型;消息选择器要尽可能简单(最好不使用),尽量不要使用复杂的操作符,如like、in或者between等,使用字符串数据类型的速度最慢;务必为特定的应用程序定义特定的JMS连接工厂,并且禁用默认的JMS连接工厂;不要在javax.*与weblogic.*的名字空间中使用JNDI名称;尽量使用异步消费者,线程不必封锁以等待消息的到达;使用完JNDI树上的资源后注意关闭。

1.4.2 消息类型的选择
  标准JMS提供了五种消息类型,而TextMessage应用最为普遍, 当发送的消息是几种原始数据类型的集合体时,最好使用MapMessage消息类型,而不要使用ObjectMessage,以便减少不同系统间的耦合。此外消息是否使用压缩要慎重考虑,压缩未必能减少消息大小。如果生产者、消费者和目的地并置在同一WebLogic Server内部,通常不使用压缩。WebLogic特有的XMLMessage能为运行于消息主体之上的消息选择器提供内嵌式支持,而且易于数据交换。因此,建议应用程序之间传送消息使用XML消息格式,而应用程序内部间传送消息使用二进制消息格式。

1.4.3 确认方式的选择和JMS事务
  使用事务性会话时,尽量使用恰当的消息确认方式:如果需求允许,使用NO_ACKKNOWLEDGE;非持久的订阅者使用DUPS_OK_ACKNOWLEDGE或者MULTICAST_NO_ACKNOWLEDGE。而使用JTA的UserTransaction,确认方式将被忽略。在使用JMS事务时,无效的消息会导致事务的回滚,以致消息重发这样的死循环。此时,可以将无效消息发送到错误消息队列,并提交JMS事务,这将确保消息不会再次传递。

1.5 EJB代码调优
1.5.1 有效使用设计模式
  GoF 的《设计模式》为我们实现高性能、易扩展的J2EE应用提供理论保障和技术支持。而EJB作为J2EE的核心组件和技术,善用设计模式对系统性能影响很大。Service Locator 和Value Object 已为我们所熟悉,Floyd Marinescu的《EJB Design Patterns》中的Session Fa?ade、Message Fa?ade、EJB Command和Data Transfer Object等设计模式更是为我们提供设计典范:缓存对EJBHome的访问;使用门面模式,不暴露Entity Bean,用Session Bean封装Entity Bean;如果可以异步处理,则用MDB代替Session Bean;封装业务逻辑在轻量级JavaBean中;使用值对象等简单对象传递数据;不直接使用get/set方法操作Entity Bean。当然过度使用模式或者牵强套用模式也是不提倡的,总的原则就是减少网络流量,改进事务管理。

1.5.2 使用EJB和WebLogic的特性
  使用EJB和WebLogic的新特性往往能提高性能。与EJB2.0特性相关的技巧有:一个Application中使用本地接口,对于Entity Bean肯定使用本地接口,避免远程调用的开销;使用CMP管理关系,而不是BMP,EJB2.0中CMP的性能大大改善,性能和移植性都优于BMP;使用ejbSelect进行内部查询;使用home方法进行外部查询和批处理; 数据库驱动级联删除等。

  与WebLogic特性相关的技巧有:使用自动生成主键,WebLogic为Oracle和Sqlserver两种数据库的CMP提供了自动生成主键功能,节约了Entity Bean产生主键的时间,同时设key-cache-size不小于100;WebLogic管理事务性能更好,使用容器管理,而不是Bean管理事务;WebLogic提供了为CMP动态查询和批量插入功能,对性能也有很大帮助。

1.5.3 缓存资源
  对SLSB或者MDB来说,使用setMesssageDrivenContext()或者ejbCreate()方法缓存特定资源,在ejbRemove()方法里释放; 对SLSB或者MDB来说,使用setSessionContext()或者ejbCreate()方法缓存特定资源,在ejbRemove()方法里释放;对Entity Bean来说,使用setEntityContext ()方法缓存特定资源,在unSetEntityContext ()方法里释放。

1.5.4 如何选择和使用Entity Bean
  1. 在设计EJB时,要适当考虑EJB的粒度, 细粒度的EJB在事务管理和资源管理的开销太大,尽量创建粗粒度的 EJB , 不要太粗,粗到能满足实际需求就可以;

  2. Entity Bean不是唯一方式,如果只有一个很小的数据子集被经常改变,建议采用JDO;

  3. 在操作大数据量的时候,直接采用JDBC比Entity Bean更有效;

  4. 避免采用返回很大数据组的finder方法,如 FindAll() 方法,因为它的实现代价太大;

  5. 考虑设置域组field groups,减少没有必要并昂贵的属性加载,如BLOB;

  6. 对于EJB1.1或者BMP,可以设置is-modified-method-name属性,根据isModified()的值来判断是否调用ejbStore()等方法,减少没有必要运算;

  7. 避免连接多个表创建BMP,可以使用视图,存储过程或者O/R Mapping等方式。

1.5.5 其他的一些小技巧
  1. 考虑使用 javax.ejb.SessionSynchronization 接口,提供在Rollback之后恢复数据的方法: afterBegin(), beforeCompletion(), afterCompletion();
  2. 使用完SFSB之后,调用remove()方法释放实例;
  3. 假如你不需要EJB服务的时候,建议使用普通Java类;
  4. 避免EJB之间相互调用;
  5. 使用多读模式。

第二章 应用服务器调优(目录)
2.1 JVM调优
2.1.1 垃圾收集和堆大小

  垃圾收集(GC)是指JVM释放Java堆中不再使用的对象所占用的内存的过程,而Java堆(Heap)是指Java应用程序对象生存的空间。堆大小决定了GC的频度和时间。堆越大,GC频度低,速度慢。堆越小,GC频度高,速度快。所以GC和堆大小是一组矛盾。为了获取理想的Heap堆大小,需要使用-verbosegc参数(Sun jdk: -Xloggc:<file>)以打开详细的GC输出。分析GC的频度和时间,结合应用最大负载所需内存情况,得出堆的大小。
通常情况下,我们建议使用可用内存(除操作系统和其他应用程序占用之外的内存)70-80%,为避免堆大小调整引起的开销,设置内存堆的最小值等于最大值即:-Xms=-Xmx。而为了防止内存溢出,建议在生产环境堆大小至少为256M(Platform至少512M),实际环境中512M~1G左右性能最佳,2G以上是不可取的,在调整内存时可能需要调整核心参数进程的允许最大内存数。对于sun和hp的jvm,永久域太小(默认4M)也可能造成内存溢出,应增加参-XX:MaxPermSize=128m。建议设置临时域-Xmn的大小为-Xmx的1/4~1/3, SurvivorRatio为8。

  为了获得更好的性能,建议在启动文件设置WebLogic为产品模式,此时sun和hp jvm JIT引擎为-server,默认情况下打开JIT编译模式对性能也有帮助。调整Chunk Size和Chunk Pool Size也可能对系统的吞吐量有提高。此外还需关闭显示GC: -XX:+DisableExplicitGC。

  当然在Intel平台上使用jRockit(使用参数-jrockit)无疑大大提高WebLogic性能。

2.1.2 jRockit调优
  jRockit支持四种垃圾收集器:分代复制收集器、单空间并发收集器、分代并发收集器和并行收集器。默认状态下,JRockit使用分代并发收集器。要改变收集器,可使用-Xgc:<gc-name>,对应四个收集器分其他为gencopy, singlecom, gencon以及parallel。为得到更好的响应性能,应该使用并发垃圾回收器:-Xgc:gencon,可使用-Xms和-Xmx设置堆栈的初始大小和最大值,要设置护理域-Xns为-Xmx的10%。而如果要得到更好的性能,应该选用并行垃圾回收器:-Xgc: parallel,由于并行垃圾回收器不使用nursery,不必设置-Xns。

  如果你的线程大于100或者在linux平台下,可以尝试使用瘦线程模式:-Xthinthread,同时关闭Native IO:-Xallocationtype:global。

  jRockit 还提供了强大的图形化监控工具Jrockit Management Console。欲详细了解JRockit可访问:http://edocs.bea.com/wljrockit/docs81/index.html


2.2 Server调优
  WebLogic Server的核心组件由监听线程,套接字复用器和可执行线程的执行队列组成。当服务器由监听线程接收到连接请求后,将对它的连接控制权交给等待接收请求的套接字复用器。然后套接字复用器读取离开套接字的请求,并将此请求及相关安全信息或事务处理环境一起置入适当的执行队列中(一般为默认的执行队列)。 当有一个请求出现在执行队列中时,就会有一个空闲的执行线程从该队列中取走发来的该请求,并返回应答,然后等待下一次请求。因此要提高WebLogic的性能,就必须从调整核心组件性能出发。

2.2.1 尽量使用本地I/O库
WebLogic Server有两套套接字复用器:Java版和本地库。采用小型本地库更有效,尽量激活Enable Native IO(默认),此时UNIX默认使用CPUs+1个线程,Window下为双倍CPU。如果系统不能加载本地库,将会抛出java.lang.UnsatisfiedLinkException,此时只能使用Java套接字复用器,可以调整socket readers 百分比,默认为33%。该参数可以在Console Server Tuning Configuration配置栏里设置。

2.2.2 调整默认执行线程数
  理想的默认执行线程数是由多方面的因素决定的,比如机器CPU性能、总线体系架构、I/O、操作系统的进程调度机制、JVM的线程调度机制。WebLogic生产环境下默认的线程为25个,随着CPU个数的增加,WebLogic可以近乎线性地提高线程数。线程数越多,花费在线程切换的时间也就越多,线程数越小,CPU可能无法得到充分利用。为获取一个理想的线程数,需要经过反复的测试。在测试中,可以以25*CPUs为基准进行调整。当空闲线程较少,CPU利用率比较低时,可以适当增加线程数的大小(每五个递增)。对于PC Server 和Window 2000,则最好每个CPU小于50个线程, 以CPU利用率为90%左右为佳。由于目前WebLogic执行线程没有缩小线程数的功能,所以应将参数Threads Increase设置为0,同时不应改变优先级的大小。

2.2.3 调整连接参数
  WebLogic Server用Accept Backlog参数规定服务器向操作系统请求的队列大小,默认值为50。当系统重载负荷时,这个值可能过小,日志中报Connection Refused,导致有效连接请求遭到拒绝,此时可以提高Accept Backlog 25%直到连接拒绝错误消失。对于Portal类型的应用,默认值往往是不够的。Login Timeout和SSL Login Timeout参数表示普通连接和SSL连接的超时时间,如果客户连接被服务器中断或者SSL容量大,可以尝试增加该值。这些参数可以在Console Server Tuning Configration配置栏里找到。

2.2.4 创建新的执行队列
  创建新的执行队列有助于解决核心业务优先、避免交叉阻塞、死锁和长时间处理的业务等问题。通常会将自己的执行队列和默认的执行队列设置不同的优先级,这里优先级不应设为9或者10。 定义一个新的执行队列很容易,利用View Excute Queue选项中的Configure a new Excute Queue链接即可定制新的执行队列。创建新的执行队列后,用户需要为应用程序的J2EE组件配置分配策略,以便它可以找到新的队列。举个例子:要将servlet或jsp捆绑到一个特定的执行队列,必须替换web.xml文件项,将wl-dispatch-policy初始化参数设置为自己的执行队列名。

<servlet>
<servlet-name>servletname</servlet-name>
<jsp-file>/directoryname/deployment.jsp</jsp-file>
<init-param>
<param-name>wl-dispatch-policy</param-name>
<param-value>NewExecuteQueueName</param-value>
</init-param>
</servlet>

  我们可以为一个jsp或者servlet乃至一个WEB应用设置自己的执行队列。同时也可以为EJB设置自己的执行队列。对于执行时间比较长的MDB,建议使用自己的执行队列。

2.3 JDBC调优
2.3.1 调整连接池配置

  JDBC Connection Pool的调优受制于WebLogic Server线程数的设置和数据库进程数,游标的大小。通常我们在一个线程中使用一个连接,所以连接数并不是越多越好,为避免两边的资源消耗,建议设置连接池的最大值等于或者略小于线程数。同时为了减少新建连接的开销,将最小值和最大值设为一致。

  增加Statement Cache Size对于大量使用PreparedStatement对象的应用程序很有帮助,WebLogic能够为每一个连接缓存这些对象,此值默认为10。在保证数据库游标大小足够的前提下,可以根据需要提高Statement Cache Size。比如当你设置连接数为25,Cache Size为10时,数据库可能需要打开25*10=250个游标。不幸的是,当遇到与PreparedStatement Cache有关的应用程序错误时,你需要将Cache Size设置为0。

  尽管JDBC Connection Pool提供了很多高级参数,在开发模式下比较有用,但大部分在生产环境下不需调整。这里建议最好不要设置测试表, 同时Test Reserved Connections和Test Released Connections也无需勾上。 当然如果你的数据库不稳定,时断时续,你就可能需要上述的参数打开。

  最后提一下驱动程序类型的选择,以Oracle为例,Oracle提供thin驱动和oci驱动,从性能上来讲,oci驱动强于thin驱动,特别是大数据量的操作。但在简单的数据库操作中,性能相差不大,随着thin驱动的不断改进,这一弱势将得到弥补。而thin驱动的移植性明显强于oci驱动。所以在通常情况下建议使用thin驱动。而最新驱动器由于WebLogic server/bin目录下的类包可能不是最新的,请以Oracle网站为准: http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc9201.html

2.4 WEB调优
2.4.1 调整WEB应用描述符

  WEB应用除代码之外的调优比较简单,仅仅是对一些WEB应用描述符的调整。首先关闭Session Monitoring Enabled,仅仅在Cluster环境下设置Session复制(优先使用内存复制),在保证应用正常运行的情况下,设置较短的Session超时时间。 同时生产环境下无需检查Jsp和servlet:JSPPage Check Secs和Servlet Reload Check Secs均设为-1,关闭JSPKeep Generated 和JSPVerbose对性能也有帮助。此外,还可以对jsp进行预编译,有两种方法:激活precompile选项;使用weblogic.appc事先编译,建议采用后者。

2.5 JMS调优
  1. 增加-Dweblogic.JMSThreadPoolSize=n(至少为5),以提高处理JMS的线程数,在jRockit上增加-XXenablefatspin以减少加锁冲突;
  2. 采用文件存储策略,将同步写策略设置为Direct-Write,同时在windows平台上启用磁盘写入缓存;
  3. 使用分布式目的地时,激活连接工厂Load Balancing Enabled ,Server Affinity Enabled;
  4. 为减少服务器不必要的JMS请求路由,如果多个目的地之间存在事务,则部署在同一JMS服务器上,尽量将连接工厂部署到JMS服务器所在的WebLogic实例上,集群环境下,则最好将连接工厂部署到集群中的所有服务器上,而集群中每个JMS服务器和目的地成员尽量使用类似的设置;
  5. 启用消息分页存储功能,以释放内存,可以为JMS服务器和目的地设置, 激活Messages Paging Enabled和Bytes Paging Enabled,同时使用限额防止服务器耗尽接收消息的所有可用内存空间;
  6. 在运行WebLogic Server进程之外的生产者务必使用流控制, 并增大Send Timeout;
  7. 将JMS Server Expiration Scan Interval设很大的值,能禁止主动扫描过期消息;
  8. 使用FIFO或者LIFO方式处理目的地消息;
  9. MDB的max-beans-in-free-pool不应大于最大MDB线程数(默认线程数/2+1)。

2.6 EJB调优
2.6.1 调整pool和cache

  initial-beans-in-free-pool定义SLSB启动时实例的个数,默认为0,可以调大到正常并发数的大小,以减少初始响应时间。max-beans-in-free-pool为最大个数,默认1000对SLSB来说,在频繁创建和删除实例的情况下很有帮助,一般不用调整,至少设为默认线程数,过大容易造成内存溢出。而对Entity Bean来说,由于是匿名的,所以当频繁使用finder、home和create方法时可以调大。

  对SFSB来说,尽量将max-beans-in-cache参数设置得足够的大,以满足Bean实例对最大并发用户数的要求,可以避免有状态会话Bean过多的钝化行为。而idle-timeout-seconds尽量设置小,如果SFSB不用于存储Web应用会话状态可以设置为0。

  对于Entity Bean来说, max-beans-in-cache同样可以首先采用默认值1000,监控实例缓存和钝化的情况,再做适当调整。

  并行策略concurrency-strategy定义了实体Bean如何管理锁,有四种策略: Exclusive、Databse、ReadOnly、Optimistic。效率依次提高,可靠性依次降低,尽量避免使用互斥策略,如果Bean无需更新操作,使用只读策略,更甚的是,如果Bean的内容不会改变,可设置read-timeout-seconds为0,乐观并行策略时采用事务间缓存策略,在entity-cache描述符中将cache-between-transactions元素设为true。

2.6.2 优化事务隔离级别和事务属性
  对EJB组件来说,有四种事务隔离水平:

  • TRANSACTION-SERIALIZABLE:在处理完成之前拒绝其他处理的读入、可扩展性或插入数据操作;
  • TRANSACTION-REPEATABLE-READ:防止处理修改正在被其他处理调用的数据;
  • TRANSACTOIN-READ-COMMITTED:防止对正在被其他处理修改的数据执行写锁定;
  • TRANSACTION-READ-UNCOMMITTED:允许处理读入未受权的数据以及允许在向结果中添加记录时可以忽略处理。

   以上隔离水平依次降低,效率和性能依次提高。因此,建议选用满足在业务数据完整性要求前提下水平最低的隔离级别。

  对于事务属性的设置也是如此,对于删除、修改和插入操作设置为Required,而对于只读操作设置为Supports或者NotSupports。

2.6.3 其他一些小技巧
  1. 利用finders-load-bean的默认值true,既可以避免“n+1”的查询问题,又可以提高系统的性能;
  2. 使用delay-updates-until-end-of-tx参数的默认值true,除非应用程序对某些变化有特别的要求;
  3. 应用程序在每个业务方法调用后不需要进行存在性检查,将check-exists-on-method设定为false,以提高程序的性能;
  4. 同一应用内, 将enable-call-by-reference设置为 true;
  5. reentrant设置为false,避免事先加载子数据。

第三章 数据库调优(目录)
3.1.1 Oracle性能优化

  Oracle9i的性能优化除了调整kernal之外就是主要对Oracle启动文件的调整,即调整SGA的参数。注意,不同操作系统不同位数的机器最优的参数不是一样的,这里主要有windows和unix之分,32位和64位之分。
首先需要调大进程数和游标数,一般默认的值对实际应用来说都比较小,比如说,进程数可以调到300,游标数可以调到500。

  其次,看一个经验公式: OS 使用内存+ SGA + session*(sort_area_size + hash_area_size +2M)<0.7RAM,通常认为此时的SGA比较合理。这里sort_area_size为64k, hash_area_size为128k(当排序多的时候需要增大sort_area_size,按调整后的值计算),session表示最大并发进程数,假设100个。假如1G内存的机器,OS占用200M,PGA占用200M左右,那么SGA可以设为400-500M,如果2G内存可以1G给SGA,8G可以5G给SGA。不过对于32位数据库来说,通常最多只能使用1.7G内存。

  然后,SGA内参数设置的基本原则是:data buffer 通常可以尽可能的大,shared_pool_size 要适度,log_buffer 通常大到几百K到1M就差不多。具体的:data buffer 1G内存可以设置500M,2G设为1.2G,8G可设为5G 。shared_pool_size不易过大,通常应该控制在200M--300M,如果使用了大量的存储过程,可以根据SGA的值增大到500M,如果增大后命中率得不到提高,则增加是无益的。具体的:1G内存可以设置100M,2G设为150M,8G可设为300M。如不使用Java,java_pool_size 10-20M即可。large_pool_size如果不设置MTS,在20M -30M 即可,假如设置 MTS,可以考虑为 session * (sort_area_size + 2M)。

  最后,关于内存的设置可根据statspack信息和v$system_event,v$sysstat,v$sesstat,v$latch 等view信息来考虑微调。

3.1.2 Oracle的其他调整
  为了Oracle高效率的运行,除了上面提到的内存因素之外,还有就是需要良好的数据库设计:表、视图、索引和日志的合理规划和建立。I/O的性能也是重要因素,应尽量减少页交换和页分配。此外,就是改善检查点的效率。

第四章 操作系统调优(目录)
4.1 操作系统调整

  操作系统影响应用程序运行性能的因素主要有:硬件的配置(CPU、内存、硬盘等),核心参数,TCP/IP参数以及补丁的情况等。这里对操作系统的优化,除了更新最新的补丁程序以保证应用程序正常运行之外,就是调整TCP/IP参数,文件描述符,对于个别操作系统还有其他特别的参数调整。下面将依次介绍不同操作系统的情况,更多的信息请参考各操作系统的文档。

4.1.1 HP-UX
  对于HP-UX,你首先需要安装Java Patch:
http://www.hp.com/products1/unix/java/patches/index.html,然后需要确认下面文档中的核心参数是否满足(可以使用sam命令修改核心参数):http://e-docs.bea.com/platform/suppconfigs/configs81/hpux11_risc/81sp3.html#80105

  调整TCP参数: ndd -set /dev/tcp tcp_conn_req_max 1024, 将侦听队列的最大允许长度调整到1024。 有时操作系统限制进程使用的最大内存数小于你要配置的内存大小,则需要调整该值。

  读者可以从http://docs.hp.com/hpux/onlinedocs/TKP-90203/TKP-90203.html了解更多的HP-UX调整建议。

4.1.2 Solaris
  调整TCP的参数,等待时间间隔tcp-time-wait-interval建议设置为60000ms: /usr/sbin/ndd ?set /dev/tcp tcp_time_wait_interval 60000;
其他参数调整如下:

tcp_xmit_hiwat/tcp_recv_hiwat 131072
tcp_conn_req_max_q/tcp_conn_req_max_q0 16384

  调整一个进程打开的文件描述符的数量:软限制和硬限制以及散列表的大小,修改/etc/system文件:

set tcp:tcp_conn_hash_size=32768
set rlim_fd_cur=8192
set rlim_fd_max=8192

更多的调整信息请查阅: http://docs.sun.com/db/doc/806-7009(Solaris9)。

4.1.3 AIX
  AIX用no命令调整TCP参数,等待时间间隔tcp_timewait: no -o tcp_timewait=4,将tcp.timewait参数设置为4个15秒间隔,即1分钟。运行no -a命令将显示网络当前的所有属性值。由于UDP_SENDSPACE默认的缓存大小是8k,为减少I/O异常,需调整为32k:

  no -o udp_sendspace=32768。此外, 当WebLogic HTTP请求忙时,可以调整侦听队列的最大长somaxconn到8192(默认值是1024)。

  更多信息:http://publib16.boulder.ibmo.com/pseries/en-us/aixbman/prftungd/prftungd.htm

4.1.4 Linux
  调整Linux系统使用sysctl命令修改TCP参数等待时间间隔:sysctl -w ip_ct_tcp_timeout_time_wait=60;调整打开文件的最大数:在/etc/sysctl.conf文件中,添加: Fs.file-max=65535,然后运行sysctl -p;调整打开文件描述符最大数为8192:在/etc/security/limits.conf文件,添加:WebLogic hard nofile 8192(仅针对WebLogic用户),然后在WebLogic启动文件里运行ulimit-n 8192激活设置。

更多信息请查阅:http://ipsysctl-tutorial.frozentux.net/ipsysctl-tutorial.html

4.1.5 Windows
  Windows系统的调整通过修改注册表HKEY-LOCAL-MACHINESYSTEMCurrent ControlSetServices文件夹来完成。可以调整TcpipParameters子文件夹中的等待时间间隔时间TcpTimedWaitDelay参数的值。侦听队列最大长度的默认值为15,为修改它,可在InetinfoParameters子目录中创建DWORD条目ListenBackLog。
此外,Windows2000的Service Pack(要求sp3以上)也会影响系统稳定性: http://e-docs.bea.com/platform/suppconfigs/configs81/win2ksvr_as_data_pentium/81sp3.html

第五章 性能监控和性能分析(目录)
5.1 性能瓶颈
  最后,介绍一下实际分析J2EE应用性能的常用命令和工具。对于实现一个高性能的J2EE应用来说,掌握了J2EE调优的理论经验还是不够的。掌握性能监控,发现瓶颈和问题诊断才是保证J2EE系统持续高效运行的关键。
瓶颈指的是限值所有吞吐操作以及严重影响反应时间的系统内资源。在分布式系统内寻找并纠正瓶颈是非常困难的,需要有经验的团队来解决。瓶颈会发生在Web服务器上,程序代码中,应用服务器上,数据库,操作系统或者网络,硬件上。经验表明,瓶颈很容易发生在如下地方:数据库连接与队列中;应用服务器的程序代码中;应用服务器和Web服务器硬件上;网络和TCP配置中。实际中可以着力对这些环节进行监控。

5.2 操作系统监控
  操作系统层面的性能监控主要是对内存、CPU、I/O和交换区的使用情况进行监控分析。windows平台可以通过任务管理器和perfmon工具查看。如果是unix系统可以使用stat系列命令(vmstat, mpstat, iostat)监控内存、CPU和I/O的即时变化,使用swap命令查看交换区的使用情况。如果操作系统安装了top、topas、glance等使用工具,则使用top、topas、glance将能更为方便地看到WebLogic进程对操作系统的内存,CPU和I/O资源使用的即时变化情况。

  而网络方面的性能可以通过ping和netstat等命令来监控,主要几个关键的网络统计值,如数据包再发送、重复数据包和数据包侦听丢失。

  说明:本文提到的unix命令并非适用所有操作系统,仅供参考。

5.3 数据库监控
  数据库层面的监控这里为oracle9i为例来说明,可以采用oracle自带的工具Oracle
Interprise Manager Console来监控session和sql的执行情况。还有其他专业的数据库监控工具可以使用,比如QUEST的spotlight(http://www.quest.com/spotlight-portal/)可以非常形象和直观地对Oracle数据库的CPU、内存、I/O、Data Buffer Size、Shared Pool Size、Redo Buffer等参数进行即时监控,并自动对不正常的参数以红色显示。

5.4 WebLogic监控
5.4.1 JVM监控

  采用java参数-verbose:gc 来分析JVM的GC非常繁琐,而且不直观。使用-Xloggc:gc.log 参数将GC日志写入文件,采用GC 工具HPjtune (http://www.javaperformancetuning.com/tools/hpjtune/index.shtml)进行分析,可以轻松看出当前jvm参数配置是否合理。

  严格意义上来说HPjtune是一个分析工具,不是监控工具。这里不得不提及jRocket,Intel平台上最快的JVM, 在WebLogic启动命令中增加-Xmanagement参数,就可以执行beajrockit81sp3_142_04in下console命令监控WebLogic的内存使用和CPU负载情况。设置Tools/Preferences菜单中的Mode of operation属性为developer, jRocket将提供Method Profiler工具,她能够将所有在JRockit Java虚拟机上执行的成员方法的调用次数、执行的总时间和每次调用的执行时间都统计出来,进行代码级调优,这是jRockit的又一大优势。


5.4.2 Console监控
  WebLogic Console除了管理配置功能之外,提供了丰富的监控功能。通过WebLogic Console,首先我们可以查看服务器的运行情况。

5.4.2.1 Server监控
  通过使用服务器的Performance Monitoring选项卡,可以查看到请求吞吐量,执行队列积压情况以及JVM栈利用情况。而通过点击Performance Genaral选项卡中” Monitor all Active Queues...”可以查看所以执行线程的当前统计数据。此外Monitoring选项卡还可以监控JTA和JMS等Service的情况。


5.4.2.2 JDBC监控
  在连接池Monitoring选项卡中,WebLogic Console为每一个数据库连接池提供了实时统计信息。其中有三个重要参数可以反应WebLogic Server的健康状况:Connections High、Wait Second High和Waiters High。Connection High表示从服务器启动开始后到达池的最大连接数量,如果大于池的最大数量,则需要调整Maxium Capacity。Waiters High表示在没有可用连接的情况下,应用程序等待连接的最大个数。我们可以根据Waiters High的大小调整连接池容量。更多的参数可以通过Customize this view链接添加,参数含义参考:http://e-docs.bea.com/wls/docs81/ConsoleHelp/domain_jdbcconnectionpool_monitor.html#1104829

5.4.2.3 WEB监控
  Web Application Monitoring选项卡可以监控WEB应用的Session个数,以及Servlet的响应情况,激活Session Monitoring Enabled可以获取所有session的统计情况。更多信息请参考:
http://e-docs.bea.com/wls/docs81/ConsoleHelp/web_applications.html#1106723

5.4.2.4 JMS监控
  Welogic Console JMS监控功能比较多,不仅在Server JMS Monitoring选项卡可以监控Active JMS Connections, Pooled JMS Connections和Active JMS Servers的连接和使用情况。还可以监控JMS Session Pool、Active JMS Destinations和Durable Subscribers的消费和生产情况。比如,我们可以监控到JMS Queue的接收和消费消息的数量和字节数。有关JMS监控的详细情况可参见:http://edocs.bea.com/wls/docs81/ConsoleHelp/jms_monitor.html

5.4.2.5 EJB监控
  EJB监控包括对SLSB,SFSB,Entity Bean,MDB四种EJB的监控。本人认为EJB监控提供了非常丰富的运行时统计信息(http://e-docs.bea.com/wls/docs81/ConsoleHelp/ejb.html#1105036),非常有利于我们对EJB进行性能调优。

  SLSB选项卡为用户提供实例池的运行时统计信息。Pool Miss Ratio 表示实例池的Miss率,Pool Waiter Total Count 表示线程等待bean 实例的累计时间,Pool Timeout Total Count表示超时的线程数。当Pool Miss Ratio较大时,可以增加max-beans-free-pool。

  SFSB可以关注Cache Miss Ratio和Activation Count。Cache Miss Ratio过大时,调大max-bean-in-cache未必有帮助,需要尝试不用的max-bean-in-cache以获得最低的Cache Miss Ratio。激活将严重减慢应用程序的速度,如果某一个bean的Activation Count的值过高,那么需要考虑增加max-bean-in-cache的大小。
Entity Bean结合了SLSB的free pool和SFSB的cache。可以结合上面的策略进行监控。

  而MDB仅比SLSB多一个参数JMSConnection Alive,报告EJB是否成功连接到JMS目的地。

更多Console监控信息可参见http://edocs.bea.com/wls/docs81/ConsoleHelp/index.html

5.4.3 实用工具分析
  WebLogic除了提供Console进行应用监控之外,用户还可以编写JMX程序或者通过SNMP协议进行监控。而QUEST Spotlight for WebLogic Server提供了类似WebLogic Console类似的监控功能,并对异常情况显红。
这里不得不提到实战中经常用来分析性能瓶颈的工具THREAD DUMP,统一的命令是使用 weblogic.Admin 命令 THREAD_DUMP。而在 windows上还可以使用<Ctrl>+<Break> 来创建诊断问题所需的线程转储Thread Dump,而在unix上使用kill -3 <wlspid>命令。我们从中可以看到WebLogic后台线程的运行情况,通常需要每隔10秒左右持续执行几次以助诊断问题。更多信息可以参考BEA实战集锦。

5.5 应用程序分析
  应用程序分析除了凭借程序员丰富的经验和敏锐的洞察力去人工检查代码之外,使用厂家的工具也是节省时间的不错选择。目前市场上有Borland Optimizeit Enterprise Suite和QUEST Jprobe两个产品可以用来分析性能瓶颈,垃圾收集,内存泄漏,线程死锁和代码复盖等。Hpjmeter是一个免费的工具,也具有以上类似的性能分析功能。

  而Borland Optimizeit Server Trace,HP OpenView Transaction Analyzer和Mercury LoadRunner J2EE breakdown都可以用来分解J2EE应用从客户端访问到最终数据库操作每一层次花费的时间,甚至精确到每一个方法的执行时间。Server Trace还具有检查内存泄漏,连接泄漏和错误警告等功能,一般在测试环境中使用。而HP OTVA的优势在于运行时监控,LoadRunner优势在于压力测试。

总结(目录)
  J2EE调优是一门实践和经验科学,是一个复杂而往复的过程。其原则是:合理。合理,看似简单,细细品味,意味深长。本文所述的调优策略并不是一成不变的,只是为了给大家一个参考建议,让大家少走弯路,关键是根据实际环境调优。欢迎有兴趣的朋友在论坛上积极讨论和批评指正。

参考文献(目录)
[1]BEA WebLogic Server edocs: http://e-docs.bea.com/wls/docs81/perform/index.html
[2]Gregory Nyberg & Robert Patrick :Mastering BEA WebLogic Server
[3]Jack Shirasi:Java Performance Tuning

关于作者(目录)
周海根(dev2dev ID:zhouhg) 合力思软件(中国)有限公司技术顾问,BEA Certified Specialist,BEA dev2dev撰稿人。多年从事J2EE开发工作,目前致力于技术支持工作,主要研究J2EE技术在WebLogic上的应用、调优。有着西电人的务实,喜欢专研技术,是个体育狂热者。
联系方式: 010-85251858-1053,zhouhaigen@hotmail.com

posted @ 2005-06-10 13:09 Boris-Java 阅读(4361) | 评论 (1)编辑 收藏

java&xml第四天,sax

SAX(Simple API for XML用于XML的简单API)
由于提前学习了cocoon,时间上又经过了一个周末,想要写得激情没有剩下多少,这里简单的回顾一下SAX的一些接口定义和用处吧!-_-#
1、准备工作
      sax相关的类都封装在org.xml.sax中,其中接口org.xml.sax.XMLReader是SAX2的核心类,你的xml解析器应该提供这个接口的实现类。比如"org.apache.xerces.parsers.SAXParser"这个类。
2、sax的处理流程
      sax基本的处理方法是在解析之前注册各种处理类(Handler),在解析的时候callback这些处理器,内容处理器就是其中最主要的一个。举例来说明的话,如下的xml文档:
<?xml version="1.0"?>
  
<samples>
    
<server>UNIX</server>
    
<monitor>color</monitor>
  
</samples>
他将会在解析的时候被转化成如下的一串事件流:
    Start document
    Start element (samples)
    Characters (white space)
    Start element (server)
    Characters (UNIX)
    End element (server)
    Characters (white space)
    Start element (monitor)
    Characters (color)
    End element (monitor)
    Characters (white space)
    End element (samples)
开发者要做的就是捕获这些事件,然后做自己要做的事情。
3、内容处理类
      org.xml.sax.ContentHandler
package org.xml.sax;
public interface ContentHandler
{
    
public void setDocumentLocator (Locator locator);
    
public void startDocument ()throws SAXException;
    
public void endDocument()throws SAXException;
    
public void startPrefixMapping (String prefix, String uri) throws SAXException;
    
public void endPrefixMapping (String prefix)throws SAXException;
       public void startElement (String namespaceURI, String localName,String qName, Attributes atts)
       throws SAXException;
    
public void endElement (String namespaceURI, String localName,String qName)throws SAXException;
    
public void characters (char ch[], int start, int length)throws SAXException;
    
public void ignorableWhitespace (char ch[], int start, int length)throws SAXException;
    
public void processingInstruction (String target, String data)throws SAXException;
    
public void skippedEntity (String name)throws SAXException;
}
有一点要说明的就是ignorableWhitespace 这个方法是在遇到可以忽略的空白的时候回调的,但是如果xml文档没有定义DTD或者是Schema,那么这个方法将不会被调用,因为如果没有文档结构的定义,解析器又如何判断哪些空白是可以忽略的呢。
4、错误处理类
      ErrorHandler这个类提供两个方法,warning和error,用于在处理解析过程发生的错误和警告,包括xml格式的错误和文档结构检查的错误。
5、过滤器和写入器
      org.xml.sax.XMLFilter这个接口扩展了XMLReader接口,添加了两个新方法:
      public void setParent(XMLReader reader);
      public XMLReader getParent();
      他的意图比较明显,将一个已有的XMLReader作为上级解析器,他将得以在这个XMLReader执行捕获sax事件之前捕获他们,并作一些操作,最后在链向XMLReader的对象,这里的概念很像cocoon的内部实现。
      这里还要提到的一个类是:org.xml.sax.helpers.XMLFilterImpl这个类实现了XMLFilter接口,不仅如此,他还提供了ContentHandler,ErrorHandler等处理器的处理方法通道。也就是说,如果继承XMLFilterImpl并覆盖startElement方法,那么你写得代码将在实际的Reader执行startElement方法被执行之前被执行。下面是一个注册Filter的例子:
XMLReader reader = XMLReaderFactory.createXMLreader();
MyFilter filter 
= new MyFilter(reader.);
filter.setContenHandler();

注意在注册内容处理类等类的时候,应该写filter....
另外,你当然也可以再写一个filter2,而把filter作为parent传入,这样就构成了一个事件处理链。

      org.xml.sax.XMLWriter是一个实际的过滤器,他也是通过上面说到的方式:扩展XMLFilterImpl来实现的。具体的类除了XMLWriter外还有DataWriter,他扩展XMLWriter。
      需要注意的是这两个类一般不用来做实际的写入流操作,但是他们可以用于很好的表现sax处理链的中间结果,也就是快照snapshot
6、sax的属性和特征
      属性和特征在XMLReader接口里面体现为:
      getFeature(String),setFeature(String,boolean)方法和getProperty(String),setProperty(String,Object)方法,用来控制解析过程的一些选项,比如是否进行DTD校验。比如:
      reader.setFeature("http://xml.org/sax/features/validation", true);这样会在解析的时候校验DTD定义
reader.setFeature("http://apache.org/xml/features/validation/schema", true);这样会启动schema校验。

posted @ 2005-03-14 13:26 Boris-Java 阅读(914) | 评论 (0)编辑 收藏

java&XML学习第三天,cocoon2

     摘要:       由于对于cocoon 2的内容特别的感兴趣,所以跳过了对sax的学习就直接开始了cocoon 2的学习,事实证明这样是不对的,如果你只是想对cocoon 2作一个简单的了解,可以不学sax,但是如果想要深入了解cocoon 2的话,还是应该先学习sax。      首...  阅读全文

posted @ 2005-03-10 15:38 Boris-Java 阅读(2167) | 评论 (2)编辑 收藏

学习java&XML第二天,命名空间

      关于XML的基础知识一直都是读的http://www1.xml.net.cn/那本初学进阶,讲的非常容易懂,就是关于命名空间这一块没有给出一个比较好的例子,所以自己整理了一下。
      初学进阶里面说命名空间是用于在一个XML里面引入多个DTD的,的确,概念上是这样子的,不过网上的资料显示XML的命名空间并不支持DTD格式的格式定义,也就是说,想实现一个XML当中有多个文档格式的话,就必须要使用Schema。
      先了解一下我们要实现的例子:
      
client.xml
<联系人列表>
  
<联系人>
    
<姓名>张三</姓名>
    
<ID>001</ID>
    
<公司>A公司</公司>
    
<EMAIL>zhang@aaa.com</EMAIL>
    
<电话>(010)62345678</电话>
    
<地址>
      
<街道>五街1234号</街道>
      
<城市>北京市</城市>
      
<省份>北京</省份>
    
</地址>
    
<直接上司>
      
<姓名>王五</姓名>
      
<电话>
        
<秘书电话>(010)62345678</秘书电话>
        
<手机>13601234567</手机>
      
</电话>
    
</直接上司>
  
</联系人>
</联系人列表>

      以上是我们想要最终表达的数据格式,其中,联系人的直接上司属性有点麻烦,因为整个直接上司表达的是一个“企业经理”的“对象”,该“对象”可以以另外的XML形式体现,如下:

<?xml version="1.0" encoding="GB2312"?>
<企业经理>
  
<姓名>王五</姓名>
  
<电话>
    
<秘书电话>(010)62345678</秘书电话>
    
<手机>13601234567</手机>
  
</电话>
</企业经理>

      看以上的两个文档,实际上就是我们想表达的数据,两个抽象的实体“联系人”和“企业经理”之间存在着一对一的关系。
      但是我们现在有个麻烦,在联系人列表这个XML当中,有两个“姓名”元素和两个“电话”元素,他们表达的是不同的意思,其文档格式定义也不同。他们分别对应着不同的DTD或者是Schema。
      为了解决这一问题,就有了命名空间的概念,首先,对于我们要最终作用于其上的client.xml,他必须首先区别联系人和企业经理,做法就是在前面加前缀,比如联系人的名字改为“联系人:名字”而企业经理的名字则改为“企业经理:名字”
      其次,两个不同的文档定义文件必须首先定义好命名空间,在作用于XML文件的时候,使命名空间和XML声明中的命名空间一致
      下面分别给出例子代码:
      client.xml:
<?xml version="1.0" encoding="GB2312"?>
<联系人:联系人列表 
xmlns:联系人
="id" 
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation
="id client.xsd id2 manager.xsd"
xmlns:企业经理
="id2">
    
<联系人:联系人>
        
<联系人:姓名>张三</联系人:姓名>
        
<联系人:ID>001</联系人:ID>
        
<联系人:公司>A公司</联系人:公司>
        
<联系人:EMAIL>zhang@联系人.com</联系人:EMAIL>
        
<联系人:电话>(010)62345678</联系人:电话>
        
<联系人:地址>
            
<联系人:街道>五街1234号</联系人:街道>
            
<联系人:城市>北京市</联系人:城市>
            
<联系人:省份>北京</联系人:省份>
        
</联系人:地址>
        
<联系人:直接上司>
            
<企业经理:姓名>王五</企业经理:姓名>
            
<企业经理:电话>
              
<企业经理:秘书电话>(010)62345678</企业经理:秘书电话>
              
<企业经理:手机>13601234567</企业经理:手机>
            
</企业经理:电话>
        
</联系人:直接上司>
    
</联系人:联系人>
    
<联系人:联系人>
        
<联系人:姓名>李四</联系人:姓名>
        
<联系人:ID>002</联系人:ID>
        
<联系人:公司>B公司</联系人:公司>
        
<联系人:EMAIL>li@bbb.org</联系人:EMAIL>
        
<联系人:电话>(021)87654321</联系人:电话>
        
<联系人:地址>
            
<联系人:街道>南京路9876号</联系人:街道>
            
<联系人:城市>上海市</联系人:城市>
            
<联系人:省份>上海</联系人:省份>
        
</联系人:地址>
        
<联系人:直接上司>aa</联系人:直接上司>
    
</联系人:联系人>
</联系人:联系人列表>

      client.xsd:
<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<!--W3C Schema generated by XMLSpy v2005 sp1 U (http://www.xmlspy.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="id" targetNamespace="id" elementFormDefault="qualified">
    
<xs:element name="EMAIL" type="xs:string"/>
    
<xs:element name="ID" type="xs:string"/>
    
<xs:element name="公司" type="xs:string"/>
    
<xs:element name="地址">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="街道"/>
                
<xs:element ref="城市"/>
                
<xs:element ref="省份"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="城市" type="xs:string"/>
    
<xs:element name="姓名" type="xs:string"/>
    
<xs:element name="电话" type="xs:string"/>
    
<xs:element name="省份" type="xs:string"/>
    
<xs:element name="联系人">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="姓名"/>
                
<xs:element ref="ID"/>
                
<xs:element ref="公司"/>
                
<xs:element ref="EMAIL"/>
                
<xs:element ref="电话"/>
                
<xs:element ref="地址"/>
                
<xs:element ref="直接上司"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="联系人列表">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="联系人" maxOccurs="unbounded"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="街道" type="xs:string"/>
    
<xs:element name="直接上司" type="xs:anyType"/>
</xs:schema>

      manager.xsd:
<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<!--W3C Schema generated by XMLSpy v2005 sp1 U (http://www.xmlspy.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="id2" targetNamespace="id2" elementFormDefault="qualified">
    
<xs:element name="企业经理">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="姓名"/>
                
<xs:element ref="电话"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="姓名" type="xs:string"/>
    
<xs:element name="手机" type="xs:string"/>
    
<xs:element name="电话">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="秘书电话"/>
                
<xs:element ref="手机"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="秘书电话" type="xs:string"/>
</xs:schema>

说明:我在这里用id和id2来表示命名空间是应为很多人会认为那个命名空间的网址会在解析XML的时候被访问,我一开始也这样认为,所以改成id来做个测试。

posted @ 2005-03-08 17:32 Boris-Java 阅读(1014) | 评论 (0)编辑 收藏

学习java&XML第二天熟悉一下DTD

DTD(Document Type Definition)文件类型描述

第一点要注意的:DTD中的关键字必须全部大写!

一、DTD的位置
      
DTD可以放在xml文档里面:

出自《XML入门》
<?xml version = "1.0" encoding="GB2312" standalone = "yes"?>
<!DOCTYPE 联系人列表[
        <!ELEMENT 联系人列表 (联系人)*
>
        
<!ELEMENT 联系人 (姓名,ID,公司,EMAIL,电话,地址)>
        
<!ELEMENT 地址 (街道,城市,省份)>
        
<!ELEMENT 姓名 (#PCDATA)>
        
<!ELEMENT ID (#PCDATA)>
        
<!ELEMENT 公司 (#PCDATA)>
        
<!ELEMENT EMAIL (#PCDATA)>
        
<!ELEMENT 电话 (#PCDATA)>
        
<!ELEMENT 街道 (#PCDATA)>
        
<!ELEMENT 城市 (#PCDATA)>
        
<!ELEMENT 省份 (#PCDATA)>
    ]>
<联系人列表>
...................................

放在里面的时候,应该注意“standalone = "yes"”
也可以放在外面,放在外面有两种形式,一种是引用本地文件,如:

<?xml version = "1.0" encoding="GB2312" standalone = "no"?>
<!DOCTYPE 联系人列表 SYSTEM "fclml.dtd">
<联系人列表> 
..................

引用的格式是:<!DOCTYPE 根元素名 SYSTEM "外部DTD文件的URL">
另外一种是引用公共的文档定义,如:
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
格式为:<!DOCTYPE 根元素 PUBLIC "DTD名称" "外部DTD的URL">
其中DTD名称解释为:
这个DTD标识的命名规则和XML文件的命名规则稍有不同。具体地说,DTD名称只能包含字母、数字、空格和下面的符号:_%$#@()+:=/!*;?。同时,DTD名称还必须符合一些标准的规定。例如,ISO标准的DTD以“ISO”三个字母开头;被改进的非ISO标准的DTD以加号“+”开头;未被改进的非ISO标准的DTD以减号“-”开头。
所以说struts的配置文件就是“未被改进的非ISO标准的DTD文档”

二、DTD的内容
DTD文档的内容总结下来有几个比较重要也比较常用的:参数实体定义、元素定义和属性定义
1、参数实体定义
   实体实际上在XML当中充当宏定义或者别名之类的意思,也可以理解成public static String......
   参数实体是专门用在DTD当中的,你可以在下面两项元素定义和属性定义中引用参数实体。
   其定义方式如下:
   <!ENTITY % 实体名 "实体内容"> 注意,在XML中的实体定义是没有%的
   或者是:
   <!ENTITY % 实体名 SYSTEM "外部文件名">
   引用方式:
   %实体名
    例子:
   <!ENTITY % Boolean "(true|false|yes|no)">表示定义了一个Boolean 的参数实体,值是"(true|false|yes|no)"
   在struts的配置文件的DTD中有如下描述:
   <!ATTLIST form-bean      dynamic        %Boolean;       #IMPLIED>
   也就定义了form-bean这个元素的dynamic属性可以取得值是true、false、yes、no其中之一。

2、元素定义
   用来定义元素的格式以及元素的子孙等。
   定义形式:    
   <!ELEMENT 元素名 元素内容描述>
   元素定义这里由于篇幅有限,仅列几个例子
      1、<!ELEMENT 联系人列表 ANY>表示联系人列表这个元素的格式及其子孙都不受限制。
      2、<!ELEMENT 姓名(#PCDATA)>表示姓名这个元素只能包含文本数据
      3、<!ELEMENT 联系人(姓名 EMAIL)>表示联系人这个元素只能包含姓名和EMAIL两种子孙,顺序不限,并且姓名只能由一个,EMAIL也只能由一个。
      4、<!ELEMENT 联系人(姓名,EMAIL)>表示联系人这个元素只能包含姓名和EMAIL两种子孙,有顺序的限制,并且姓名只能由一个,EMAIL也只能由一个。
      5、<!ELEMENT 联系人(姓名,EMAIL+)>表示联系人必须有且仅有一个姓名子孙,有一个到多个EMAIL子孙,其中,如果+换作*,则表示零个或者多个。
      6、<!ELEMENT 联系人(姓名,EMAIL)+>表示联系人有一组到多组子孙,每组中有且仅有一对姓名和EMAIL
      7、<!ELEMENT 联系人(姓名,(电话|EMAIL))>表示联系人有一组到多组子孙,每组中第一个元素一定是姓名,第二个元素要么是电话,要么是EMAIL,两者选一个。
      8、<!ELEMENT 联系人 EMPTY>联系人这个元素不包含任何子孙,也不包含文本。

3、属性定义
      格式:
<!ATTLIST 元素名 (属性名 属性类型 缺省值)*>
      例子:
      
1、<!ATTLIST 页面作者
        姓名 #CDATA #IMPLIED
        年龄 #CDATA #IMPLIED
        联系信息 #CDATA #REQUIRED
        网站职务 #CDATA #FIXED "页面作者"
        个人爱好 #CDATA "上网">
      其中,定义了页面作者这个元素的属性可以有“姓名”,“年龄”,“联系信息”,“网站职务”和“个人爱好”
      并且,姓名和年龄是纯文本,可以没有,联系信息必须有,网站职务一定是“页面作者”,个人爱好如果不填,则默认是上网。

      2、<!ATTLIST 肉 类型( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉">元素肉可以有“类型”属性,类型属性可以选择 鸡肉 | 牛肉 | 猪肉 | 鱼肉其中一个,默认是“鸡肉”
      3、<!ATTLIST 联系人 编号 ID #REQUIRED>联系人元素有且必须有编号属性,其类型是ID型的,ID型或者是IDREF型的属性值必须是一个有效的XML名称,它由字母、数字或下划线开始,名字中不能出现空白符。类似Html中的ID。
      4、另外类型NMTOKEN和NMTOKENS还有NOTATION类型我还不是太明白,那位明白的不妨给出^_^。

posted @ 2005-03-08 14:23 Boris-Java 阅读(677) | 评论 (0)编辑 收藏

XQuery的一个简单例子(转载)

来源:中国XML论坛

看到有人问如何使用xquery,其实我也是个菜鸟。
刚刚运行了两个例子,给不会的指个路。
首先下载saxon8.1.1   http://saxon.sourceforge.net/
Saxon-B 8.1.1是免费的,Saxon-SA 8.1.1是有试用期的,前者就够了。
系统要安装jdk1.4.1以上版本,因为saxon是用这个版本写的,但不知道1.3.1行不。
记得设置JAVA_HOME环境变量指向jdk。
然后,试试吧!

例子:文件characters.xml

<characters>
<character>
    <name>Aleria</name>
    <gender>Female</gender>
    <species>Heroleim</species>
    <vocation>Bard</vocation>
    <level>5</level>
    <health>25</health>
</character>
<character>
    <name>Shar</name>
    <gender>Male</gender>
    <species>Human</species>
    <vocation>Merchant</vocation>
    <level>6</level>
    <health>28</health>
</character>
<character>
    <name>Gite</name>
    <gender>Female</gender>
    <species>Aelvar</species>
    <vocation>Mage</vocation>
    <level>7</level>
    <health>18</health>
</character>
<character>
    <name>Horukkan</name>
    <gender>Male</gender>
    <species>Udrecht</species>
    <vocation>Warrior</vocation>
    <level>5</level>
    <health>32</health>
</character>
<character>
    <name>Gounna</name>
    <gender>Female</gender>
    <species>Noleim</species>
    <vocation>Mage</vocation>
    <level>8</level>
    <health>31</health>
</character>
<character>
    <name>Sheira</name>
    <gender>Female</gender>
    <species>Human</species>
    <vocation>Cleric</vocation>
    <level>4</level>
    <health>17</health>
</character>
<character>
    <name>Drue</name>
    <gender>Female</gender>
    <species>Voleim</species>
    <vocation>Warrior</vocation>
    <level>6</level>
    <health>32</health>
</character>
<character>
    <name>Paccu</name>
    <gender>Male</gender>
    <species>Human</species>
    <vocation>Merchant</vocation>
    <level>5</level>
    <health>24</health>
</character>
</characters>

查询文件:Date.xquery
for $character in doc('characters.xml')//character
order by $character/name descending
return
      <dateReport>
            {$character/name}
            
      </dateReport>
(: Stylus Studio meta-information - (c)1998-2003. Sonic Software Corporation. All rights reserved.
<metaInformation>
<scenarios/><MapperInfo><TargetSchema SchemaFilePath="" SchemaRoot="" AssociatedInstance=""/></MapperInfo>
</metaInformation>
:)

在命令提示下,输入:
set classpath=d:\saxon\saxon8.jar (saxon8.jar所在文件夹)
java net.sf.saxon.Query -s characters.xml Date.xquery
ok!
看结果吧!

D:\xml>java net.sf.saxon.Query -s characters.xml Date.xquery
<?xml version="1.0" encoding="UTF-8"?>
<dateReport>
   <name>Sheira</name>
</dateReport>
<dateReport>
   <name>Shar</name>
</dateReport>
<dateReport>
   <name>Paccu</name>
</dateReport>
<dateReport>
   <name>Horukkan</name>
</dateReport>
<dateReport>
   <name>Gounna</name>
</dateReport>
<dateReport>
   <name>Gite</name>
</dateReport>
<dateReport>
   <name>Drue</name>
</dateReport>
<dateReport>
   <name>Aleria</name>
</dateReport>

posted @ 2005-03-08 12:25 Boris-Java 阅读(1547) | 评论 (0)编辑 收藏