小菜毛毛技术分享

与大家共同成长

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks

#

如果是使用的catalina.sh(linux)或Catalina.bat(win)启动的:修改这两个文件,加上下面这句: SET CATALINA_OPTS= -Xms64m -Xmx128m 如果使用的winnt服务启动:打开C:\WINNT\system32\regedt32.exe,在HKEY_LOCAL_MACHINE-->SOFTWARE-->Apache Software Foundation-->Process Runner 1.0-->Tomcat5-->Parameters 修改属性: -Xms64m -Xmx128m 有人建议Xms和Xmx的值取成一样比较好,说是可以加快内存回收速度。但未经本人验证过。有兴趣可以试试。 加大tomcat连接数: 在tomcat配置文件server.xml中的配置中,和连接数相关的参数有: minProcessors:最小空闲连接线程数,用于提高系统处理性能,默认值为10 maxProcessors:最大连接线程数,即:并发处理的最大请求数,默认值为75 acceptCount:允许的最大连接数,应大于等于maxProcessors,默认值为100 enableLookups:是否反查域名,取值为:true或false。为了提高处理能力,应设置为false connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。 其中和最大连接数相关的参数为maxProcessors和acceptCount。如果要加大并发连接数,应同时加大这两个参数。 web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。
posted @ 2010-01-18 14:06 小菜毛毛 阅读(451) | 评论 (0)编辑 收藏

问题表现:

当用户执行一个大数据的应用时(净字节码量约为5M)时,系统会提示出错:

前台错误为:HTTP Status 500-Dispatch[EAITool] to method listCurTree retrun an exception

(以下省略)

………………………………………………………

………………………………………………………

后台错误为:java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start(Native Method)
        at org.apache.catalina.loader.WebappLoader.notifyContext(WebappLoader.ja
va:847)

(以下省略)

………………………………………………………

………………………………………………………

问题分析:

   由于TOMCAT内存溢出而引发的问题,主要原因是JVM的虚拟内存默认为128M,当超过这个值时就把先前占用的内存释放,而导致好象TCP/IP丢包的假象,出现HTTP500的错误。  
      解决方法主要是加大TOMCAT可利用内存,并在程序当中加大内存使用。

解决方法:

方法:加大TOMCAT可利用内存:
  在TOMCAT的目录下,也就是在TOMCAT41/bin/catalina.bat文件最前面加入
  set JAVA_OPTS=-Xms800m -Xmx800m
  表现效果是当你启动TOMCAT时,系统内存会增加近800M使用

操作方法:
  1)、先关掉WINDOWS服务当中的TOMCAT4服务。
  2)、再找到TOMCAT/BIN目录下startup.bat,双击打开它,你会发现现WINDOWS内存占用会增加近800M
  3)、执行程序,因为是TOMCAT重新编译程序,所以第一次会比较慢。

结论:

经过测试,我们得出如下数据:

系统传输约2000条数据时,大约近12M的净数据(不压缩时),系统辅助运行的内存大约占用150M左右的空间,也就是近200M的内存占用,而我们扩大了近800MJAVA内存使用,这对于业务本身来说是足够了。所以你们不用担心大数据量的传递问题。

基于JAVA虚拟机的原理,JAVA自动有垃圾回收机制,也就是在你对一些内存长时间不使用时(近2分钟,取决于使用频度和优先级等),就会自动垃圾回收,从而释放不用的内存占用。

posted @ 2010-01-18 14:05 小菜毛毛 阅读(1238) | 评论 (0)编辑 收藏

单态定义:
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。

还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。

另外方面,Singleton也能够被无状态化。提供工具性质的功能,

Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。

我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。

如何使用?
一般Singleton模式通常有几种形式:

public class Singleton {

  private Singleton(){}

  //在自己内部定义自己一个实例,是不是很奇怪?
  //注意这是private 只供内部调用

  private static Singleton instance = new Singleton();

  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
  public static Singleton getInstance() {
    return instance;   
   }
}

 

第二种形式:

public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  if (instance==null)
    instance=new Singleton();
  return instance;   }

}

 

使用Singleton.getInstance()可以访问单态类。

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

一般认为第一种形式要更加安全些。

使用Singleton注意事项
有时在某些情况下,使用Singleton并不能达到Singleton的目的,如有多个Singleton对象同时被不同的类装入器装载;在EJB这样的分布式系统中使用也要注意这种情况,因为EJB是跨服务器,跨JVM的。

我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocator为例稍微分析一下:

在Pet Store中ServiceLocator有两种,一个是EJB目录下;一个是WEB目录下,我们检查这两个ServiceLocator会发现内容差不多,都是提供EJB的查询定位服务,可是为什么要分开呢?仔细研究对这两种ServiceLocator才发现区别:在WEB中的ServiceLocator的采取Singleton模式,ServiceLocator属于资源定位,理所当然应该使用Singleton模式。但是在EJB中,Singleton模式已经失去作用,所以ServiceLocator才分成两种,一种面向WEB服务的,一种是面向EJB服务的。

Singleton模式看起来简单,使用方法也很方便,但是真正用好,是非常不容易,需要对Java的类 线程 内存等概念有相当的了解。

总之:如果你的应用基于容器,那么Singleton模式少用或者不用,可以使用相关替代技术。

 

进一步深入可参考:

Double-checked locking and the Singleton pattern

When is a singleton not a singleton?

Singleton是邪恶的

关于web应用的static变量

Jive中的单例模式

更多单例专题

更多本模式专题

更多线程安全专题

更多同步或锁专题

更多对象生命周期专题

posted @ 2010-01-11 13:44 小菜毛毛 阅读(290) | 评论 (0)编辑 收藏

c:forEach标签的使用

在JSP的开发中,迭代是经常要使用到的操作。例如,逐行的显示查询的结果等。在早期的JSP中,通常使用Scriptlets来实现Iterator或者Enumeration对象的迭代输出。现在,通过JSTL的迭代标签可以在很大的程度上简化迭代操作。

           JSTL所支持的迭代标签有两个,分别是c:forEach和c:forTokens。在这里介绍的是c:forEach标签。

           简单点说,<c:forEach>标签的作用就是迭代输出标签内部的内容。它既可以进行固定次数的迭代输出,也可以依据集合中对象的个数来决定迭代的次数。

           c:forEach标签的语法定义如下所示。

xml 代码
  1. <c:forEach var="name" items="expression" varStatus="name"    
  2.   
  3.          begin="expression" end="expression" step="expression">  
  4.   
  5.          body content    
  6.   
  7. </c:forEach>  


           <c:forEach>标签具有以下一些属性:

l            var:迭代参数的名称。在迭代体中可以使用的变量的名称,用来表示每一个迭代变量。类型为String。

l            items:要进行迭代的集合。对于它所支持的类型将在下面进行讲解。

l            varStatus:迭代变量的名称,用来表示迭代的状态,可以访问到迭代自身的信息。

l            begin:如果指定了items,那么迭代就从items[begin]开始进行迭代;如果没有指定items,那么就从begin开始迭代。它的类型为整数。

l            end:如果指定了items,那么就在items[end]结束迭代;如果没有指定items,那么就在end结束迭代。它的类型也为整数。

l            step:迭代的步长。

           <c:forEach>标签的items属性支持Java平台所提供的所有标准集合类型。此外,您可以使用该操作来迭代数组(包括基本类型数组)中的元素。它所支持的集合类型以及迭代的元素如下所示:

l            java.util.Collection:调用iterator()来获得的元素。

l            java.util.Map:通过java.util.Map.Entry所获得的实例。

l            java.util.Iterator:迭代器元素。

l            java.util.Enumeration:枚举元素。

l            Object实例数组:数组元素。

l            基本类型值数组:经过包装的数组元素。

l            用逗号定界的String:分割后的子字符串。

l            javax.servlet.jsp.jstl.sql.Result:SQL查询所获得的行。

           不论是对整数还是对集合进行迭代,<c:forEach>的varStatus属性所起的作用相同。和var属性一样,varStatus用于创建限定了作用域的变量(改变量只在当前标签体内起作用)。不过,由varStatus属性命名的变量并不存储当前索引值或当前元素,而是赋予javax.servlet.jsp.jstl.core.LoopTagStatus类的实例。该类包含了一系列的特性,它们描述了迭代的当前状态,如下这些属性的含义如下所示:

l            current:当前这次迭代的(集合中的)项。

l            index:当前这次迭代从0开始的迭代索引。

l            count:当前这次迭代从1开始的迭代计数。

l            first:用来表明当前这轮迭代是否为第一次迭代,该属性为boolean类型。

l            last:用来表明当前这轮迭代是否为最后一次迭代,该属性为boolean类型。

l            begin:begin属性的值。

l            end:end属性的值

l            step:step属性的值

下面就来看一个个基本的例子,表格隔行背景色变化
xml 代码
  1. <c:forEach var="item" items="${contents}" varStatus="status">  
  2.       <tr <c:if test="${status.count%2==0}">bgcolor="#CCCCFE"</c:if> align="left">  
  3.             xxx   
  4.             </tr>  
