﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-飞艳小屋-文章分类-java服务器相关</title><link>http://www.blogjava.net/songfei/category/12166.html</link><description>程序--人生--哲学___________________欢迎艳儿的加入</description><language>zh-cn</language><lastBuildDate>Sat, 28 Apr 2007 04:54:01 GMT</lastBuildDate><pubDate>Sat, 28 Apr 2007 04:54:01 GMT</pubDate><ttl>60</ttl><item><title>配置WebLogic Server集群</title><link>http://www.blogjava.net/songfei/articles/113536.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Wed, 25 Apr 2007 06:58:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/113536.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/113536.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/113536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/113536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/113536.html</trackback:ping><description><![CDATA[<div class=post>
<div class=postText>
<div align=center>&nbsp;</div>
<div align=center><strong><span style="FONT-SIZE: 26pt">配置</span></strong><strong><span style="FONT-SIZE: 26pt">WebLogic Server</span></strong><strong><span style="FONT-SIZE: 26pt">集群</span></strong></div>
<div align=left>下面为网上文章.现总结一下自己配置时遇到的一些问题的解决方案:<br><br>1.集群的概念是这样的,先建立管理服务器,跟据下面的图就可以建起来.这个不难,接下来就是建立受理服务器,受理服务器可以建立一到多台,也可以跟据下面的图建立起来,不管是远程的还是本地的都可以建起来.接下来就是启动管理服务器了,这个不难,再就是启动代理服务器了,这个比较难理解.在启动代理服务器以前先讲二点,一就是管理服务器启动以后不能部署应用程序(我是这么理解的,不确定)要想部署应用就一定得建一个代理服务器,不管是在一台机子上还是在多台电脑上,都行.二启动了管理服务器就可以进入控制台,在控制台上可以新建受理服务器,如果要在管理服务器上建受理服务器就可以直接部署应用了.如果是别的计算机上面则还没试,`接下来就是代理服务器的启动,启动的domain文件我是从服务器上拷贝过来.启动是在运行打上CMD也就是在dos控制台下输入.D:\bea\user_projects\domains\base_domain\bin&gt;下启动startManagedWebLogic.cmd文件,后面带上 你在管理服务器上看到的代理的名称默认情况下为server-0,接着再打入<a href="http://192.168.0.131:7001/">http://192.168.0.131:7001</a>就可以看到启动了.</div>
<div align=center>（本文讲述如何在<span>WebLogic Server 8.1上配置集群，以及通过Proxy Server来访问集群）</span></div>
<div align=center>&nbsp;</div>
<div><strong><font size=6>预备知识</font></strong></div>
<div><strong><font size=6></font></strong></div>
<div><strong><font size=5>什么是Domain和Server</font></strong></div>
<div><strong><font size=5></font></strong></div>
<div><strong><font size=4>Domain</font></strong></div>
<div style="TEXT-INDENT: 21pt">Domain是WebLogic Server实例的基本管理单元。所谓Domain就是，由配置为Administrator Server的WebLogic Server实例管理的逻辑单元，这个单元是有所有相关资源的集合。</div>
<div style="TEXT-INDENT: 21pt"></div>
<div><strong><font size=4>Server</font></strong></div>
<div style="TEXT-INDENT: 21pt">Server是一个相对独立的，为实现某些特定功能而结合在一起的单元。</div>
<div style="TEXT-INDENT: 21pt"></div>
<div><strong><font size=5>Domain and Server的关系</font></strong></div>
<div style="TEXT-INDENT: 21pt">一个Domain 可以包含一个或多个WebLogic Server实例，甚至是Server集群。一个Domain中有一个且只能有一个Server 担任管理Server的功能，其它的Server具体实现一个特定的逻辑功能。</div>
<div style="TEXT-INDENT: 21pt"></div>
<div><strong><font size=6>本文环境</font></strong></div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>平台：Windows 2000</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>软件：Bea WebLogic Server 8.1 SP2</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"></div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"></div>
<div><strong><font size=6>配置WebLogic Server集群</font></strong></div>
<div><strong><font size=6></font></strong></div>
<div><strong><font size=5>WebLogic集群的体系结构</font></strong></div>
<div><strong><font size=5></font></strong></div>
<div><strong><font size=4>单层混合型的集群架构（Cluster）</font></strong></div>
<div style="TEXT-INDENT: 21pt">这种架构将所有的Web应用以及相关的服务应用全部置于集群中的单一WLS实例中，这种架构的优势在于：</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>易于管理</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>灵活的负载平衡机制</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>更强的安全控制</div>
<div align=center><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/134951062d284066846d426790d46552.jpg"></div>
<div><strong><font size=4>多层结构的集群架构（Cluster）</font></strong></div>
<div style="TEXT-INDENT: 21pt">这种架构使用两个WLS集群，一个放置表静态内容和集群Servlet，另一个放置集群EJB。一般应用于下面这些情况：</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>在负载平衡机制需要调用集群EJB中的方法时；</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>在提供内容与提供对象的服务之间需要更大的机动性时；</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>在需要更高的系统稳定性时；</div>
<div align=center><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/a50902c784ed4d6fb184364792e46f04.jpg"></div>
<div><strong><font size=5>配置集群应用的必要条件</font></strong></div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>集群中的所有Server必须位于同一网段，并且必须是IP广播(UDP)可到达的</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>集群中的所有Server必须使用相同的版本,包括Service Pack</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>集群中的Server必须使用永久的静态IP地址。动态IP地址分配不能用于集群环境。如果服务器位于防火墙后面，而客户机位于防火墙外面，那么服务器必须有公共的静态IP地址，只有这样，客户端才能访问服务器</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>要以CLUSTER方式运行，必须有包含CLUSTER许可的LICENSE才行（从Bea网站上下载的试用版本就可以进行Cluster配置）</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"></div>
<div><strong><font size=5>配置前的准备工作</font></strong></div>
<div style="TEXT-INDENT: 21pt">在配置集群应用前要对集群的配置信息有一个良好的设计，下面就是我们这次配置的集群信息：</div>
<div style="TEXT-INDENT: 21pt">在同一台机器上配置集群</div>
<div align=center>
<table style="WIDTH: 95%" cellSpacing=1 cellPadding=0 width="95%" border=1>
    <tbody>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">机器类型</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">操作系统</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">硬件配置</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">角色</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">备注</span></div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Professional</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.33</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:7080</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Administrator Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Professional</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.33</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:8080</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Proxy Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Professional</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.33</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:7082</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Managed Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Professional</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.33</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:7084</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Managed Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Professional</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.33</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:7086</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Managed Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div style="TEXT-INDENT: 21pt">在同一网段内的不同机器上配置集群</div>
<div align=center>
<table style="WIDTH: 95%" cellSpacing=1 cellPadding=0 width="95%" border=1>
    <tbody>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">机器类型</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">操作系统</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">硬件配置</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">角色</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; BACKGROUND: rgb(223,223,223) 0% 50%; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
            <div style="LINE-HEIGHT: 160%" align=center><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">备注</span></div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.7</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:7080</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Administrator Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.7</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:8080</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Proxy Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.7</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:7082</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Managed Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">DELL PC</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Win2000 Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">IP:</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">10.16.92.33</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">PORT</span><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">:7084</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left><span style="FONT-SIZE: 9pt; COLOR: rgb(51,51,51); LINE-HEIGHT: 160%">Managed Server</span></div>
            </td>
            <td style="PADDING-RIGHT: 1.5pt; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; PADDING-TOP: 1.5pt">
            <div style="LINE-HEIGHT: 160%" align=left>&nbsp;</div>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div><strong><font size=5></font></strong></div>
<div><strong><font size=5>使用Domain Configuration Wizard进行配置</font></strong></div>
<div><strong><font size=4>创建新的Domain</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>选择&#8220;Create a new WebLogic configuration&#8221;，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/64aea1f2be934f5db866cb52d7923962.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>选择安装类型</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>选择安装&#8220;Basic WebLogic Server Domain&#8221;，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/d0d03fb3fcb549b38ad44fdc13fb2821.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>选择定制安装</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>选择&#8220;Custom&#8221;安装，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/2b1f84302afd4485aad47700749082f5.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>输入Administrator Server的信息</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>输入Administrator Server的名称，监听地址，监听端口，如果需要SSL支持的话可以在&#8220;SSL enabled&#8221;后面的复选取框上打勾，配置SSL监听端口，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/da90cda687e446678c907badfb25cc7c.jpg"></div>
<div>&nbsp;</div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>是否配置Server、Cluster、Machine信息</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>选择&#8220;Yes&#8221;，对Server、Cluster、Machine信息进行配置，，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/3a49cff0056243ffb211e7cac07c6ff4.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置Managed Server信息</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>输入Managed Server的名称，监听地址，监听端口，如果需要SSL支持的话，可以在&#8220;SSL enabled&#8221;复选框上打勾，配置SSL监听端口。可以配置多个Managed Server。单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/88c9098fb2404999b11f6f48c018c4b5.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置Cluster信息</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>输入Cluster的名称，Cluster的组播地址和端口，Cluster地址可输可不输。单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/cb176dbf78754dfcb357b05a38e32e20.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>将Managed Server添加到Cluster中</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>选择左面列表中的Managed Server，将其添加到右面的列表中，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/e2a1ec4d1e91413395ff653064a28f37.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置Machine信息</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在此不对Machine进行配置，单击&#8220;Next&#8221;按钮</div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>是否配置JDBC信息</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在此不对JDBC数据源和连接池进行配置，单击&#8220;Next&#8221;按钮</div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置JMS信息</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在此不对JMS进行配置，单击&#8220;Next&#8221;按钮</div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置缺省系统管理员用户名和密码</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>输入系统管理员用户名和密码，还可以配置其它的系统管理用户，在此不做配置，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/3c9d48f873c54a6d85c0ddcba7beb2e8.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置Windows附加选项</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>可以选择是否创建开始菜单中的快捷方式，是否将该服务作为Windows系统服务，在这里我们全部选择&#8220;No&#8221;，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/97b8f10b7e61494e9026f1d9d7857e1a.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置服务的启动模式并选择Java SDK</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>选择&#8220;Development Mode&#8221;模式，并选择标准的Java SDK 1.4，在开发模式下会有比较丰富的调试信息，对我们很有帮助，单击&#8220;Next&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/6e175bc67f6e4b48bcc345d66e1f1c0c.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>配置信息确认以及选择安装路径</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>系统列出您的配置信息，并指定了缺省的安装路径（D:\bea\user_projects\domains\mydomain），在此我们将安装路径定位在D:\bea\user_projects\clusterdomain，单击&#8220;Create&#8221;按钮</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/c818fbb545334ed281f9027a58e1a840.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>系统创建Domain</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>系统根据配置信息，完成缺省的目录及文件的创建</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/adf77010392241afa15f7b4270bee1f7.jpg"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>启动WebLogic服务</font></strong></div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>启动Administrator Server</div>
<div style="MARGIN-LEFT: 21pt">使用startWebLogic命令启动Administrator Server</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/82d8fbc10e6b4b66921da72e58be17b6.jpg"></div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>启动Managed Server</div>
<div style="MARGIN-LEFT: 21pt">使用startManagedWeblogic命令启动Managed Server，它的命令格式是：</div>
<div style="MARGIN-LEFT: 21pt"><span style="COLOR: blue">startManagedWeblogic.cmd</span> <span style="COLOR: red">Managed Server</span><span style="COLOR: red">的名称</span> <span style="COLOR: green">Administrator Server</span><span style="COLOR: green">地址</span></div>
<div style="MARGIN-LEFT: 21pt">同理可以启动nodeB和nodeC，以及Proxy Server</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/d9e0c6415b784f9996bad26e1a7d713d.jpg"></div>
<div><strong><font size=5></font></strong></div>
<div><strong><font size=5>通过HttpClusterServlet实现请求的自动分发处理</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpClusterServlet</span>通过一个WebLogic服务器代理对WebLogic集群中的其他服务器成员的HTTP请求， 同时HttpClusterServlet还为代理的HTTP请求提供负载平衡与容错处理。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>实际上实现是很简单的，遵循下面几个步骤就可以轻松实现请求的自动分发功能：</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>创建一个代理Server（在此我们称这proxyServer）</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>生成配置文件web.xml</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>生成配置文件weblogic.xml</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>打包生成Web应用</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>在proxyServer上部署应用，并将该应用作为缺省的Web应用</div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>创建代理Server</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>启动Administrator Server，然后进入Console控制台（http://10.16.92.33:7080/console/），在此我们将代理Server与Administrator Server置于同一台主机之上。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>进入console控制台后，在&#8220;Server&#8221;结点上单击右键，在弹出菜单上选择&#8220;Configure a New Server&#8221;，然后配置代理Server的相关信息。（在这里只要指定名称，监听地址，监听端口就可以了）</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/f5d75f0bb88742c9ad756268d88d65ea.jpg"></div>
<div>&nbsp;</div>
<div style="TEXT-INDENT: 21pt"></div>
<div style="TEXT-INDENT: 21pt">HttpClusterServlet 的部署，主要是Servlet的声明和映射，并设置初始化参数，可以创建一个Web App，然后直接在web.xml中添加或在管理控制台上设置HttpClusterServlet的部署信息。最后将它发布给用来做代理的 Server，并将这个Web App设置为这个Server的缺省WEB应用。</div>
<div><strong><font size=4>web.xml文件示例</font></strong></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/30f21cbac468435aaabf87397b4b4cfd.png"></div>
<div><strong><font size=4>weblogic.xml文件示例</font></strong></div>
<div></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/4388e3f09f7f4d178307c4002021ab2d.png"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>打包WEB应用</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>可以使用jar命令将proxy应用打包成war文件，我们建一个临时目录temp，然后在其中建立如下目录结构：</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/c3e21f41b79c472c8b02e845ed85d746.png"></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>使用如下的命令操作，就可完成web应用的打包操作：</div>
<div style="TEXT-INDENT: 21pt"><span style="COLOR: blue">JAR &#8211;</span><span style="COLOR: blue">参数</span><span style="COLOR: blue"> WEB</span><span style="COLOR: blue">应用名称</span><span style="COLOR: blue">要打包的目录</span></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/11a15e176ae24ec0a22b1f8360ecd1b5.png"></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>当然我们也可以直接部署该目录，而无需打包，这在项目的开发阶段是很有帮助的，便于修改。</div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>部署proxy应用</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>启动Administrator Server，然后进入Console控制台（http://10.16.92.33:7080/console/），在此我们将代理Server与Administrator Server置于同一台主机之上。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>进入console控制台后，在&#8220;<span>Web Application Modules</span>&#8221; 结点上单击右键，在弹出菜单上选择&#8220;Deploy a new Web Application Module&#8221;，然后选择要部署的文件或目录，单击&#8220;Target Module&#8221;按钮，然后选择&#8220;proxyServer&#8221;，单击&#8220;Continue&#8221;按钮，到了下一步，单击&#8220;Deploy&#8221;按钮，完成部署工作。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>部署完成后，查看WEB应用的状态是&#8220;FAILS&#8221;，造成这种情况的原因是&#8220;proxyServer&#8221;还没有启动，我们可以通过下面的命令启动&#8220;proxyServer&#8221;：</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/f7a1738c83e14f2f9ec66996a76b71a7.png"></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>然后点击&#8220;ReDeploy&#8221;，重新部署应用，状态值将变为&#8220;Success&#8221;。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>将WEB应用配置成缺省的WEB应用，weblogic8.1与weblogic6.1有很大的不同，8.1不再支持从console控制台完成配置的工作，而是在weblogic.xml中通过下面的结点，完成配置的工作。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;context-root&gt; / &lt;/context-root&gt;</span></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/156c2fc672e7494795232115f5077e94.png"></div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/8e8a942aee7d4d53b496f22143dc0f3d.png"></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>测试proxy应用</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>修改web.xml文件，加入下面的结点，然后重启服务。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;</span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;DebugConfigInfo&lt;/param-name&gt;</span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;ON&lt;/param-value&gt;</span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</span></div>
<div style="TEXT-INDENT: 21pt">打开浏览器，访问下面的地址，会得到下图所示的结果，这就说明你的配置是成功的。</div>
<div style="MARGIN-LEFT: 21pt">http://myserver:port/placeholder.jsp? __WebLogicBridgeConfig</div>
<div style="MARGIN-LEFT: 21pt">myserver为服务地址（在这里是10.16.92.7）</div>
<div style="MARGIN-LEFT: 21pt">port为proxy服务的端口（在这里是8080）</div>
<div style="MARGIN-LEFT: 21pt">placeholder.jsp（这是一个不存在的JSP文件，您也可以随意指定文件名）</div>
<div style="MARGIN-LEFT: 21pt">__WebLogicBridgeConfig（这个可千万不能写错呦！）</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/5bdedf4a20a24fa883603865dca5c2e3.png"></div>
<div><strong><font size=5></font></strong></div>
<div><strong><font size=5>测试集群的分发功能</font></strong></div>
<div><strong><font size=4></font></strong></div>
<div><strong><font size=4>编写测试WEB应用并部署</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>我们来编写一个简单的WEB应用，它会在控制台和浏览器上同时打印出&#8220;OK&#8221;字样，然后将这个WEB应用部署到集群中所有Managed Server上面。（代码见附件）</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在这里我们将通过Apache中所带的ab包来进行并发访问的模拟测试，使用如下的命令就可以完成压力测试。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ab &#8211;n 100 &#8211;c 10 <a href="http://10.16.92.7:8080/index.jsp"><u><font color=#0000ff>http://10.16.92.7:8080/index.jsp</font></u></a></span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ab</span>是测试程序的名称</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>参数n代表请求的总数量</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>参数c代表并发的请求数</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url</span>为要测试压力的页面</div>
<div>注：使用这个命令时，一定要在系统路径中能够找到该程序，否则不能执行。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>压力测试完成后，我们从Managed Server的控制台上可以看到，nodeA，nodeB，nodeC都打印出了&#8220;OK&#8221;字样，这说明，在并发请求的情况下，集群能够将请求进行分发，以达到负载平衡的目的。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>测试应用的目录结构如下，部署与proxy应用的部署一样，要注意的是要将它部署在Managed Server上面。</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/9a8a016469b24cbab117b7943d189be0.png"></div>
<div><strong><font size=5></font></strong></div>
<div><strong><font size=5>同一网段内不同机器部署集群</font></strong></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在不同机器上部署集群与上面的操作有一些不同，就是在部署&#8220;Managed Server&#8221;时，要注意的是，参见下面的图解。</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/bf825f3375dd462e90114127f7ede74c.png"></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在另外一台机器上配置&#8220;Managed Server&#8221;时，要指定&#8220;Admin Server&#8221;的名称，监听地址，监听端口。</div>
<div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/e0304bac0e3042298927c0dd194d1805.png"></div>
<div><span></span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>另外要注意的是，&#8220;Managed Server&#8221;上的配置信息要与&#8220;Admin Server&#8221;中Cluster所指定的配置信息一致。</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>启动&#8220;Managed Server&#8221;的命令与上面的一样，如下所示：</div>
<div></div>
<div><img style="WIDTH: 750px; HEIGHT: 56px" height=182 alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/aqiao95/0d440d00dd0449b5b957062623dfaec4.png" width=750></div>
<div><strong><font size=5></font></strong></div>
<div><strong><font size=5>集群配置中要注意的问题</font></strong></div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>Admin Server只用于集群的管理，而不能参与集群事务。</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>&#216;<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>Web应用应该部署到集群上，文件的同步是由WebLogic来完成的。</div>
</div>
</div>
<img src ="http://www.blogjava.net/songfei/aggbug/113536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-04-25 14:58 <a href="http://www.blogjava.net/songfei/articles/113536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TOMCAT源码分析(启动框架)</title><link>http://www.blogjava.net/songfei/articles/105247.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Wed, 21 Mar 2007 05:07:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/105247.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/105247.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/105247.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/105247.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/105247.html</trackback:ping><description><![CDATA[
		<div class="cnt">
				<p>TOMCAT源码分析(启动框架)<br />前言：<br />   本文是我阅读了TOMCAT源码后的一些心得。 主要是讲解TOMCAT的系统框架， 以及启动流程。若有错漏之处，敬请批评指教！<br />建议：<br />   毕竟TOMCAT的框架还是比较复杂的， 单是从文字上理解， 是不那么容易掌握TOMCAT的框架的。 所以得实践、实践、再实践。 建议下载一份TOMCAT的源码， 调试通过， 然后单步跟踪其启动过程。 如果有不明白的地方， 再来查阅本文， 看是否能得到帮助。 我相信这样效果以及学习速度都会好很多！<br />   <br />1. Tomcat的整体框架结构<br />   Tomcat的基本框架， 分为4个层次。<br />   Top Level Elements:<br />    Server<br />    Service   <br />   Connector<br />    HTTP<br />    AJP<br />   Container<br />   Engine<br />     Host<br />   Context<br />   Component  <br />    manager<br />   logger<br />   loader<br />   pipeline<br />   valve<br />         ...<br />   站在框架的顶层的是Server和Service<br />   Server:  其实就是BackGroud程序， 在Tomcat里面的Server的用处是启动和监听服务端事件（诸如重启、关闭等命令。  在tomcat的标准配置文件：server.xml里面， 我们可以看到“&lt;Server port="8005" shutdown= "SHUTDOWN" debug="0"&gt;”这里的"SHUTDOWN"就是server在监听服务端事件的时候所使用的命令字）<br />   Service： 在tomcat里面， service是指一类问题的解决方案。  通常我们会默认使用tomcat提供的：Tomcat- Standalone 模式的service。 在这种方式下的service既给我们提供解析jsp和servlet的服务， 同时也提供给我们解析静态文本的服务。<br />   <br />   Connector: Tomcat都是在容器里面处理问题的， 而容器又到哪里去取得输入信息呢？<br />Connector就是专干这个的。 他会把从socket传递过来的数据， 封装成Request, 传递给容器来处理。<br />   通常我们会用到两种Connector,一种叫http connectoer， 用来传递http需求的。 另一种叫AJP， 在我们整合 apache与tomcat工作的时候， apache与tomcat之间就是通过这个协议来互动的。 （说到apache与tomcat的整合工作，  通常我们的目的是为了让apache 获取静态资源， 而让tomcat来解析动态的jsp或者servlet。）<br />   Container: 当http connector把需求传递给顶级的container: Engin的时候， 我们的视线就应该移动到Container这个层面来了。<br />   在Container这个层， 我们包含了3种容器： Engin, Host, Context.<br />   Engin: 收到service传递过来的需求， 处理后， 将结果返回给service( service 是通过 connector 这个媒介来和Engin互动的 ).<br />   Host: Engin收到service传递过来的需求后，不会自己处理， 而是交给合适的Host来处理。<br />Host在这里就是虚拟主机的意思， 通常我们都只会使用一个主机，既“localhost”本地机来处理。 <br />   Context: Host接到了从Host传过来的需求后， 也不会自己处理， 而是交给合适的Context来处理。 <br />   比如： &lt;<a href="http://127.0.0.1:8080/foo/index.jsp">http://127.0.0.1:8080/foo/index.jsp</a>&gt;<br />         &lt;<a href="http://127.0.1:8080/bar/index.jsp">http://127.0.1:8080/bar/index.jsp</a>&gt;<br />   前者交给foo这个Context来处理， 后者交给bar这个Context来处理。<br />   很明显吧！ context的意思其实就是一个web app的意思。<br />   我们通常都会在server.xml里面做这样的配置<br />   &lt;Context path="/foo" docBase="D:/project/foo/web" /&gt;<br />   这个context容器，就是用来干我们该干的事儿的地方的。<br />   <br />   Compenent: 接下来， 我们继续讲讲component是干什么用的。<br />   我们得先理解一下容器和组件的关系。<br />   需求被传递到了容器里面， 在合适的时候， 会传递给下一个容器处理。<br />   而容器里面又盛装着各种各样的组件， 我们可以理解为提供各种各样的增值服务。<br />   manager: 当一个容器里面装了manager组件后，这个容器就支持session管理了， 事实上在tomcat里面的session管理， 就是靠的在context里面装的manager component.<br />   logger: 当一个容器里面装了logger组件后， 这个容器里所发生的事情， 就被该组件记录下来啦！ 我们通常会在logs/ 这个目录下看见 catalina_log.time.txt 以及 localhost.time.txt 和 localhost_examples_log.time.txt。 这就是因为我们分别为：engin, host以及context (examples)这三个容器安装了logger组件， 这也是默认安装， 又叫做标配 ：）<br />   loader: loader这个组件通常只会给我们的context容器使用， loader是用来启动context以及管理这个context的classloader用的。<br />    pipline: pipeline是这样一个东西， 当一个容器决定了要把从上级传递过来的需求交给子容器的时候， 他就把这个需求放进容器的管道(pipeline)里面去。 而需求傻呼呼得在管道里面流动的时候， 就会被管道里面的各个阀门拦截下来。 比如管道里面放了两个阀门。 第一个阀门叫做“access_allow_vavle”， 也就是说需求流过来的时候，它会看这个需求是哪个IP过来的， 如果这个IP已经在黑名单里面了，  sure, 杀！ 第二个阀门叫做“defaul_access_valve”它会做例行的检查， 如果通过的话，OK， 把需求传递给当前容器的子容器。 就是通过这种方式， 需求就在各个容器里面传递，流动， 最后抵达目的地的了。<br />    valve: 就是上面所说的阀门啦。<br />   Tomcat里面大概就是这么些东西， 我们可以简单地这么理解tomcat的框架，它是一种自上而下， 容器里又包含子容器的这样一种结构。<br />2. Tomcat的启动流程<br />   这篇文章是讲tomcat怎么启动的，既然我们大体上了解了TOMCAT的框架结构了， 那么我们可以望文生意地就猜到tomcat的启动， 会先启动父容器，然后逐个启动里面的子容器。 启动每一个容器的时候， 都会启动安插在他身上的组件。 当所有的组件启动完毕， 所有的容器启动完毕的时候，  tomcat本身也就启动完毕了。<br />   顺理成章地， 我们同样可以猜到， tomcat的启动会分成两大部分， 第一步是装配工作。 第二步是启动工作。 <br />   装配工作就是为父容器装上子容器， 为各个容器安插进组件的工作。 这个地方我们会用到digester模式， 至于digester模式什么， 有什么用， 怎么工作的. 请参考 &lt;<a href="http://software.ccidnet.com/pub/article/c322_a31671_p2.html">http://software.ccidnet.com/pub/article/c322_a31671_p2.html</a>&gt;<br />   启动工作是在装配工作之后， 一旦装配成功了， 我们就只需要点燃最上面的一根导线， 整个tomcat就会被激活起来。 这就好比我们要开一辆已经装配好了的汽车的时候一样，我们只要把钥匙插进钥匙孔，一拧，汽车的引擎就会发动起来，空调就会开起来， 安全装置就会生效， 如此一来，汽车整个就发动起来了。（这个过程确实和TOMCAT的启动过程不谋而和， 让我们不得不怀疑 TOMCAT的设计者是在GE做JAVA开发的）。<br />2.1 一些有意思的名称：<br />   Catalina<br />   Tomcat<br />   Bootstrap<br />   Engin<br />   Host<br />   Context<br />   他们的意思很有意思：<br />   Catalina: 远程轰炸机<br />   Tomcat: 熊猫轰炸机 -- 轰炸机的一种（这让我想起了让国人引以为豪的熊猫手机，是不是英文可以叫做tomcat??? ， 又让我想起了另一则广告： 波导-手机中的战斗机、波音-客机中的战斗机 ）<br />   Bootstap: 引导<br />   Engin: 发动机<br />   Host: 主机，领土<br />   Context: 内容， 目标， 上下文<br />   <br />   ... 在许多许多年后， 现代人类已经灭绝。 后现代生物发现了这些单词零落零落在一块。 一个自以为聪明的家伙把这些东西翻译出来了： <br />   在地勤人员的引导(bootstrap)下， 一架轰炸架(catalina)腾空跃起， 远看是熊猫轰炸机(tomcat)， 近看还是熊猫轰炸机！ 凭借着优秀的发动机技术(engin)， 这架熊猫轰炸机飞临了敌国的领土上空(host)， 对准目标(context)投下了毁天灭地的核弹头，波~ 现代生物就这么隔屁了~<br /> <br />   综上所述， 这又不得不让人联想到GE是不是也参与了军事设备的生产呢？<br />   反对美帝国主义！ 反对美霸权主义！ 和平万岁！ 自由万岁！<br />   <br />2.2  历史就是那么惊人的相似！ tomcat的启动就是从org.apache.catalina.startup.Bootstrap这个类悍然启动的！<br />   在Bootstrap里做了两件事：<br />   1. 指定了3种类型classloader:<br />      commonLoader: common/classes、common/lib、common/endorsed<br />      catalinaLoader: server/classes、server/lib、commonLoader<br />      sharedLoader：  shared/classes、shared/lib、commonLoader<br />   2. 引导Catalina的启动。<br />      用Reflection技术调用org.apache.catalina.startup.Catalina的process方法， 并传递参数过去。<br />   <br />2.3 Catalina.java<br />   Catalina完成了几个重要的任务：<br />   1. 使用Digester技术装配tomcat各个容器与组件。<br />      1.1 装配工作的主要内容是安装各个大件。 比如server下有什么样的servcie。 Host会容纳多少个context。 Context都会使用到哪些组件等等。 <br />      1.2 同时呢， 在装配工作这一步， 还完成了mbeans的配置工作。 在这里，我简单地但不十分精确地描述一下mbean是什么，干什么用的。<br />          我们自己生成的对象， 自己管理， 天经地义！ 但是如果我们创建了对象了， 想让别人来管， 怎么办呢？ 我想至少得告诉别人我们都有什么， 以及通过什么方法可以找到  吧！ JMX技术给我们提供了一种手段。 JMX里面主要有3种东西。Mbean, agent,  connector.<br />       Mbean： 用来映射我们的对象。也许mbean就是我们创建的对象， 也许不是， 但有了它， 就可以引用到我们的对象了。<br />       Agent:  通过它， 就可以找到mbean了。<br />       Connector: 连接Agent的方式。 可以是http的， 也可以是rmi的，还可以直接通过socket。<br />      发生在tomcat 装配过程中的事情:  GlobalResourcesLifecycleListener 类的初始化会被触发：<br />         protected static Registry registry = MBeanUtils.createRegistry();  会运行<br />         MBeanUtils.createRegistry()  会依据 /org/apache/catalina/mbeans/mbeans-descriptors.xml这个配置文件创建 mbeans. Ok, 外界就有了条途径访问tomcat中的各个组件了。（有点像后门儿）<br />   2. 为top level 的server 做初始化工作。 实际上就是做通常会配置给service的两条connector.(http, ajp)<br />   3. 从server这个容器开始启动， 点燃整个tomcat.<br />   4. 为server做一个hook程序， 检测当server shutdown的时候， 关闭tomcat的各个容器用。<br />   5. 监听8005端口， 如果发送"SHUTDOWN"（默认培植下字符串）过来， 关闭8005serverSocket。<br />2.4 启动各个容器<br />   1. Server<br />      触发Server容器启动前(before_start)， 启动中(start)， 启动后(after_start)3个事件， 并运行相应的事件处理器。<br />      启动Server的子容器：Servcie. <br />   2. Service<br />      启动Service的子容器：Engin<br />      启动Connector<br />   3. Engin<br />      到了Engin这个层次，以及以下级别的容器， Tomcat就使用了比较一致的启动方式了。<br />      首先，  运行各个容器自己特有一些任务<br />      随后，  触发启动前事件<br />      立即，  设置标签，就表示该容器已经启动<br />      接着，  启动容器中的各个组件： loader, logger, manager等等<br />      再接着，启动mapping组件。（注1）<br />      紧跟着，启动子容器。<br />      接下来，启动该容器的管道(pipline)<br />      然后，  触发启动中事件<br />      最后，  触发启动后事件。<br /> <br />      Engin大致会这么做， Host大致也会这么做， Context大致还是会这么做。 那么很显然地， 我们需要在这里使用到代码复用的技术。 tomcat在处理这个问题的时候， 漂亮地使用了抽象类来处理。 ContainerBase. 最后使得这部分完成复杂功能的代码显得干净利落， 干练爽快， 实在是令人觉得叹为观止， 细细品来， 直觉如享佳珍， 另人齿颊留香， 留恋往返啊！<br />      <br />      Engin的触发启动前事件里， 会激活绑定在Engin上的唯一一个Listener：EnginConfig。<br />      这个EnginConfig类基本上没有做什么事情， 就是把EnginConfig的调试级别设置为和Engin相当。 另外就是输出几行文本， 表示Engin已经配置完毕， 并没有做什么实质性的工作。<br />      注1: mapping组件的用处是， 当一个需求将要从父容器传递到子容器的时候， 而父容器又有多个子容器的话， 那么应该选择哪个子容器来处理需求呢？ 这个由mapping 组件来定夺。<br />    <br />   4. Host<br />       同Engin一样， 也是调用ContainerBase里面的start()方法， 不过之前做了些自个儿的任务,就是往Host这个容器的通道（pipline）里面， 安装了一个叫做<br /> “org.apache.catalina.valves.ErrorReportValve”的阀门。<br />       这个阀门的用处是这样的：  需求在被Engin传递给Host后， 会继续传递给Context做具体的处理。 这里需求其实就是作为参数传递的Request, Response。 所以在context把需求处理完后， 通常会改动response。 而这个 org.apache.catalina.valves.ErrorReportValve的作用就是检察response是否包含错误， 如果有就做相应的处理。<br />   5. Context<br />       到了这里， 就终于轮到了tomcat启动中真正的重头戏，启动Context了。<br /> StandardContext.start() 这个启动Context容器的方法被StandardHost调用.<br /> 5.1 webappResources 该context所指向的具体目录<br /> 5.2 安装defaultContex, DefaultContext 就是默认Context。 如果我们在一个Host下面安装了 DefaultContext，而且defaultContext里面又安装了一个数据库连接池资源的话。 那么其他所有的在该Host下的 Context, 都可以直接使用这个数据库连接池， 而不用格外做配置了。<br />  5.3 指定Loader. 通常用默认的org.apache.catalina.loader.WebappLoader这个类。   Loader就是用来指定这个context会用到哪些类啊， 哪些jar包啊这些什么的。<br /> 5.4 指定 Manager. 通常使用默认的org.apache.catalina.session. StandardManager 。 Manager是用来管理session的。<br />     其实session的管理也很好实现。 以一种简单的session管理为例。 当需求传递过来的时候， 在Request对象里面有一个 sessionId 属性。 OK， 得到这个sessionId后， 我们就可以把它作为map的key，而value我们可以放置一个 HashMap. HashMap里边儿， 再放我们想放的东西。<br /> 5.5 postWorkDirectory (). Tomcat下面有一个work目录。 我们把临时文件都扔在那儿去。 这个步骤就是在那里创建一个目录。 一般说来会在%CATALINA_HOME%/work/Standalone\localhost\ 这个地方生成一个目录。<br />5.6  Binding thread。到了这里， 就应该发生 class Loader 互换了。 之前是看得见tomcat下面所有的class 和lib. 接下来需要看得见当前context下的class。 所以要设置contextClassLoader, 同时还要把旧的 ClassLoader记录下来，因为以后还要用的。<br />5.7  启动 Loader. 指定这个Context具体要使用哪些classes， 用到哪些jar文件。 如果reloadable设置成了true, 就会启动一个线程来监视classes的变化， 如果有变化就重新启动Context。<br />5.8  启动logger<br />5.9  触发安装在它身上的一个监听器。<br /> lifecycle.fireLifecycleEvent(START_EVENT, null); <br /> 作为监听器之一，ContextConfig会被启动. ContextConfig就是用来配置web.xml的。 比如这个Context有多少Servlet， 又有多少Filter， 就是在这里给Context装上去的。<br /> 5.9.1 defaultConfig. 每个context都得配置 tomcat/conf/web.xml 这个文件。<br /> 5.9.2 applicationConfig 配置自己的 WEB-INF/web.xml 文件<br />5.9.3 validateSecurityRoles 权限验证。 通常我们在访问/admin 或者/manager的时候，需要用户要么是 admin的要么是manager的， 才能访问。 而且我们还可以限制那些资源可以访问， 而哪些不能。 都是在这里实现的。<br />5.9.4 tldScan: 扫描一下， 需要用到哪些标签(tag lab)<br />5.10 启动 manager<br />5.11 postWelcomeFiles() 我们通常会用到的3个启动文件的名称：<br />index.html、index.htm、index.jsp 就被默认地绑在了这个context上<br /> 5.12 listenerStart 配置listener<br /> 5.13 filterStart 配置 filter<br /> 5.14 启动带有&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;的Servlet.<br />  顺序是从小到大： 1,2,3… 最后是0<br />  默认情况下， 至少会启动如下3个的Servlet: <br />  org.apache.catalina.servlets.DefaultServlet   <br />      处理静态资源的Servlet. 什么图片啊， html啊， css啊， js啊都找他<br />  org.apache.catalina.servlets.InvokerServlet<br />      处理没有做Servlet Mapping的那些Servlet.<br />  org.apache.jasper.servlet.JspServlet <br />      处理JSP文件的.<br />       5.15  标识context已经启动完毕。<br /> 走了多少个步骤啊， Context总算是启动完毕喽。<br />    OK! 走到了这里， 每个容器以及组件都启动完毕。 Tomcat终于不辞辛劳地为人民服务了！<br />3. 参考文献：<br />    &lt;<a href="http://jakarta.apache.org/tomcat/">http://jakarta.apache.org/tomcat/</a>&gt;<br />    &lt;<a href="http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html">http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html</a>&gt;<br />    <br />4. 后记<br />    这篇文章是讲解tomcat启动框架的，还有篇文章是讲解TOMCAT里面的消息处理流程的细节的。 文章内容已经写好了， 现在正在整理阶段。 相信很快就可以做出来， 大家共同研究共同进步。<br />    这篇文章是独自分析TOMCAT源码所写的， 所以一定有地方是带有个人主观色彩， 难免会有片面之处。若有不当之处敬请批评指教，这样不仅可以使刚开始研究TOMCAT的兄弟们少走弯路， 我也可以学到东西。<br />    email: <a href="mailto:sojan_java@yahoo.com.cn">sojan_java@yahoo.com.cn</a></p>
				<p>5. <a href="http://www.csdn.net/develop/article/28/28075.shtm"><font color="#800080">tomcat源码分析(消息处理)</font></a></p>
		</div>
<img src ="http://www.blogjava.net/songfei/aggbug/105247.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-03-21 13:07 <a href="http://www.blogjava.net/songfei/articles/105247.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>调用tomcat自带的连接池所要书写的代码和配置</title><link>http://www.blogjava.net/songfei/articles/105201.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Wed, 21 Mar 2007 02:54:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/105201.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/105201.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/105201.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/105201.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/105201.html</trackback:ping><description><![CDATA[tomcat里的D:\tomcat5.5.15\conf\Catalina\localhost文件夹下.写上这样的xml文件,内容如下.<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;Context<br /> docBase="工程路径\WebRoot"<br /> path="jxhealth"<br /> reloadable="true"&gt;<br /> &lt;Resource<br />  name="jdbc/oracle"<br />  auth="Container"<br />  type="javax.sql.DataSource"<br />  maxActive="20"<br />  maxIdle="10"<br />  maxWait="5000"<br />  username="test"<br />  password="test"<br />  driverClassName="oracle.jdbc.driver.OracleDriver"<br />  url="jdbc:oracle:thin:@192.168.0.80:1521:JXSMJK" /&gt;<br />&lt;/Context&gt;<br /><br />web.xml加上这样一句话.<br />&lt;!-- 需要引用的JNDI资源 --&gt;<br /> &lt;resource-ref&gt;<br />  &lt;res-ref-name&gt;jdbc/oracle&lt;/res-ref-name&gt;<br />  &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br />  &lt;res-auth&gt;Container&lt;/res-auth&gt;<br /> &lt;/resource-ref&gt;<br />java文件里这样写<br />public class DBConnection {<br /> private static String JNDI_NAME="jdbc/plantDB";<br /> <br /> public DBConnection(){ <br /> }<br /> <br /> public Connection getConnection(){ <br />  Connection cn=null; <br />  try{<br />   InitialContext initTxt=new InitialContext();<br />   //Context cTxt=(Context)initTxt.lookup("java:comp/env");<br />   //Object obj=(Object)cTxt.lookup(JNDI_NAME);<br />   //DataSource ds=(DataSource)obj;   <br />   DataSource ds=(DataSource)initTxt.lookup("java:comp/env/"+JNDI_NAME);<br />   cn=ds.getConnection();<br />   //cn.setAutoCommit(true);   <br />  }catch(Exception E){<br />   String strMsg=E.getMessage().toString();<br />   System.out.print(strMsg);<br />  }  <br />  return cn;<br /> }<br /> <br />}<img src ="http://www.blogjava.net/songfei/aggbug/105201.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-03-21 10:54 <a href="http://www.blogjava.net/songfei/articles/105201.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>连接池</title><link>http://www.blogjava.net/songfei/articles/62323.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Tue, 08 Aug 2006 03:31:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/62323.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/62323.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/62323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/62323.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/62323.html</trackback:ping><description><![CDATA[
		<table class="showinfo" style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellspacing="0" cellpadding="3" width="100%" align="center" border="0">
				<tbody>
						<tr>
								<td class="showTitle" align="middle">用连接池提高Servlet访问数据库的效率</td>
						</tr>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" align="left" border="0">
												<tbody>
														<tr>
																<td>
																		<script language="javascript" src="/ad/js/edu_left_300-300.js">
																		</script>
																</td>
														</tr>
												</tbody>
										</table>Java Servlet作为首选的服务器端数据处理技术，正在迅速取代CGI脚本。Servlet超越CGI的优势之一在于，不仅多个请求 <br />可以共享公用资源，而且还可以在不同用户请求之间保留持续数据。本文介绍一种充分发挥该特色的实用技术，即数据库连 <br />接池。 <br /><br /><br />一、实现连接池的意义 <br /><br />动态Web站点往往用数据库存储的信息生成Web页面，每一个页面请求导致一次数据库访问。连接 <br />数据库不仅要开销一定的通讯和内存资源，还必须完成用户验证、安全上下文配置这类任务，因而往往成为最为耗时的操 <br />作。当然，实际的连接时间开销千变万化，但1到2秒延迟并非不常见。如果某个基于数据库的Web应用只需建立一次初始连 <br />接，不同页面请求能够共享同一连接，就能获得显著的性能改善。 <br />Servlet是一个Java类。Servlet引擎（它可能是Web服务软件的一部分，也可能是一个独立的附加模块）在系统启动或Servlet <br />第一次被请求时将该类装入Java虚拟机并创建它的一个实例。不同用户请求由同一Servlet实例的多个独立线程处理。那些要 <br />求在不同请求之间持续有效的数据既可以用Servlet的实例变量来保存，也可以保存在独立的辅助对象中。 <br />用JDBC访问数据库首先要创建与数据库之间的连接，获得一个连接对象（Connection），由连接对象提供执行SQL语句的方法。 <br />本文介绍的数据库连接池包括一个管理类DBConnectionManager，负责提供与多个连接池对象（DBConnectionPool类）之间 <br />的接口。每一个连接池对象管理一组JDBC连接对象，每一个连接对象可以被任意数量的Servlet共享。 <br />类DBConnectionPool提供以下功能： <br /><br />1) 从连接池获取（或创建）可用连接。 <br />2) 把连接返回给连接池。 <br />3) 在系统关闭时释放所有资源，关闭所有连接。 <br /><br />此外， DBConnectionPool类还能够处理无效连接（原来登记为可用的连接，由于某种原因不再可用，如超时，通讯问题） <br />，并能够限制连接池中的连接总数不超过某个预定值。 <br />管理类DBConnectionManager用于管理多个连接池对象，它提供以下功能： <br /><br />1) 装载和注册JDBC驱动程序。 <br />2) 根据在属性文件中定义的属性创建连接池对象。 <br />3) 实现连接池名字与其实例之间的映射。 <br />4) 跟踪客户程序对连接池的引用，保证在最后一个客户程序结束时安全地关闭所有连接池。 <br /><br />本文余下部分将详细说明这两个类，最后给出一个示例演示Servlet使用连接池的一般过程。 <br /><br /><br />二、具体实现 <br /><br />DBConnectionManager.java程序清单如下： <br /><br />001 import java.io.*; <br />002 import java.sql.*; <br />003 import java.util.*; <br />004 import java.util.Date; <br />005 <br />006 /** <br />007 * 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接 <br />008 * 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例. <br />009 */ <br />010 public class DBConnectionManager { <br />011 static private DBConnectionManager instance; // 唯一实例 <br />012 static private int clients; <br />013 <br />014 private Vector drivers = new Vector(); <br />015 private PrintWriter log; <br />016 private Hashtable pools = new Hashtable(); <br />017 <br />018 /** <br />019 * 返回唯一实例.如果是第一次调用此方法,则创建实例 <br />020 * <br />021 * @return DBConnectionManager 唯一实例 <br />022 */ <br />023 static synchronized public DBConnectionManager getInstance() { <br />024 if (instance == null) { <br />025 instance = new DBConnectionManager(); <br />026 } <br />027 clients++; <br />028 return instance; <br />029 } <br />030 <br />031 /** <br />032 * 建构函数私有以防止其它对象创建本类实例 <br />033 */ <br />034 private DBConnectionManager() { <br />035 init(); <br />036 } <br />037 <br />038 /** <br />039 * 将连接对象返回给由名字指定的连接池 <br />040 * <br />041 * @param name 在属性文件中定义的连接池名字 <br />042 * @param con 连接对象 <br />043 */ <br />044 public void freeConnection(String name, Connection con) { <br />045 DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br />046 if (pool != null) { <br />047 pool.freeConnection(con); <br />048 } <br />049 } <br />050 <br />051 /** <br />052 * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数 <br />053 * 限制,则创建并返回新连接 <br />054 * <br />055 * @param name 在属性文件中定义的连接池名字 <br />056 * @return Connection 可用连接或null <br />057 */ <br />058 public Connection getConnection(String name) { <br />059 DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br />060 if (pool != null) { <br />061 return pool.getConnection(); <br />062 } <br />063 return null; <br />064 } <br />065 <br />066 /** <br />067 * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制, <br />068 * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接. <br />069 * <br />070 * @param name 连接池名字 <br />071 * @param time 以毫秒计的等待时间 <br />072 * @return Connection 可用连接或null <br />073 */ <br />074 public Connection getConnection(String name, long time) { <br />075 DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br />076 if (pool != null) { <br />077 return pool.getConnection(time); <br />078 } <br />079 return null; <br />080 } <br />081 <br />082 /** <br />083 * 关闭所有连接,撤销驱动程序的注册 <br />084 */ <br />085 public synchronized void release() { <br />086 // 等待直到最后一个客户程序调用 <br />087 if (--clients != 0) { <br />088 return; <br />089 } <br />090 <br />091 Enumeration allPools = pools.elements(); <br />092 while (allPools.hasMoreElements()) { <br />093 DBConnectionPool pool = (DBConnectionPool) allPools.nextElement(); <br />094 pool.release(); <br />095 } <br />096 Enumeration allDrivers = drivers.elements(); <br />097 while (allDrivers.hasMoreElements()) { <br />098 Driver driver = (Driver) allDrivers.nextElement(); <br />099 try { <br />100 DriverManager.deregisterDriver(driver); <br />101 log("撤销JDBC驱动程序 " + driver.getClass().getName()+"的注册"); <br />102 } <br />103 catch (SQLException e) { <br />104 log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName()); <br />105 } <br />106 } <br />107 } <br />108 <br />109 /** <br />110 * 根据指定属性创建连接池实例. <br />111 * <br />112 * @param props 连接池属性 <br />113 */ <br />114 private void createPools(Properties props) { <br />115 Enumeration propNames = props.propertyNames(); <br />116 while (propNames.hasMoreElements()) { <br />117 String name = (String) propNames.nextElement(); <br />118 if (name.endsWith(".url")) { <br />119 String poolName = name.substring(0, name.lastIndexOf(".")); <br />120 String url = props.getProperty(poolName + ".url"); <br />121 if (url == null) { <br />122 log("没有为连接池" + poolName + "指定URL"); <br />123 continue; <br />124 } <br />125 String user = props.getProperty(poolName + ".user"); <br />126 String password = props.getProperty(poolName + ".password"); <br />127 String maxconn = props.getProperty(poolName + ".maxconn", "0"); <br />128 int max; <br />129 try { <br />130 max = Integer.valueOf(maxconn).intValue(); <br />131 } <br />132 catch (NumberFormatException e) { <br />133 log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolName); <br />134 max = 0; <br />135 } <br />136 DBConnectionPool pool = <br />137 new DBConnectionPool(poolName, url, user, password, max); <br />138 pools.put(poolName, pool); <br />139 log("成功创建连接池" + poolName); <br />140 } <br />141 } <br />142 } <br />143 <br />144 /** <br />145 * 读取属性完成初始化 <br />146 */ <br />147 private void init() { <br />148 InputStream is = getClass().getResourceAsStream("/db.properties"); <br />149 Properties dbProps = new Properties(); <br />150 try { <br />151 dbProps.load(is); <br />152 } <br />153 catch (Exception e) { <br />154 System.err.println("不能读取属性文件. " + <br />155 "请确保db.properties在CLASSPATH指定的路径中"); <br />156 return; <br />157 } <br />158 String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log"); <br />159 try { <br />160 log = new PrintWriter(new FileWriter(logFile, true), true); <br />161 } <br />162 catch (IOException e) { <br />163 System.err.println("无法打开日志文件: " + logFile); <br />164 log = new PrintWriter(System.err); <br />165 } <br />166 loadDrivers(dbProps); <br />167 createPools(dbProps); <br />168 } <br />169 <br />170 /** <br />171 * 装载和注册所有JDBC驱动程序 <br />172 * <br />173 * @param props 属性 <br />174 */ <br />175 private void loadDrivers(Properties props) { <br />176 String driverClasses = props.getProperty("drivers"); <br />177 StringTokenizer st = new StringTokenizer(driverClasses); <br />178 while (st.hasMoreElements()) { <br />179 String driverClassName = st.nextToken().trim(); <br />180 try { <br />181 Driver driver = (Driver) <br />182 Class.forName(driverClassName).newInstance(); <br />183 DriverManager.registerDriver(driver); <br />184 drivers.addElement(driver); <br />185 log("成功注册JDBC驱动程序" + driverClassName); <br />186 } <br />187 catch (Exception e) { <br />188 log("无法注册JDBC驱动程序: " + <br />189 driverClassName + ", 错误: " + e); <br />190 } <br />191 } <br />192 } <br />193 <br />194 /** <br />195 * 将文本信息写入日志文件 <br />196 */ <br />197 private void log(String msg) { <br />198 log.println(new Date() + ": " + msg); <br />199 } <br />200 <br />201 /** <br />202 * 将文本信息与异常写入日志文件 <br />203 */ <br />204 private void log(Throwable e, String msg) { <br />205 log.println(new Date() + ": " + msg); <br />206 e.printStackTrace(log); <br />207 } <br />208 <br />209 /** <br />210 * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最 <br />211 * 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性. <br />212 */ <br />213 class DBConnectionPool { <br />214 private int checkedOut; <br />215 private Vector freeConnections = new Vector(); <br />216 private int maxConn; <br />217 private String name; <br />218 private String password; <br />219 private String URL; <br />220 private String user; <br />221 <br />222 /** <br />223 * 创建新的连接池 <br />224 * <br />225 * @param name 连接池名字 <br />226 * @param URL 数据库的JDBC URL <br />227 * @param user 数据库帐号,或 null <br />228 * @param password 密码,或 null <br />229 * @param maxConn 此连接池允许建立的最大连接数 <br />230 */ <br />231 public DBConnectionPool(String name, String URL, String user, String password, <br />232 int maxConn) { <br />233 this.name = name; <br />234 this.URL = URL; <br />235 this.user = user; <br />236 this.password = password; <br />237 this.maxConn = maxConn; <br />238 } <br />239 <br />240 /** <br />241 * 将不再使用的连接返回给连接池 <br />242 * <br />243 * @param con 客户程序释放的连接 <br />244 */ <br />245 public synchronized void freeConnection(Connection con) { <br />246 // 将指定连接加入到向量末尾 <br />247 freeConnections.addElement(con); <br />248 checkedOut--; <br />249 notifyAll(); <br />250 } <br />251 <br />252 /** <br />253 * 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接 <br />254 * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之, <br />255 * 然后递归调用自己以尝试新的可用连接. <br />256 */ <br />257 public synchronized Connection getConnection() { <br />258 Connection con = null; <br />259 if (freeConnections.size() &gt; 0) { <br />260 // 获取向量中第一个可用连接 <br />261 con = (Connection) freeConnections.firstElement(); <br />262 freeConnections.removeElementAt(0); <br />263 try { <br />264 if (con.isClosed()) { <br />265 log("从连接池" + name+"删除一个无效连接"); <br />266 // 递归调用自己,尝试再次获取可用连接 <br />267 con = getConnection(); <br />268 } <br />269 } <br />270 catch (SQLException e) { <br />271 log("从连接池" + name+"删除一个无效连接"); <br />272 // 递归调用自己,尝试再次获取可用连接 <br />273 con = getConnection(); <br />274 } <br />275 } <br />276 else if (maxConn == 0 || checkedOut &lt; maxConn) { <br />277 con = newConnection(); <br />278 } <br />279 if (con != null) { <br />280 checkedOut++; <br />281 } <br />282 return con; <br />283 } <br />284 <br />285 /** <br />286 * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间 <br />287 * 参见前一个getConnection()方法. <br />288 * <br />289 * @param timeout 以毫秒计的等待时间限制 <br />290 */ <br />291 public synchronized Connection getConnection(long timeout) { <br />292 long startTime = new Date().getTime(); <br />293 Connection con; <br />294 while ((con = getConnection()) == null) { <br />295 try { <br />296 wait(timeout); <br />297 } <br />298 catch (InterruptedException e) {} <br />299 if ((new Date().getTime() - startTime) &gt;= timeout) { <br />300 // wait()返回的原因是超时 <br />301 return null; <br />302 } <br />303 } <br />304 return con; <br />305 } <br />306 <br />307 /** <br />308 * 关闭所有连接 <br />309 */ <br />310 public synchronized void release() { <br />311 Enumeration allConnections = freeConnections.elements(); <br />312 while (allConnections.hasMoreElements()) { <br />313 Connection con = (Connection) allConnections.nextElement(); <br />314 try { <br />315 con.close(); <br />316 log("关闭连接池" + name+"中的一个连接"); <br />317 } <br />318 catch (SQLException e) { <br />319 log(e, "无法关闭连接池" + name+"中的连接"); <br />320 } <br />321 } <br />322 freeConnections.removeAllElements(); <br />323 } <br />324 <br />325 /** <br />326 * 创建新的连接 <br />327 */ <br />328 private Connection newConnection() { <br />329 Connection con = null; <br />330 try { <br />331 if (user == null) { <br />332 con = DriverManager.getConnection(URL); <br />333 } <br />334 else { <br />335 con = DriverManager.getConnection(URL, user, password); <br />336 } <br />337 log("连接池" + name+"创建一个新的连接"); <br />338 } <br />339 catch (SQLException e) { <br />340 log(e, "无法创建下列URL的连接: " + URL); <br />341 return null; <br />342 } <br />343 return con; <br />344 } <br />345 } <br />346 } <br /><br /><br /><br /><br />三、类DBConnectionPool说明 <br /><br />该类在209至345行实现，它表示指向某个数据库的连接池。数据库由JDBC URL标识。一个JDBC URL由三部分组成：协议标识 <br />（总是jdbc），驱动程序标识（如 odbc、idb、oracle等），数据库标识（其格式依赖于驱动程序）。例如，jdbc:odbc:de <br />mo，即是一个指向demo数据库的JDBC URL，而且访问该数据库要使用JDBC-ODBC驱动程序。每个连接池都有一个供客户程序 <br />使用的名字以及可选的用户帐号、密码、最大连接数限制。如果Web应用程序所支持的某些数据库操作可以被所有用户执行， <br />而其它一些操作应由特别许可的用户执行，则可以为两类操作分别定义连接池，两个连接池使用相同的JDBC URL，但使用不 <br />同的帐号和密码。 <br />类DBConnectionPool的建构函数需要上述所有数据作为其参数。如222至238行所示，这些数据被保存为它的实例变量： <br />如252至283行、285至305行所示， 客户程序可以使用DBConnectionPool类提供的两个方法获取可用连接。两者的共同之处 <br />在于：如连接池中存在可用连接，则直接返回，否则创建新的连接并返回。如果没有可用连接且已有连接总数等于最大限制 <br />数，第一个方法将直接返回null，而第二个方法将等待直到有可用连接为止。 <br />所有的可用连接对象均登记在名为freeConnections的向量（Vector）中。如果向量中有多于一个的连接，getConnection() <br />总是选取第一个。同时，由于新的可用连接总是从尾部加入向量，从而使得数据库连接由于长时间闲置而被关闭的风险减低 <br />到最小程度。 <br />第一个getConnection()在返回可用连接给客户程序之前，调用了isClosed()方法验证连接仍旧有效。如果该连接被关闭或 <br />触发异常，getConnection()递归地调用自己以尝试获取另外的可用连接。如果在向量freeConnections中不存在任何可用连 <br />接，getConnection()方法检查是否已经指定最大连接数限制。如已经指定，则检查当前连接数是否已经到达极限。此处 <br />maxConn为0表示没有限制。如果没有指定最大连接数限制或当前连接数小于该值，该方法尝试创建新的连接。如创建成功， <br />则增加已使用连接的计数并返回，否则返回空值。 <br />如325至345行所示，创建新连接由newConnection()方法实现。创建过程与是否已经指定数据库帐号、密码有关。 <br />JDBC的DriverManager类提供多个getConnection()方法，这些方法要用到JDBC URL与其它一些参数，如用户帐号和密码等。 <br />DriverManager将使用指定的JDBC URL确定适合于目标数据库的驱动程序及建立连接。 <br />在285至305行实现的第二个getConnection()方法需要一个以毫秒为单位的时间参数，该参数表示客户程序能够等待的最长 <br />时间。建立连接的具体操作仍旧由第一个getConnection()方法实现。 <br />该方法执行时先将startTime初始化为当前时间。在while循环中尝试获得一个连接。如果失败，则以给定的时间值为参数调 <br />用wait()。wait()的返回可能是由于其它线程调用notify()或notifyAll()，也可能是由于预定时间已到。为找出wait()返 <br />回的真正原因，程序用当前时间减开始时间（startTime），如差值大于预定时间则返回空值，否则再次调用getConnection()。 <br />把空闲的连接登记到连接池由240至250行的freeConnection()方法实现，它的参数为返回给连接池的连接对象。该对象被加 <br />入到freeConnections向量的末尾，然后减少已使用连接计数。调用notifyAll()是为了通知其它正在等待可用连接的线程。 <br />许多Servlet引擎为实现安全关闭提供多种方法。数据库连接池需要知道该事件以保证所有连接能够正常关闭。DBConnectionManager <br />类负协调整个关闭过程，但关闭连接池中所有连接的任务则由DBConnectionPool类负责。在307至323行实现的release() <br />方法供DBConnectionManager调用。该方法遍历freeConnections向量并关闭所有连接，然后从向量中删除这些连接。 <br /><br /><br />四、类DBConnectionManager 说明 <br /><br />该类只能创建一个实例，其它对象能够调用其静态方法（也称为类方法）获得该唯一实例的引用。如031至036行所示， <br />DBConnectionManager类的建构函数是私有的，这是为了避免其它对象创建该类的实例。 <br />DBConnectionManager类的客户程序可以调用getInstance()方法获得对该类唯一实例的引用。如018至029行所示，类的唯 <br />一实例在getInstance()方法第一次被调用期间创建，此后其引用就一直保存在静态变量instance中。每次调用getInstance() <br />都增加一个DBConnectionManager的客户程序计数。即，该计数代表引用DBConnectionManager唯一实例的客户程序总数， <br />它将被用于控制连接池的关闭操作。 <br />该类实例的初始化工作由146至168行之间的私有方法init()完成。其中 getResourceAsStream()方法用于定位并打开外部 <br />文件。外部文件的定位方法依赖于类装载器的实现。标准的本地类装载器查找操作总是开始于类文件所在路径，也能够搜 <br />索CLASSPATH中声明的路径。db.properties是一个属性文件，它包含定义连接池的键-值对。可供定义的公用属性如下： <br /><br />drivers 以空格分隔的JDBC驱动程序类列表 <br />logfile 日志文件的绝对路径 <br /><br />其它的属性和特定连接池相关，其属性名字前应加上连接池名字： <br /><br />&lt;poolname&gt;.url 数据库的 JDBC URL <br />&lt;poolname&gt;.maxconn 允许建立的最大连接数，0表示没有限制 <br />&lt;poolname&gt;.user 用于该连接池的数据库帐号 <br />&lt;poolname&gt;.password 相应的密码 <br /><br />其中url属性是必需的，而其它属性则是可选的。数据库帐号和密码必须合法。用于Windows平台的db.properties文件示例 <br />如下： <br /><br />drivers=sun.jdbc.odbc.JdbcOdbcDriver jdbc.idbDriver <br />logfile=D:\\user\\src\\java\\DBConnectionManager\\log.txt <br /><br />idb.url=jdbc:idb:c:\\local\\javawebserver1.1\\db\\db.prp <br />idb.maxconn=2 <br /><br />access.url=jdbc:odbc:demo <br />access.user=demo <br />access.password=demopw <br /><br />注意在Windows路径中的反斜杠必须输入2个，这是由于属性文件中的反斜杠同时也是一个转义字符。 <br />init()方法在创建属性对象并读取db.properties文件之后，就开始检查logfile属性。如果属性文件中没有指定日志文件， <br />则默认为当前目录下的DBConnectionManager.log文件。如日志文件无法使用，则向System.err输出日志记录。 <br />装载和注册所有在drivers属性中指定的JDBC驱动程序由170至192行之间的loadDrivers()方法实现。该方法先用StringTokenizer <br />将drivers属性值分割为对应于驱动程序名称的字符串，然后依次装载这些类并创建其实例，最后在 DriverManager中注册 <br />该实例并把它加入到一个私有的向量drivers。向量drivers将用于关闭服务时从DriverManager取消所有JDBC 驱动程序的注册。 <br />init()方法的最后一个任务是调用私有方法createPools()创建连接池对象。如109至142行所示，createPools()方法先创建 <br />所有属性名字的枚举对象（即Enumeration对象，该对象可以想象为一个元素系列，逐次调用其nextElement()方法将顺序返 <br />回各元素），然后在其中搜索名字以“.url”结尾的属性。对于每一个符合条件的属性，先提取其连接池名字部分，进而读 <br />取所有属于该连接池的属性，最后创建连接池对象并把它保存在实例变量pools中。散列表（Hashtable类 ）pools实现连接 <br />池名字到连接池对象之间的映射，此处以连接池名字为键，连接池对象为值。 <br />为便于客户程序从指定连接池获得可用连接或将连接返回给连接池，类DBConnectionManager提供了方法getConnection()和 <br />freeConnection()。所有这些方法都要求在参数中指定连接池名字，具体的连接获取或返回操作则调用对应的连接池对象完 <br />成。它们的实现分别在051至064行、066至080行、038至049行。 <br />如082至107行所示，为实现连接池的安全关闭，DBConnectionManager提供了方法release()。在上面我们已经提到，所有 <br />DBConnectionManager的客户程序都应该调用静态方法getInstance()以获得该管理器的引用，此调用将增加客户程序计数。 <br />客户程序在关闭时调用release()可以递减该计数。当最后一个客户程序调用release()，递减后的引用计数为0，就可以调 <br />用各个连接池的release()方法关闭所有连接了。管理类release()方法最后的任务是撤销所有JDBC驱动程序的注册。 <br /><br /><br />五、Servlet使用连接池示例 <br /><br />Servlet API所定义的Servlet生命周期类如： <br /><br />1) 创建并初始化Servlet（init()方法）。 <br />2) 响应客户程序的服务请求（service()方法）。 <br />3) Servlet终止运行，释放所有资源（destroy()方法）。 <br /><br />本例演示连接池应用，上述关键步骤中的相关操作为： <br /><br />1) 在init()，用实例变量connMgr 保存调用DBConnectionManager.getInstance()所返回的引用。 <br />2) 在service()，调用getConnection()，执行数据库操作，用freeConnection()将连接返回给连接池。 <br />3) 在destroy()，调用release()关闭所有连接，释放所有资源。 <br /><br />示例程序清单如下： <br /><br />import java.io.*; <br />import java.sql.*; <br />import javax.servlet.*; <br />import javax.servlet.http.*; <br />public class TestServlet extends HttpServlet { <br />private DBConnectionManager connMgr; <br /><br />public void init(ServletConfig conf) throws ServletException { <br />super.init(conf); <br />connMgr = DBConnectionManager.getInstance(); <br />} <br /><br />public void service(HttpServletRequest req, HttpServletResponse res) <br />throws IOException { <br /><br />res.setContentType("text/html"); <br />PrintWriter out = res.getWriter(); <br />Connection con = connMgr.getConnection("idb"); <br />if (con == null) { <br />out.println("不能获取数据库连接."); <br />return; <br />} <br />ResultSet rs = null; <br />ResultSetMetaData md = null; <br />Statement stmt = null; <br />try { <br />stmt = con.createStatement(); <br />rs = stmt.executeQuery("SELECT * FROM EMPLOYEE"); <br />md = rs.getMetaData(); <br />out.println("&lt;H1&gt;职工数据&lt;/H1&gt;"); <br />while (rs.next()) { <br />out.println("&lt;BR&gt;"); <br />for (int i = 1; i &lt; md.getColumnCount(); i++) { <br />out.print(rs.getString(i) + ", "); <br />} <br />} <br />stmt.close(); <br />rs.close(); <br />} <br />catch (SQLException e) { <br />e.printStackTrace(out); <br />} <br />connMgr.freeConnection("idb", con); <br />} <br /><br />public void destroy() { <br />connMgr.release(); <br />super.destroy(); <br />} <br />} </td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/songfei/aggbug/62323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2006-08-08 11:31 <a href="http://www.blogjava.net/songfei/articles/62323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>