posted @ 2010-01-08 15:56 小菜毛毛 阅读(336) | 评论 (0)编辑 收藏

配置的前提是要有装oracle的驱动程序,如果有装oracle服务器端或客户端就自动安装上的oracle的驱动程序
1、database->generate database
2、general->Direct generation  如果没有配置好数据源,就要点数据库的图标
3、配置Data Sourcce
选择ODBC machine data source
选择Configure
4、点击添加data source 选择用户数据源(只用于当前机器)
5、选择oracle驱动,填写新建的数据源的名字即可!
posted @ 2010-01-08 09:39 小菜毛毛 阅读(1709) | 评论 (0)编辑 收藏

Hex number system
  是计算机中数据的一种表示方法.同我们日常中的十进制表示法不一样.它由0-9,A-F,组成.与10进制的对应关系是:
  0-9对应0-9;
  A-F对应10-15;
  N进制的数可以用0---(N-1)的数表示超过9的用字母A-F
  例如:
  10进制的32表示成16进制就是:20
  16进制的32表示成10进制就是:3×16^1+2×16^0=50
  6.1 为什么需要八进制和十六进制?
  编程中,我们常用的还是10进制……毕竟C/C++是高级语言。
  比如:
  int a = 100,b = 99;
  不过,由于数据在计算机中的表示,最终以二进制的形式存在,所以有时候使用二进制,可以更直观地解决问题。
  但,二进制数太长了。比如int 类型占用4个字节,32位。比如100,用int类型的二进制数表达将是:
  0000 0000 0000 0000 0110 0100
  面对这么长的数进行思考或操作,没有人会喜欢。因此,C,C++ 没有提供在代码直接写二进制数的方法。
  用16进制或8进制可以解决这个问题。因为,进制越大,数的表达长度也就越短。不过,为什么偏偏是16或8进制,而不其它的,诸如9或20进制呢?
  2、8、16,分别是2的1次方,3次方,4次方。这一点使得三种进制之间可以非常直接地互相转换。8进制或16进制缩短了二进制数,但保持了二进制数的表达特点。在下面的关于进制转换的课程中,你可以发现这一点。
  6.2 二、八、十六进制数转换到十进制数
  6.2.1 二进制数转换为十进制数
  二进制数第0位的权值是2的0次方,第1位的权值是2的1次方……
  所以,设有一个二进制数:0110 0100,转换为10进制为:
  下面是竖式:
  0110 0100 换算成 十进制
  第0位 0 * 2^0 = 0
  第1位 0 * 2^1 = 0
  第2位 1 * 2^2 = 4
  第3位 0 * 2^3 = 0
  第4位 0 * 2^4 = 0
  第5位 1 * 2^5 = 32
  第6位 1 * 2^6 = 64
  第7位 0 * 2^7 = 0 +
  ---------------------------
  100
  用横式计算为:
  0 * 2^0 + 0 * 2^1 + 1 * 2^2 + 0 * 2^3 + 0 * 2^4 + 1 * 2^5 + 1 * 2^6 + 0 * 2^7 = 100
  0乘以多少都是0,所以我们也可以直接跳过值为0的位:
  1 * 2^2 + 1 * 2^3 + 1 * 2^5 + 1 * 2^6 = 100
  上面错的,改
  1 * 2^2 + 1 * 2^5 + 1 * 2^6 = 100
  4 + 32 + 64 =100
  6.2.2 八进制数转换为十进制数
  八进制就是逢8进1。
  八进制数采用 0~7这八数来表达一个数。
  八进制数第0位的权值为8的0次方,第1位权值为8的1次方,第2位权值为8的2次方……
  所以,设有一个八进制数:1507,转换为十进制为:
  用竖式表示:
  1507换算成十进制。
  第0位 7 * 8^0 = 7
  第1位 0 * 8^1 = 0
  第2位 5 * 8^2 = 320
  第3位 1 * 8^3 = 512 +
  --------------------------
  839
  同样,我们也可以用横式直接计算:
  7 * 8^0 + 0 * 8^1 + 5 * 8^2 + 1 * 8^3 = 839
  结果是,八进制数 1507 转换成十进制数为 839
  6.2.3 八进制数的表达方法
  C,C++语言中,如何表达一个八进制数呢?如果这个数是 876,我们可以断定它不是八进制数,因为八进制数中不可能出7以上的阿拉伯数字。但如果这个数是123、是567,或12345670,那么它是八进制数还是10进制数,都有可能。
  所以,C,C++规定,一个数如果要指明它采用八进制,必须在它前面加上一个0,如:123是十进制,但0123则表示采用八进制。这就是八进制数在C、C++中的表达方法。
  由于C和C++都没有提供二进制数的表达方法,所以,这里所学的八进制是我们学习的,CtC++语言的数值表达的第二种进制法。
  现在,对于同样一个数,比如是100,我们在代码中可以用平常的10进制表达,例如在变量初始化时:
  int a = 100;
  我们也可以这样写:
  int a = 0144; //0144是八进制的100;一个10进制数如何转成8进制,我们后面会学到。
  千万记住,用八进制表达时,你不能少了最前的那个0。否则计算机会通通当成10进制。不过,有一个地方使用八进制数时,却不能使用加0,那就是我们前面学的用于表达字符的“转义符”表达法。
  6.2.4 八进制数在转义符中的使用
  我们学过用一个转义符\'\\'加上一个特殊字母来表示某个字符的方法,如:\'\n\'表示换行(line),而\'\t\'表示Tab字符,\'\\'\'则表示单引号。今天我们又学习了一种使用转义符的方法:转义符\'\\'后面接一个八进制数,用于表示ASCII码等于该值的字符。
  比如,查一下第5章中的ASCII码表,我们找到问号字符(?)的ASCII值是63,那么我们可以把它转换为八进值:77,然后用 \'\77\'来表示\'?\'。由于是八进制,所以本应写成 \'\077\',但因为C,C++规定不允许使用斜杠加10进制数来表示字符,所以这里的0可以不写。
  事实上我们很少在实际编程中非要用转义符加八进制数来表示一个字符,所以,6.2.4小节的内容,大家仅仅了解就行。
  6.2.5 十六进制数转换成十进制数
  2进制,用两个阿拉伯数字:0、1;
  8进制,用八个阿拉伯数字:0、1、2、3、4、5、6、7;
  10进制,用十个阿拉伯数字:0到9;
  16进制,用十六个阿拉伯数字……等等,阿拉伯人或说是印度人,只发明了10个数字啊?
  16进制就是逢16进1,但我们只有0~9这十个数字,所以我们用A,B,C,D,E,F这五个字母来分别表示10,11,12,13,14,15。字母不区分大小写。
  十六进制数的第0位的权值为16的0次方,第1位的权值为16的1次方,第2位的权值为16的2次方……
  所以,在第N(N从0开始)位上,如果是是数 X (X 大于等于0,并且X小于等于 15,即:F)表示的大小为 X * 16的N次方。
  假设有一个十六进数 2AF5, 那么如何换算成10进制呢?
  用竖式计算: 2AF5换算成10进制:
  第0位: 5 * 16^0 = 5
  第1位: F * 16^1 = 240
  第2位: A * 16^2 = 2560
  第3位: 2 * 16^3 = 8192 +
  -------------------------------------
  10997
  直接计算就是:
  5 * 16^0 + F * 16^1 + A * 16^2 + 2 * 16^3 = 10997
  (别忘了,在上面的计算中,A表示10,而F表示15)
  现在可以看出,所有进制换算成10进制,关键在于各自的权值不同。
  假设有人问你,十进数 1234 为什么是 一千二百三十四?你尽可以给他这么一个算式:
  1234 = 1 * 10^3 + 2 * 10^2 + 3 * 10^1 + 4 * 10^0
  6.2.6 十六进制数的表达方法
  如果不使用特殊的书写形式,16进制数也会和10进制相混。随便一个数:9876,就看不出它是16进制或10进制。
  C,C++规定,16进制数必须以 0x开头。比如 0x1表示一个16进制数。而1则表示一个十进制。另外如:0xff,0xFF,0X102A,等等。其中的x也也不区分大小写。(注意:0x中的0是数字0,而不是字母O)
  以下是一些用法示例:
  int a = 0x100F;
  int b = 0x70 + a;
  至此,我们学完了所有进制:10进制,8进制,16进制数的表达方式。最后一点很重要,C/C++中,10进制数有正负之分,比如12表示正12,而-12表示负12,;但8进制和16进制只能用达无符号的正整数,如果你在代码中里:-078,或者写:-0xF2,C,C++并不把它当成一个负数。
  6.2.7 十六进制数在转义符中的使用
  转义符也可以接一个16进制数来表示一个字符。如在6.2.4小节中说的 \'?\' 字符,可以有以下表达方式:
  \'?\' //直接输入字符
  \'\77\' //用八进制,此时可以省略开头的0
  \'\0x3F\' //用十六进制
  同样,这一小节只用于了解。除了空字符用八进制数 \'\0\' 表示以外,我们很少用后两种方法表示一个字符。
  6.3 十进制数转换到二、八、十六进制数
  6.3.1 10进制数转换为2进制数
  给你一个十进制,比如:6,如果将它转换成二进制数呢?
  10进制数转换成二进制数,这是一个连续除2的过程:
  把要转换的数,除以2,得到商和余数,
  将商继续除以2,直到商为0。最后将所有余数倒序排列,得到数就是转换结果。
  听起来有些糊涂?我们结合例子来说明。比如要转换6为二进制数。
  “把要转换的数,除以2,得到商和余数”。
  那么:
  要转换的数是6, 6 ÷ 2,得到商是3,余数是0。 (不要告诉我你不会计算6÷3!)
  “将商继续除以2,直到商为0……”
  现在商是3,还不是0,所以继续除以2。
  那就: 3 ÷ 2, 得到商是1,余数是1。
  “将商继续除以2,直到商为0……”
  现在商是1,还不是0,所以继续除以2。
  那就: 1 ÷ 2, 得到商是0,余数是1 (拿笔纸算一下,1÷2是不是商0余1!)
  “将商继续除以2,直到商为0……最后将所有余数倒序排列”
  好极!现在商已经是0。
  我们三次计算依次得到余数分别是:0、1、1,将所有余数倒序排列,那就是:110了!
  6转换成二进制,结果是110。
  把上面的一段改成用表格来表示,则为:
  被除数 计算过程 商 余数
  6 6/2 3 0
  3 3/2 1 1
  1 1/2 0 1
  (在计算机中,÷用 / 来表示)
  如果是在考试时,我们要画这样表还是有点费时间,所更常见的换算过程是使用下图的连除:
  (图:1)
  请大家对照图,表,及文字说明,并且自己拿笔计算一遍如何将6转换为二进制数。
  说了半天,我们的转换结果对吗?二进制数110是6吗?你已经学会如何将二进制数转换成10进制数了,所以请现在就计算一下110换成10进制是否就是6。
  6.3.2 10进制数转换为8、16进制数
  非常开心,10进制数转换成8进制的方法,和转换为2进制的方法类似,唯一变化:除数由2变成8。
  来看一个例子,如何将十进制数120转换成八进制数。
  用表格表示:
  被除数 计算过程 商 余数
  120 120/8 15 0
  15 15/8 1 7
  1 1/8 0 1
  120转换为8进制,结果为:170。
  非常非常开心,10进制数转换成16进制的方法,和转换为2进制的方法类似,唯一变化:除数由2变成16。
  同样是120,转换成16进制则为:
  被除数 计算过程 商 余数
  120 120/16 7 8
  7 7/16 0 7
  120转换为16进制,结果为:78。
  请拿笔纸,采用(图:1)的形式,演算上面两个表的过程。
  6.4 二、十六进制数互相转换
  二进制和十六进制的互相转换比较重要。不过这二者的转换却不用计算,每个C,C++程序员都能做到看见二进制数,直接就能转换为十六进制数,反之亦然。
  我们也一样,只要学完这一小节,就能做到。
  首先我们来看一个二进制数:1111,它是多少呢?
  你可能还要这样计算:1 * 2^0 + 1 * 2^1 + 1 * 2^2 + 1 * 2^3 = 1 * 1 + 1 * 2 + 1 * 4 + 1 * 8 = 15。
  然而,由于1111才4位,所以我们必须直接记住它每一位的权值,并且是从高位往低位记,:8、4、2、1。即,最高位的权值为2^3 = 8,然后依次是 2^2 = 4,2^1=2, 2^0 = 1。
  记住8421,对于任意一个4位的二进制数,我们都可以很快算出它对应的10进制值。
  下面列出四位二进制数 xxxx 所有可能的值(中间略过部分)
  仅4位的2进制数 快速计算方法 十进制值 十六进值
  1111 = 8 + 4 + 2 + 1 = 15 F
  1110 = 8 + 4 + 2 + 0 = 14 E
  1101 = 8 + 4 + 0 + 1 = 13 D
  1100 = 8 + 4 + 0 + 0 = 12 C
  1011 = 8 + 0 + 2 + 1 = 11 B
  1010 = 8 + 0 + 2 + 0 = 10 A
  1001 = 8 + 0 + 0 + 1 = 10 9
  ....
  0001 = 0 + 0 + 0 + 1 = 1 1
  0000 = 0 + 0 + 0 + 0 = 0 0
  二进制数要转换为十六进制,就是以4位一段,分别转换为十六进制。
  如(上行为二制数,下面为对应的十六进制):
  1111 1101 , 1010 0101 , 1001 1011
  F D , A 5 , 9 B
  反过来,当我们看到 FD时,如何迅速将它转换为二进制数呢?
  先转换F:
  看到F,我们需知道它是15(可能你还不熟悉A~F这五个数),然后15如何用8421凑呢?应该是8 + 4 + 2 + 1,所以四位全为1 :1111。
  接着转换 D:
  看到D,知道它是13,13如何用8421凑呢?应该是:8 + 4 + 1,即:1101。
  所以,FD转换为二进制数,为: 1111 1101
  由于十六进制转换成二进制相当直接,所以,我们需要将一个十进制数转换成2进制数时,也可以先转换成16进制,然后再转换成2进制。
  比如,十进制数 1234转换成二制数,如果要一直除以2,直接得到2进制数,需要计算较多次数。所以我们可以先除以16,得到16进制数:
  被除数 计算过程 商 余数
  1234 1234/16 77 2
  77 77/16 4 13 (D)
  4 4/16 0 4
  结果16进制为: 0x4D2
  然后我们可直接写出0x4D2的二进制形式: 0100 1101 0010。
  其中对映关系为:
  0100 -- 4
  1011 -- D
  0010 -- 2
  同样,如果一个二进制数很长,我们需要将它转换成10进制数时,除了前面学过的方法是,我们还可以先将这个二进制转换成16进制,然后再转换为10进制。
  下面举例一个int类型的二进制数:
  01101101 11100101 10101111 00011011
  我们按四位一组转换为16进制: 6D E5 AF 1B
  6.5 原码、反码、补码
  结束了各种进制的转换,我们来谈谈另一个话题:原码、反码、补码。
  我们已经知道计算机中,所有数据最终都是使用二进制数表达。
  我们也已经学会如何将一个10进制数如何转换为二进制数。
  不过,我们仍然没有学习一个负数如何用二进制表达。
  比如,假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:
  00000000 00000000 00000000 00000101
  5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。
  现在想知道,-5在计算机中如何表示?
  在计算机中,负数以其正值的补码形式表达。
  什么叫补码呢?这得从原码,反码说起。
  原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
  比如 00000000 00000000 00000000 00000101 是 5的 原码。
  反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。
  取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
  比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。
  称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反码。
  反码是相互的,所以也可称:
  11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互为反码。
  补码:反码加1称为补码。
  也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。
  比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。
  那么,补码为:
  11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
  所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。
  再举一例,我们来看整数-1在计算机中如何表示。
  假设这也是一个int类型,那么:
  1、先取1的原码:00000000 00000000 00000000 00000001
  2、得反码: 11111111 11111111 11111111 11111110
  3、得补码: 11111111 11111111 11111111 11111111
  可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF。
  一切都是纸上说的……说-1在计算机里表达为0xFFFFFF,我能不能亲眼看一看呢?当然可以。利用C++ Builder的调试功能,我们可以看到每个变量的16进制值。
  6.6 通过调试查看变量的值
  下面我们来动手完成一个小小的实验,通过调试,观察变量的值。
  我们在代码中声明两个int 变量,并分别初始化为5和-5。然后我们通过CB提供的调试手段,可以查看到程序运行时,这两个变量的十进制值和十六进制值。
  首先新建一个控制台工程。加入以下黑体部分(就一行):
  //---------------------------------------------------------------------------
  #pragma hdrstop
  //---------------------------------------------------------------------------
  #pragma argsused
  int main(int argc, char* argv[])
  {
  int aaaa = 5, bbbbb = -5;
  return 0;
  }
  //---------------------------------------------------------------------------
  没有我们熟悉的的那一行:
  getchar();
  所以,如果全速运行这个程序,将只是DOS窗口一闪而过。不过今天我们将通过设置断点,来使用程序在我们需要的地儿停下来。
  设置断点:最常用的调试方法之一,使用程序在运行时,暂停在某一代码位置,
  在CB里,设置断点的方法是在某一行代码上按F5或在行首栏内单击鼠标。
  如下图:
  在上图中,我们在return 0;这一行上设置断点。断点所在行将被CB以红色显示。
  接着,运行程序(F9),程序将在断点处停下来。
  (请注意两张图的不同,前面的图是运行之前,后面这张是运行中,左边的箭头表示运行运行到哪一行)
  当程序停在断点的时,我们可以观察当前代码片段内,可见的变量。观察变量的方法很多种,这里我们学习使用Debug Inspector (调试期检视),来全面观察一个变量。
  以下是调出观察某一变量的 Debug Inspector 窗口的方法:
  先确保代码窗口是活动窗口。(用鼠标点一下代码窗口)
  按下Ctrl键,然后将鼠标挪到变量 aaaa 上面,你会发现代码中的aaaa变蓝,并且出现下划线,效果如网页中的超链接,而鼠标也变成了小手状:
  点击鼠标,将出现变量aaaa的检视窗口:
  (笔者使用的操作系统为WindowsXP,窗口的外观与Win9X有所不同)
  从该窗口,我可以看到:
  aaaa :变量名
  int :变量的数据类型
  0012FF88:变量的内存地址,请参看5.2 变量与内存地址;地址总是使用十六进制表达
  5 : 这是变量的值,即aaaa = 5;
  0x00000005 :同样是变量的值,但采用16进制表示。因为是int类型,所以占用4字节。
  首先先关闭前面的用于观察变量aaaa的Debug Inspector窗口。
  现在,我们用同样的方法来观察变量bbbb,它的值为-5,负数在计算机中使用补码表示。
  正如我们所想,-5的补码为:0xFFFFFFFB。
  再按一次F9,程序将从断点继续运行,然后结束。
  6.7 本章小结
  很难学的一章?
  来看看我们主要学了什么:
  1)我们学会了如何将二、八、十六进制数转换为十进制数。
  三种转换方法是一样的,都是使用乘法。
  2)我们学会了如何将十进制数转换为二、八、十六进制数。
  方法也都一样,采用除法。
  3)我们学会了如何快速的地互换二进制数和十六进制数。
  要诀就在于对二进制数按四位一组地转换成十六进制数。
  在学习十六进制数后,我们会在很多地方采用十六进制数来替代二进制数。
  4)我们学习了原码、反码、补码。
  把原码的0变1,1变0,就得到反码。要得到补码,则先得反码,然后加1。
  以前我们只知道正整数在计算机里是如何表达,现在我们还知道负数在计算机里使用其绝对值的补码表达。
  比如,-5在计算机中如何表达?回答是:5的补码。
  5)最后我们在上机实验中,这会了如何设置断点,如何调出Debug Inspector窗口观察变量。
  以后我们会学到更多的调试方法。
  daiqionghui 修改一部分错的。、
  十六进制
  rkb-irir rtrt*-7-759-9urelurugf 44ihub 十六进制
posted @ 2009-12-18 17:02 小菜毛毛 阅读(468) | 评论 (0)编辑 收藏

字体大小: 正文
交换两个变量的值,不使用第三个变量(2009-09-16 18:19:18)
 
通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换。代码如下:
int a,b;
a=10; b=15;
int t;
t=a; a=b; b=t;
这种算法易于理解,特别适合帮助初学者了解计算机程序的特点,是赋值语句的经典应用。在实际软件开发当中,此算法简单明了,不会产生歧义,便于程序员之间的交流,一般情况下碰到交换变量值的问题,都应采用此算法(以下称为标准算法)。

上面的算法最大的缺点就是需要借助一个临时变量。那么不借助临时变量可以实现交换吗?答案是肯定的!这里我们可以用三种算法来实现:1)算术运算;2)指针地址操作;3)位运算。

1) 算术运算
简单来说,就是通过普通的+和-运算来实现。代码如下:
int a,b;
a=10;b=12;
a=b-a; //a=2;b=12
b=b-a; //a=2;b=10
a=b+a; //a=10;b=10
通过以上运算,a和b中的值就进行了交换。表面上看起来很简单,但是不容易想到,尤其是在习惯标准算法之后。
它的原理是:把a、b看做数轴上的点,围绕两点间的距离来进行计算。
具体过程:第一句“a=b-a”求出ab两点的距离,并且将其保存在a中;第二句“b=b-a”求出a到原点的距离(b到原点的距离与ab两点距离之差),并且将其保存在b中;第三句“a=b+a”求出b到原点的距离(a到原点距离与ab两点距离之和),并且将其保存在a中。完成交换。
此算法与标准算法相比,多了三个计算的过程,但是没有借助临时变量。(以下称为算术算法)

2) 指针地址操作
因为对地址的操作实际上进行的是整数运算,比如:两个地址相减得到一个整数,表示两个变量在内存中的储存位置隔了多少个字节;地址和一个整数相加即“a+10”表示以a为基地址的在a后10个a类数据单元的地址。所以理论上可以通过和算术算法类似的运算来完成地址的交换,从而达到交换变量的目的。即:
int *a,*b; //假设
*a=new int(10);
*b=new int(20); //&a=0x00001000h,&b=0x00001200h
a=(int*)(b-a); //&a=0x00000200h,&b=0x00001200h
b=(int*)(b-a); //&a=0x00000200h,&b=0x00001000h
a=(int*)(b+int(a)); //&a=0x00001200h,&b=0x00001000h
通过以上运算a、b的地址真的已经完成了交换,且a指向了原先b指向的值,b指向原先a指向的值了吗?上面的代码可以通过编译,但是执行结果却令人匪夷所思!原因何在?
首先必须了解,操作系统把内存分为几个区域:系统代码/数据区、应用程序代码/数据区、堆栈区、全局数据区等等。在编译源程序时,常量、全局变量等都放入全局数据区,局部变量、动态变量则放入堆栈区。这样当算法执行到“a=(int*)(b-a)”时,a的值并不是0x00000200h,而是要加上变量a所在内存区的基地址,实际的结果是:0x008f0200h,其中0x008f即为基地址,0200即为a在该内存区的位移。它是由编译器自动添加的。因此导致以后的地址计算均不正确,使得a,b指向所在区的其他内存单元。再次,地址运算不能出现负数,即当a的地址大于b的地址时,b-a<0,系统自动采用补码的形式表示负的位移,由此会产生错误,导致与前面同样的结果。
有办法解决吗?当然!以下是改进的算法:
if(a<b)
{
a=(int*)(b-a);
b=(int*)(b-(int(a)&0x0000ffff));
a=(int*)(b+(int(a)&0x0000ffff));
}
else
{
b=(int*)(a-b);
a=(int*)(a-(int(b)&0x0000ffff));
b=(int*)(a+(int(b)&0x0000ffff));
}
算法做的最大改进就是采用位运算中的与运算“int(a)&0x0000ffff”,因为地址中高16位为段地址,后16位为位移地址,将它和0x0000ffff进行与运算后,段地址被屏蔽,只保留位移地址。这样就原始算法吻合,从而得到正确的结果。
此算法同样没有使用第三变量就完成了值的交换,与算术算法比较它显得不好理解,但是它有它的优点即在交换很大的数据类型时,它的执行速度比算术算法快。因为它交换的时地址,而变量值在内存中是没有移动过的。(以下称为地址算法)

3) 位运算
通过异或运算也能实现变量的交换,这也许是最为神奇的,请看以下代码:
int a=10,b=12; //a=1010^b=1100;
a=a^b; //a=0110^b=1100;
b=a^b; //a=0110^b=1010;
a=a^b; //a=1100=12;b=1010;
此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变。
即:a^b^b=a。将a=a^b代入b=a^b则得b=a^b^b=a;同理可以得到a=b^a^a=b;轻松完成交换。

以上三个算法均实现了不借助其他变量来完成两个变量值的交换,相比较而言算术算法和位算法计算量相当,地址算法中计算较复杂,却可以很轻松的实现大类型(比如自定义的类或结构)的交换,而前两种只能进行整形数据的交换(理论上重载“^”运算符,也可以实现任意结构的交换)。

介绍这三种算法并不是要应用到实践当中,而是为了探讨技术,展示程序设计的魅力。从中可以看出,数学中的小技巧对程序设计而言具有相当的影响力,运用得当会有意想不到的神奇效果。而从实际的软件开发看,标准算法无疑是最好的,能够解决任意类型的交换问题
posted @ 2009-12-02 14:55 小菜毛毛 阅读(7521) | 评论 (0)编辑 收藏

     摘要: 转载自:http://www.ibm.com/developerworks/cn/java/j-drools/ 使用声明性编程方法编写程序的业务逻辑 ...  阅读全文
posted @ 2009-11-28 14:36 小菜毛毛 阅读(1639) | 评论 (1)编辑 收藏

第一章 介绍与导览




本文描述Weblogic Server的域以及如何配置域。域是WebLogic Server的基本管理单元。一个域可以包括一个或多个WebLogic Server实例以及相关资源,只需使用一个Administration Server进行管理。




以下章节描述该指南的内容与结构——理解域配置。

文档范围与读者

文档向导

相关文档

示例与指南

该发布版本中新的域特性




文档范围与读者




文档主要适用于基于一个或多个Weblogic server域开发和部署Web应用的J2EE系统架构师、应用开发人员和系统管理员。




文档的主题仅和软件项目的设计与开发阶段相关,不涉及产品过程管理、监控或者性能调整。对于这些主题的WebLogic Server文档和资源链接,参见“相关文档”。




文档假定读者熟悉J2EE,XML的基本概念以及应用管理的一般概念。




文档向导

本章“介绍与导览”,介绍该指南的目的、结构和上下文关系。

第二章“理解WebLogic Server域”介绍Weblogic Server域。

第三章“使用WebLogic工具配置域”,展示你可以用来修改域配置的几种工具。

第四章“域配置文件”描述维护域和域的内容的磁盘表现形式的配置与目录。

第五章“管理配置变更”描述如何变更Weblogic Server的管理特性。




相关文档

关于用于创建和配置Weblogic Server域的工具的更多信息,参见:

使用配置向导创建WebLogic域

WebLogic脚本工具

使用JMX部署可管理的应用

WebLogic Server命令参考

管理控制台在线帮助

关于其他系统管理任务的信息,参见系统管理文档,尤其是:

设计和配置WebLogic Server环境

使用WebLogic Server集群




示例和向导

BEA系统公司为本文档提供了和域配置、管理相关的以下代码示例和指南:

BEA WebLogic Server的示例安装(可选)于目录WL_HOME/samples/server/examples/src/examples,WL_HOME是你安装WebLogic Server的顶级目录,这些示例也可以通过Windows开始菜单使用。集群示例会在BEA WebLogic Server集群指南示例中描述,指导你掌握使用WebLogic配置向导和管理控制台来创建和配置一个新的server实例集群的整个过程。




本版中新的域特性

Weblogic Server 9.0在Weblogic Server域配置中引入了几项重要变化:

config.xml的XML Schema

域目录结构

配置变更管理




config.xml的XML Schema

WebLogic Server域和实例配置的磁盘表现形式在本版本中有所不同。在原版本中,配置信息被保存在单个XML仓库文件config.xml中,默认位于user_projects/domains/domain_name目录下。在本版的WebLogic Server中,config.xml文件符合XML Schema定义(用来验证域配置文件格式的有效性)。而且,config.xml融合了其他配置文件(符合各自的XML Schema)的配置信息。在本版中,config.xml默认位于user_projects/domains/domain_name/config目录下,config.xml核心文件涉及的辅助配置文件位于user_projects/domains/domain_name/config目录的子目录中。更多信息,参见第四章“域配置文件”。




域目录结构

本版中,Weblogic Server域在磁盘上的目录结构有了改变。域的父目录命名为domains。域的配置信息保存在domains/domain_name/config目录和config目录的子目录中。更多信息,参见“域目录内容”。




配置变更管理

WebLogic Server提供了一些新特性用来管理服务配置变更,这使你可以安全、可预知地实现分发某个域的配置变更。当然这要求你在使用控制台进行配置变更前获得管理员控制台锁。




WebLogic Server中的变更管理过程和数据库事务有些类似。由管理服务器维护一个独立的,可编辑的域配置表现形式,称为编辑层。server实例并不涉及编辑层。相反,server实例使用只读层来发现配置。为了开启编辑过程,你应当可以获得一个编辑层的锁以防止其他人更改。当你完成更改后,你保存并将其分发至域中的所有server实例。分发完成后,每一个server来决定自己是否接受该变更。一旦所有的server都接受该变更,则更新运行的配置层,变更才完成。




现在的管理控制台包括一个名为Change Center(变更中心)的区域。当你使用管理控制台进行配置变更时,你必须首先通过点击Change Center的Lock & Make Changes(锁且变更)获得锁。进行期望的配置变更以后,然后可以在Change Center:

点击Activate Changes(激活变更)接受更改,向域中的sever实例分发,或者

点击Undo All Changes(撤销所有变更),释放锁。

WebLogic Server一般采用相同方式控制配置变更,无论变更是使用管理控制台实现,还是WebLogic 脚本工具、配置管理服务或者JMX API。

更多信息,参见第五章“管理配置变更”。




第二章 理解Weblogic Server域

以下章节介绍Weblogic Server域和域的内容:

域是什么

组织域

域的内容

域约束




域是什么?

一个Weblogic Server管理域是逻辑上相关的Weblogic Server资源组。域包括一个特殊的Weblogic Server实例,叫做管理服务器(Administration Server),这是你配置和管理域的所有资源的关键。通常,你配置的一个域会加入另外的WebLogic Server实例,叫作托管服务器(Managed Server)。你的Web应用、EJB和其他资源会部署在托管服务器上,而管理服务器只是用于配置和管理。




多个托管服务器可以组织成集群(clusters),这使你能够保持负载平衡和对于临界的应用提供失败保护,同时只使用一个管理服务器会使托管服务器实例的管理变得简单。




组织域




如何将WebLogic Server装置组织成域,这取决于你的业务需求。你可以基于系统管理员职责、应用边界或者server运行的地理位置的不同定义多个域。与之相反,你也可以决定将所有WebLogic Server管理行为集中于一个域。




根据你特定的业务需求和系统管理实际,你可以按照如下标准决定如何组织你的域:




应用的逻辑区分。比如,你可以有一个域用于类似购物车的终端用户功能,另一个域用于后台记账。

物理位置。你可以为业务的不同地理位置和分支分别建域。

大小。你会发现域被组织成更小的单元可能会使不同的系统管理员管理效率更高。反之,你也会发现维护单个域或者少量的域,配置更容易保持一致。




一个域由一个管理服务器和一个或多个托管服务器组成,也可以只由单个孤立的server组成,既扮演管理服务器的角色又驻留应用。




由分散的托管服务器组成的域:简单的产品环境由几个驻留应用的托管服务器,一个执行管理操作的管理服务器组成。在这种配置下,应用和资源部署在各自的托管服务器中;类似地,访问应用的客户端与各自的托管服务器连接。




如果产品环境对增强应用性能、吞吐量或者可用性有要求,那么应该将两个或者更多的托管服务器配置成集群。机群允许多个托管服务器作为单个个体驻留应用和资源。关于在孤立的和集群托管服务器之间差异的更多信息,参见“托管服务器和托管服务器集群”。

孤立的server域:对于开发或测试环境而言,你可能想在部署单个应用和server独立于产品域中的server。这种情况下,你可以部署一个简单域,只由单个server实例组成,既作为管理服务器,又驻留你开发的应用。你用WebLogic Server安装的wl_server域就是一个孤立server域的例子。

注意:在产品环境中,BEA建议你只在域中的托管服务器部署应用,管理服务器应当只负责管理任务。




域的内容



尽管域的范围与目的会有很大差异,但是大多数 WebLogic Server域都包含本章节中描述的组件。




下图展示了产品环境,包括一个管理服务器,三个孤立的托管服务器和三个托管服务器组成的集群。



管理服务器

每个Weblogic Server域都必须有一个server实例作为管理服务器。你使用管理服务器(编程或者通过管理服务器)来配置域中的所有其他server实例和资源。




管理服务器的角色




在启动域的托管服务器之前,应先启动管理服务器。当你启动一个孤立或集群托管服务器时,它会按配置信息与管理服务器相联。这种方式下,管理服务器在整个域配置中充当核心控制体。




当管理服务器启动时,加载域的config.xml文件,除非你在创建域时指定另一个目录存储config.xml。




BEA_HOME/user_projects/domains/mydomain/config




这里mydomain是特定域的目录,名称与域相同。config.xml引用的其他配置文件,位于域的config目录的子目录下。




管理服务器每一次成功启动后,将在域目录中创建一份命名为config-booted.jar的备份配置文件。万一配置文件在server实例生命周期内有损坏,有可能恢复原先的配置。




如果管理服务器出错会发生什么?




域的管理服务器出错不会影响域中的托管服务器的操作。如果域的管理服务器变得不可用,而它所管理的server实例——集群或者其他方式——仍在运行,那么那些托管服务器将继续运行。如果该域包含集群server实例,那么由域配置支持的负载平衡和失败性能保持可用,即使管理服务器出错。如果域的管理服务器停止运行而托管服务器继续运行,那么每一个托管服务器会周期性地尝试重新连接管理服务器,周期由ServerMBean属性AdminReconnectIntervalSecs指定。AdminReconnectIntervalSecs默认为10秒。




如果管理服务器因为主机的硬件或软件错误而失败,同一台机器的其它server实例都可能受到同样的影响。然而,管理服务器自身的失败不会中断域的托管服务器的运行。而且即使管理服务器不在运行状态,你也可以启动托管服务器。这种情况下,托管服务器使用配置文件的本地拷贝来作为它的启动配置,然后周期性地向管理服务器作连接尝试,连接后利用管理服务器来同步配置状态。




对于重启管理服务器的指令,参见“管理服务器启动与关闭”。







托管服务器和托管服务器集群




在域中,非管理服务器的server实例,指向托管服务器。托管服务器驻留构成你应用的组件和相关资源,比如JSP和EJB。当某个托管服务器启动后,它会连接域的管理服务器来获得配置和部署设置。




注意:即使管理服务器不可用,域中的托管服务器也可以独立于管理服务器启动。更多信息参见“管理server启动与关闭”中的“避免server失败与恢复”。

两个或更多的托管服务器可以配置成一个WebLogic Server集群,来增加应用的可伸缩性与可用性。在WebLogic Server集群中,大多数资源与服务平均部署给每一个托管服务器(与单个托管服务器相反),来使失败与负载平衡。要想了解哪种组件类型和服务可以进行集群(部署给集群中的所有server实例),参见“使用WebLogic Server集群”中的“理解WebLogic Server集群”。

你可以创建一个非集群的托管服务器,然后通过配置有关server实例和集群的参数将其加入集群。你也可以通过重新配置参数从集群中删除某个托管服务器。在集群与非集群托管服务器之间的根本区别在于对失败和负载平衡的支持。这些特性仅在集群托管服务器中可用。

你对于可伸缩性与可靠性的要求将决定你是否采用集群托管服务器。比如,如果你的应用不常遇到易变的加载,应用服务中可能的中断也是可以接受的,那么就没有必要采用集群。

关于WebLogic Server集群的好处与性能的更多信息,参见“使用WebLogic Server集群”中的“理解WebLogic Server集群”。单个域可以包含多个WebLogic Server集群,同样多个托管服务器也可以不被配置成集群。




资源与服务




除了管理服务器和托管服务器之外,域还包括托管服务器所需的资源和服务及部署在该域上的应用。




域配置包括域运行的网络计算机环境信息,比如:

机器定位依靠硬件上某个特定的物理片段来识别。机器定位被用来关联驻留托管服务器的计算机。该信息由节点管理器(Node Manager)重启一台出错的托管服务器,集群的托管服务器选择存储重复的会话数据的最好位置时使用。关于节点管理器的更多信息,参见“设计与配置WebLogic Server环境”的“使用节点管理器控制服务器”。

网络通道,一个可以用来定义默认端口、协议和协议设置的可选资源。在创建一个网络通道后,可以将它分配给域中任意一个托管服务器和集群。更多信息,参见“设计与配置WebLogic Server环境”中的“配置网络资源”。

域配置还包括与驻留在域中应用相关的资源和服务信息。这些资源和服务的例子包括:

应用组件,比如EJB

连接器

JDBC连接池

JMS server

启动类

资源和服务可能被限制于域中一个或多个托管服务器,而不是对于整个域可用。你可以选择托管服务器或者集群进行部署资源与服务。




域约束




WebLogic Server环境可以由单个域组成,包括驻留应用所需的所有托管服务器,也可以是多个域。你可以选择创建多个域,根据组织单元、系统管理员职责、应用边界或者其它要考虑的事项来划分。在设计域配置时,注意以下约束:




每一个域都需要自身的管理服务器执行管理操作。当你使用管理控制台执行管理和监控任务时,你可以在域中来回切换,同时你会连接不同的管理服务器。

同一个集群中的所有托管服务器必须位于相同的域,你不能将集群拆分至多个域。

同一个域中的所有托管服务器运行的WebLogic Server软件版本必须相同。域中的管理服务器可以和托管服务器运行相同的版本,也可以是更新的版本。

你不能在域中共享配置资源与子系统。比如,如果你在一个域中创建了一个JDBC连接池,你就不可能在另一个域中的托管服务器或集群中使用。代之,你必须在第二个域中创建一个类似的连接池。




第三章 使用Weblogic工具配置域

WebLogic包括了你可以用来创建、修改或者复制域配置的一系列工具。包括以下工具:

域配置向导——域配置向导是创建一个新的域或集群的推荐工具。关于使用域配置向导的更多信息,参见“使用配置向导创建WebLogic域”。

WebLogic Server管理控制台——管理控制台是管理服务器的图形化用户界面(GUI)。管理控制台描述参见“管理控制台在线帮助”。

WebLogic脚本工具(WLST)——你可以使用命令行脚本接口来创建、管理和维护WebLogic Server配置变更。WebLogic脚本工具描述参见“WebLogic脚本工具”。

WebLogic Server应用编程接口(API)—— 你可以使用WebLogic Server提供的API编写程序修改配置属性。JMX API描述参见“使用JMX开发可管理的应用”。

WebLogic Server命令行工具——该工具允许你创建脚本来自动进行域管理。关于该工具的更多信息,参见“WebLogic Server命令参考”。




对于大多数方式而言,要修改域配置域的管理服务器必须运行。然而,你如果使用 WLST 来进行域配置变更不需要运行管理服务器。这种情况下,WLST造成的变更也不会立即生效直到管理服务器和托管服务器重启。




第四章 域配置文件





本章节描述如何在文件系统中表示域。它包括以下部分:

配置文件概览

config.xml

域域目录概览

域目录内容

域配置文件概览

WebLogic Server管理和配置服务通过Java管理扩展(JMX)API来访问。域的配置保存在域目录下的配置目录中。这些配置目录中的文件用来持久化存储WebLogic Server在使用JMX API运行期间创建和修改的托管对象。config.xml的目的是存储托管配置对象的变更以使得WebLogic Server重启时可以访问。

域的核心配置文件为domain_name/config/config.xml文件。它指定域的名称和域中每一个server实例、集群、资源和服务的配置参数。域的一些主要子系统配置保存在domain_name/config目录的子目录中。

域目录还包括你用来启动域的管理服务器和托管服务器的默认脚本文件。




config.xml

域的核心配置文件为/domains/domain_name/config/config.xml文件。它指定域的名称和域中每一个server实例、集群、资源与服务的配置参数。

config.xml文件符合XML Schema,URL为 http://www.bea.com/ns/weblogic/config。schema位于文件系统中的JAR文件BEA_HOME/weblogic90/server/lib/schema/configuration-binding.jar中,即META-INF/schemas/schema-0.xsd。XML编辑工具可以使用XML Schema来修改和验证config.xml文件。




编辑配置文件

大多数情况下,你不应该直接修改config.xml或其他配置文件,而应该使用管理控制台或者用第三章“使用WebLogic工具配置域”中列出的某个工具来修改域配置。配置变更将会映射到配置文件中。

如果你选择放置配置文件,安装的其他组件在源控制之下(使用WLST管理),直接修改配置文件可能是合适的。

警告:当WebLogic Server运行时你不能编辑配置文件,因为WebLogic Server会周期性地重写该文件。你的更改将会丢失,也可能造成WebLogic Server失败,这取决于你的平台。

WebLogic Server配置文件是格式友好的XML文件,因此它有可能使用XML解析应用比如 Apache Xerces, or JDOM来使某个重复性的变更脚本实现。

确保完整测试所创建的脚本,在作变更之前对每一个配置文件作备份性拷贝。

辅助配置文件

在原版本中,config.xml文件存放了所有配置信息。新版本中,几个WebLogic Server子系统被配置在辅助配置文件中,由核心的config.xml来引用。这些辅助配置文件位于/domains/domain_name/config目录的子目录中。关于辅助配置文件的更多信息,参见“域目录概览”和“域目录内容”。

配置文件压缩包

WebLogic Server对配置文件作备份拷贝。万一配置变更需要推倒重来或者配置文件被破坏(当然这种情况不太可能),这使得恢复很容易。当管理服务器启动时,它将配置文件保存在一个命名为config-booted.jar的JAR文件中。当你变更配置文件时,旧文件以JAR文件的形式保存在域目录下的configArchive目录中,命名带数字序列,比如config-1.jar。

域目录概览

图4-1是域目录树型结构的概览。 domain-name 、deployment-name和server-name目录名称不是字面所示,实际上替换成任何指定的名称都是可以的;其他的目录名称则是字面所示。概览只显示目录,不含目录内的文件。任何实际的特定域目录树,整个结构都可能不会是这样。



域目录内容




本节描述域目录和子目录的内容,以斜体表示的目录名称不是实际的名称,而是要以适当的具体名称来替代,非斜体的名称则是字面上所示的名称。

domain-name

该目录的名称为域的名称。




applications




该目录提供了一种在部署服务器上部署应用的快速方式。当Weblogic Server实例以开发模式运行时,它会自动部署你放置在该目录的任何应用与模块。




你放置在目录的文件可以是:

一个J2EE应用

一个EAR文件

一个WAR、EJB JAR、RAR或者CAR的压缩模块

一个应用或者一个模块的解压目录

bin

该目录包括了一些用来启动或终止域中的管理服务器和托管服务器进程的脚本。它也可以包括一些其他广义上的域脚本,比如启动和终止数据库管理系统、全文检索引擎进程等的脚本。更多信息,参见管理server启动和终止。




config

该目录包含域的当前配置和部署状态,核心域配置文件config.xml即位于本目录中。




config/deployments

保存域部署应用的目录。

config/deployments/library_modules

保存类库模块的目录,也就是说,该目录中的任何文件都将以类库模块自动注册。

config/deployments/deployment-name-1

该目录包含一个应用或者可发布的模块。它所含的子级目录可以包含一个压缩文件(EAR或WAR),一个部署清单,扩展描述符等等。

config/diagnostics

该目录包含WebLogic诊断服务(WebLogic Diagnostic Service)系统模块。更多信息,参见“理解WebLogic诊断服务”。

config/jdbc

该目录包含JDBC系统模块:所有JDBC模块都可以通过JMX直接配置(和JSR-88不同)。更多信息,参见“数据库连接(JDBC)”。

config/jms

该目录包含JMS系统模块:所有JMS模块都可以通过JMX直接配置。更多信息,参见“消息与数据库连接(JDBC)”。

config/nodemanager

该目录保存与节点管理器连接的的配置信息。更多信息,参见“设计与配置WebLogic Server环境”中的“使用节点管理器管理服务”。

config/security

该目录包含安全框架系统模块。包含了当前域的每一种安全供应器的安全供应器配置扩展。更多信息,参见理解“WebLogic 安全”。

config/startup

该目录包含含启动计划的系统模块。启动计划被用来生成shell脚本,作为server启动的一部分。

configArchive

该目录包含一组用于保存域配置状态的JAR文件。在未决的配置变更激活前,域的当前配置状态,包括config.xml文件和其他相关文件,保存在带版本号的JAR文件中,命名成config.jar#1,config.jar#2等等。

带版本号的JAR文件的最大数量由DomainMBean的archiveConfigurationCount属性指定。一旦达到最大数,在新版本创建之前删除最旧的版本。

lib

放置在该目录中的任何JAR文件在sever的Java虚拟机启动时都会添加至域中每一个server实例的系统classpath。

pending

该目录包含的域配置文件表示已请求,但还没有激活的配置变更。一旦配置变更被激活,该目录中的配置文件将被删除。更多信息,参见“管理配置变更”。

security

该目录保存的安全相关文件对于域中的每一个WebLogic Server实例来说都是相同的。

SerializedSystemIni.dat

该目录还保存只有域管理服务器需要的安全相关文件:

DefaultAuthorizerInit.ldift

DefaultAuthenticatorInit.ldift

DefaultRoleMapperInit.ldift

更多信息,参见“理解WebLogic安全”。

servers

该目录为域中每一个WebLogic Server实例设置一个子目录。

servers/server-name

该目录为server目录,名称和WebLogic Server实例的名称相同。

servers/server-name/bin

该目录存放可执行的或shell文件,对于不同的server可能会不同。server环境脚本(setServerEnv.sh或setServerEnv.cmd)是位于此处的一个文件示例,因为它能区分一个WebLogic Server实例与下一个实例的不同,这取决于server实例是否有自己的启动计划。

servers/server-name/cache

该目录存放包含缓存数据的目录和文件。这里“缓存(cached)”表示该数据是其他数据的拷贝,可能是进程中的形式(已编译,已翻译或重新格式化的)。

servers/server-name/cache/EJBCompilerCache

该目录为已编译的EJB缓存。

servers/server-name/data

和临时的、缓存的或者历史信息相反,该目录存放的文件维护持久化的预服务状态,而不是安全状态,用于运行WebLogic Server实例。该目录中的文件非常重要,必须存在于WebLogic Server实例开始,停止,崩溃,重启或升级至新版本的整个过程中。

servers/server-name/data/ldap

该目录存放内嵌的LDAP数据库。WebLogic Server实例的运行时安全状态持久化于该目录。

servers/server-name/data/store

该目录存放JMS持久化存储。对于每一个持久化存储,都有一个子目录存放表示持久化存储的文件。子目录的名称为持久化存储的名称。照例有一个存储命名为default。

servers/server-name/logs

该目录存放日志和诊断信息。实际上只是一些历史信息,对于server的运行并非至关重要,可以删除(不过至少WebLogic Server实例应该终止)而不影响正确的运行。然而,这些信息对于调试和检查相当有用,如果没有好的理由不应当删除。

servers/server-name/logs/diagnostic_images

该目录存放WebLogic诊断服务(WebLogic Diagnostic Service)的Server图片捕获器(Server Image Capture)组件创建的信息。更多信息,参见“理解WebLogic诊断服务”。

servers/server-name/logs/jmsServers

该目录为WebLogic Server实例中的每一个JMS服务提供一个子目录。每一个那样的子目录包含JMS服务的日志。子目录的名称为JMS服务的名称。

servers/server-name/logs/connector

该目录是连接器模块(JCA资源适配器)日志的默认基目录。

servers/server-name/security

该目录存放安全相关文件,每一个WebLogic Server实例都可能不同。文件boot.properties是位于此处的一个文件示例,因为它能区分一个server实例与下一个实例的不同。该目录还维护与SSL key相关的文件。

servers/server-name/tmp

该目录存放server实例运行时创建的临时目录与文件。server运行时该目录中的文件应当保留,但可以在server实例终止后随意删除。




第五章 管理配置变更

为了提供一个安全、可预期的方式来分发域的配置变更,WebLogic Server采用了大致类似于数据库事务的变更管理进程。域的配置在文件系统中表示为一组XML配置文件,核心为config.xml文件,在运行时表示为配置MBean(Configuration MBeans)树。当你编辑域配置时,你实际上编辑的是分离的管理服务器的配置MBeans树。要开始编辑过程,你应获得编辑树的锁以阻止其他人进行变更。完成变更后,保存变更。不过变更不会生效直到你激活它们,分发给域中的所有server实例。激活变更后,每一个server都决定是否接受变更。如果所有server都可以接受该变更,则更新运行着的配置层,变更完成。




注意WebLogic Server的变更管理过程适用于域的变更和server配置数据,不适用于安全或应用数据。

关于如何通过JMX和配置MBean来实现配置变更的更多详细信息,参见“使用JMX开发可管理的应用”中的“理解WebLogic Server MBeans”

如第三章“使用WebLogic工具配置域”中的描述,你可以使用一系列不同的WebLogic Server工具进行配置变更:

管理控制台

WebLogic 脚本工具

JMX API

无论你使用哪一个工具进行配置变更,WebLogic Server都采用大体相同的方式来处理变更过程。

以下章节描述配置变更管理:

管理控制台的变更管理

配置变更管理过程

配置管理状态图

管理控制台的变更管理

WebLogic管理控制台将配置变更管理过程集中于Change Center:



如果你想使用管理控制台进行配置变更,你必须先点击Change Center中的Lock & Edit(锁定并编辑)按钮。当你点击Lock & Edit后,你会获得域中所有server的配置MBean的可编辑层(编辑树)的锁。

在你使用管理控制台进行配置变更后,在适当的页面点击Save(保存)(某些情况下为Finish(完成)),这些不会使变更立即生效,而是在你点击Save时,将变更保存至编辑树,domain-name/pending/config.xml文件和相关的配置文件。只有在你点击Change Center的Activate Changes(激活变更)时变更才会生效,此时,配置变更分发至域中的每一个server。只有每一个server都接受该变更,变更才会生效。如果有任何server不接受该变更,那么域中的所有server的所有变更全部回滚。变更保持为未决状态,你既可以编辑该未决变更以解决问题或者恢复未决变更。

配置变更管理过程

以下步骤详细描述该过程,从你首先导入域的管理服务器开始:

1.服务器启动时读取域配置文件,包括config.xml文件和config.xml文件涉及的所有附属配置文件,使用这些数据对随后的MBean树进行实例化:

–一个配置 MBean的只读树包含管理服务器的当前资源配置。

–域中所有服务器的所有配置 MBean的可编辑树。

注意:管理服务器也会实例化一个运行时MBean树和一个域运行时MBean树,但是这些不用于配置管理。

2. 按以下步骤开始配置变更:

a. 获得当前配置锁。

b. 使用你选择的工具(管理控制台,WLST,JMX API等),按你的要求变更。

c. 将变更保存至config.xml文件的未决版本。

3. 配置管理器服务将来自编辑MBean树的所有数据保存成一份独立的配置文件,目录名为pending。参见图5-2。

pending目录直接位于域的根目录下。比如说,如果你的域命名为mydomain,那么未决的config.xml文件的默认路径名为mydomain/pending/config.xml。



4. 进行其它变更或者取消已做出的变更。

5. 当你准备激活域的变更时,使用管理控制台Change Center的Activate Changes按钮或者使用ConfigurationManagerMBean。

激活变更(参见图 5-3):

a. 对于域的每一个server实例,配置管理器服务将未决配置文件拷贝至server的根目录下的pending目录。

如果托管服务器和管理服务器共享根目录,ConfigurationManagerMBean不必拷贝未决的配置文件,托管服务器直接使用管理服务器的未决文件。

b. 每一个server实例将它的当前配置和未决文件中的配置进行比较。

c. 每一个server内部的子系统将对自身是否能接受新配置进行投票。

只有要任一子系统表示它不能接受该变更,整个的激活过程将回滚,ConfigurationManagerMBean抛出异常。你可以修改变更,再次进行变更激活,或者放弃锁,编辑配置MBean树和未决配置文件恢复至只读配置MBean树和配置文件的配置。

d. 如果所有server的所有子系统都能接受该变更,配置管理器服务将域的每一个server实例的只读配置文件替换成未决配置文件。

e. 每一个server实例都会更新bean和只读配置MBean树以和新的配置文件的变更保持一致。

f. 然后未决配置文件从pending目录中删除。

6. 你可以保持锁以进行其它的变更或者释放锁以使其他人可以更新配置。你也可以设置超时时限使配置管理器服务放弃锁。

注意:配置变更锁不会防止你在使用相同的管理员账号造成的配置编辑冲突。比如,如果你使用管理控制台获得配置变更锁,然后以相同的用户帐号使用WebLogic脚本工具,你将访问的是在管理控制台中打开的相同的编辑会话,你不会因为使用脚本工具而被锁定。由于这可能造成配置变更的混乱和冲突,这不是一种受推荐的手段。你应该通过为每一个管理员身份的用户维护一个独立的管理员账号来减少发生这种情况是造成的风险。不过如果你有使用相同的用户帐号的多个相同脚本实例,相同的问题仍然会发生,



处理变更冲突

这种情况,你保存的多个变更没有被激活,某个变更会使前一个变更无效,变更管理器服务需要你在保存变更前手动解决该无效问题。




配置管理状态图




配置管理服务遵循图 5-4中描述的状态转换。

 

posted @ 2009-11-25 22:17 小菜毛毛 阅读(2672) | 评论 (0)编辑 收藏

SVN客户端用户使用手册(完整版)
该文档将逐步教您如何在软件开发过程中使用svn客户端
环境模拟
现有项目名称:test
服务端版本库:test
URL:http://10.155.11.10:81/svn
开发人员:devA,devB
版本库目录结构:
 
一.基本操作
第一步:安装客户端
到共享文件夹下,下载TortoiseSVN-1.4.0.7501-win32-svn-1.4.0.msi安装程序,双击直接安装即可。安装成功后,右键单击鼠标会多出两个选项,分别是SVN checkout和Tortoise SVN。
第二步:建立工作区
项目开始之前,在本地PC的硬盘上,创建一个文件夹,文件夹命名随意(例如workspace
),该文件夹即作为软件开发者在项目开发过程中的工作区。
第三步:下载版本库
    假如现在开发一个项目,配置管理员会在服务端建立一个该项目的版本库test
在workspace文件夹上,右键单击鼠标。选择SVN checkout,会出现如下窗口
 
在URL of repository中输入版本库地址,http://10.155.11.10:81/svn/test ,在Checkout dir中系统会自动添加第二步所创建的工作区目录。
在Revision中,选中HEAD revision,这样将会下载到版本库的最新版本。如果想下载库中的旧版本文件,可选中Revision,然后填入版本号即可。
如果不想下载整个版本库,而是只想下载自己负责的那部分模块,可以在URL后添加模块名,例如http://10.155.11.10:81/svn/test/Doc 。
单击OK,输入用户名和密码
第四步:修改版本库
对版本库的修改包括修改文件内容,添加删除文件,添加删除目录。
经过第三步的操作,本地的工作区文件夹,即workspace上会有绿色对勾出现,工作区下的文件也会带有绿色对勾,如图2
 
如果对库中某一个文件进行了修改,系统会自动为这个文件和这个文件所在的各级父文件夹加上红色叹号,代表该文件或目录已经在本地被修改,如图3
 
图3
当所有对版本库的修改操作完毕后,右键单击工作区文件夹,选择commit提交新版本,输入密码后系统将把修改后的版本库上传到服务端,即完成一次对版本库的更新。
注意:
新版本提交之后,其他拥有写权限的用户也许会重复以上几步的操作,完成对版本库的再一次更新。所以,每次在工作区文件夹下修改本地版本库之前,必须首先对本地版本库执行一次更新(右键单击工作区,选择SVN Updata),将最新的版本下载到本地,然后再进行修改操作。
二.其他操作
在日常的软件开发过程中,除了以上介绍的下载,提交,更新操作外,还有另外几种常用操作。
(1)比较文件的不同之处
当对soc_1做了修改之后,soc_1文件会出现红色叹号,表示已经修改,如果想查看修改后的soc_1文件与修改前有何不同,可以右键单击此文件,选择diff,系统探出一个窗口,如图3,窗口分为两个部分,左边为更改之前的版本,右边为更改之后的版本。并在不同之处作出标记和说明。如图4

如果是word文档的话,选择diff之后,系统会打开一个word文档,并在其中标出修改后的版本与修改前有何不同。如图4.1

(2)查看日志
如果想查看一个文件的日志,例如soc_1,右键单击这个文件,选择show log,系统会踏出一个窗口,并在窗口中显示soc_1各个版本的log。如图4

图5
(3)查看版本树
如果想查看soc_1文件的版本树,右键单击该文件,选择Revision graph,系统将会打开一个窗口,并在窗口中显示该文件的版本树。如图6。

   之所以只显示了4.5.6.7四个版本,是因为选择了只显示发生过变化的版本。即1.4.5.6.7每一个版本都有不同的地方,都是经过用户修改后提交的。而2.3两个版本是与版本1相同的。
(4)下载某个文件的旧版本
如果想要得到某个文件的旧版本,只需在该文件上单击右键,选择Updata to revision…即可。系统会提示输入版本号。例如要下载soc_1的第五个版本,只需填入5即可。如图7。查看完版本5的文件后,如果想在此回到最新版本,只需要对soc_1运行Updata即可。
 
(5)重名名和删除文件
如果要删除一个文件或重名名一个文件,
注意不要在windows下直接操作。只需右键单击该文件,选择Rename或Delete,svn系统便会完成操作。
在workspace中将文件重命名或删除后,服务端的文件结构不会变化,只有当提交新版本库后,即commit后,服务端的文件结构才会被更新。
如果误删除了文件,在没有提交版本库之前,可以通过对版本库的升级将文件重新下载到本地的版本库,也可以通过revert恢复(参考第八条)。如果文件删除,并且已经提交,那么要找回文件只能通过下载旧版本库来完成,参考(4)。
(6)创建分支
版本库中最初的文件soc_1,soc_2,word_1,word_2都是主干文件。如果想要为soc_1创建一个分支,只需右键单击soc_1,选择Branch/Tag,系统会弹出一个窗口,如图8。在窗口中,From URL表示要创建的这个分支是soc_1的分支(系统会自动添加,不必更改)。在To URL中,需要更改一下文件名,在文件名后加一个标志即可,例如“
_branch”,路径不需要更改。在Creat copy in the repository from中,可以选择分支文件是由soc_1的那一个版本拷贝来的。最后填写日志,选择OK。

分支创建完毕,Updata版本库,系统会将soc_1的主干文件和分支文件soc_1_branch同时下载到本地版本库,如图8.1,然后即可在分支文件上进行操作。此时soc_1的版本树如图8.2
 
(7)合并分支
当需要把soc_1_branc分支文件合并到soc_1主干文件时,右键单击soc_1,选择Merge,会弹出一个窗口,如图9。

在 From输入框中填入主干的URL,在To输入框中填入分支的URL。在From和To中,都有两个选项HEAD Revision和Revision,表示要进行合并的是soc_1的那个版本。合并之后主干文件会标注红色叹号,表示已被修改,并可以提交。如果合并后文件标注的是黄色叹号,表示文件有冲突,处理方法见第三部分“异常处理”。
(8)撤销修改
当对一个文件进行了修改并保存后(注意此处并没有进行提交),如果对修改不满意,想要重新修改,可以右键单击修改过的文件(带红色叹号的那个),然后选择revert,前面的一系列修改便会被撤销,恢复到Updata之后的状态。如果一个文件被误删除,也可通过右键单击该文件所在的目录,选择revert来恢复。
三.异常处理
此处所说的异常主要是指文件发生冲突。以用户devA和用户devB为例,
当两个用户同时下载了最新的版本库,并对库中同一个文件soc_2进行修改提交时,首先提交的用户devA不会发生异常,第二个提交的用户
devB便会出现无法提交的现象。因为服务端的版本库已经被devA更新,devB用户在上传时,系统会提示出错如图10。

在这种情况下,devB用户需要首先对修改的文件进行Updata文件操作。如果两个用户修改了文件soc_2的同一个地方,则在devB用户执行Updata后,系统会将本地的soc_2与从服务端下载soc_2合并到一个文件上,并在该文件图标上标上黄色叹号,表示文件出冲突。在文件中通过“<<<<<<”和“>>>>>>”标识冲突位置和冲突内容。devB用户只有与devA协商,将该冲突处理,之后单击右键,选择Resolve,冲突标记消除,才能够再次提交,否则无法提交。
文件标记冲突的格式:
<<<<<<< .mine
    workspsace工作区,等abc工作区提交结束后再提交,应该会出现冲突

=======
   在此插入一段话,啊啊aaa,测试冲突
>>>>>>> .r15
绿色部分表示本地文件的修改
蓝色部分表示服务端版本库中的最新版本与本地文件修改发生冲突的地方。
紫色表示是第15个版本发生了冲突
=======
   在此插入一段话,啊啊aaa,测试冲突
>>>>>>> .r15
绿色部分表示本地文件的修改
蓝色部分表示服务端版本库中的最新版本与本地文件修改发生冲突的地方。
紫色表示是第15个版本发生了冲突
文章来自[SVN中文技术网]转发请保留本站地址:http://www.svn8.com/svnzixun/20090413/4578.html

posted @ 2009-11-24 11:38 小菜毛毛 阅读(636) | 评论 (0)编辑 收藏

仅列出标题
共17页: First 上一页 8 9 10 11 12 13 14 15 16 下一页 Last