The DataSource with the JNDI name.txt

有关Weblogic Connection Pool 连接恢复的问题 

提交时间: Mar 23, 2006 5:01:28 PM  加3分 引用  回复    发消息 
 

这是一个古老的问题,一直困扰我,这里既然碰到了,就看看能不能解决。

环境描述:  
WEBLOGIC版本是8.1 SP2,数据库是SQL SERVER 2000,分别部署在两个服务器上。

第一步:
问题描述:
数据库服务器重新启动,导致WEBLOGIC 的CONNECTION POOL中的连接中断,EJB无法获得连接,导致应用出错。

解决方法:
进入WEBLOGIC ADMIN CONSOLE,
Services->JDBC->Connection Pools->Config->Connections, 点开Advanced Options.

打开 Test Reserved Connections ,Test Created Connections,Test Released Connections这三个选项。
将Test Table Name属性设置为:sysproperties(SQL Server系统表,即使自己的应用不存在,这个表也存在,而且默认的内部没有数据)

根据如下解释:
Connections that fail the test are closed and reopened to re-establish a valid physical database connection.
(You must specify a Test Table Name below.)
每次调用首先进行测试连接,如果测试失败连接将重新建立。

测试结果:
WEBLOGIC启动后,关闭数据库SQL SERVER,应用服务器前端调用此时失败。
重新启动SQL SERVER后,WEBLOGIC端略做等待,前端应用恢复正常。

第二步:
问题描述:
进一步测试,如果WEBLOGIC先启动,启动完成后再启动数据库。
在WEBLOGIC CONSOLE得到如下输出:

......

<2006-3-22 上午11时50分08秒 GMT+08:00> ool "MyJDBC Connection Pool": [Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket.>

<2006-3-22 上午11时50分10秒 GMT+08:00> failed with the following error: 0:Could not create pool connection. The DBMS driver exception was: [Microsoft][SQLServe
r 2000 Driver for JDBC]Error establishing socket..>

<2006-3-22 上午11时50分10秒 GMT+08:00> ith the following error: DataSource(jdbc/OMSEIITxDS) can't be created with non-existent Pool (connection or multi) (MyJD
BC Connection Pool).>

......


Unable to deploy EJB: XXXXXXX from XXXXXXX.jar:

[EJB:011028]The DataSource with the JNDI name: jdbc/XXXXXX could not be located. Please ensure that the DataSource h
as been deployed successfully and that the JNDI name in your EJB Deployment descriptor is correct.

......

1、在默认初始化打开的连接一一失败以后,连接池发现可用的连接为0,郁闷的宣布自己部署失败。
2、接着数据源发现没有可用的连接池,自己也宣布部署失败。
3、下面所有的EJB发现不了数据源的JNDI名,部署也全部失败。

应用启动完成后,大部分EJB的状态为INACTIVE。前端应用无法使用,此时启动数据库,前端应用无法使用。
手动重新部署 EJB失败,错误还是找不到JNDI,前端应用无法使用。
手动重新部署 连接池,数据源后,部署EJB 依然失败。前端应用无法使用。

解决方法:
进入WEBLOGIC ADMIN CONSOLE,
Services->JDBC->Connection Pools->Config->Connections, 点开Advanced Options.

Connection Creation Retry Frequency 参数设置为 60。
ConnectionCreationRetryFrequencySeconds含义:
当创建数据库连接时,如果数据库不可用(如数据库没启动),隔多长时间试着重新创建该连接,
WLS8.1会每隔ConnectionCreationRetryFrequencySeconds秒重试一次.直到JDBC POOL创建成功
参考:http://dev2dev.bea.com.cn/techdoc/20030469.html,‘JDBC Connect Pool’部分。
英文解释可以直接控制台上看到,或者edocs查。

测试结果:
将数据库关闭,WEBLOGIC重新启动。
在WEBLOGIC CONSOLE得到如下输出:

打开Connection Creation Retry Frequency 参数后,连接池在第一轮尝试失败以后,就成功部署了,数据源也成功部署。
EJB部署会失败,但是提示也与先前的不同:
......
Unable to deploy EJB: XXXXXXX from XXXXXXX.jar:

weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool MyJDBC Connection Pool to
allocate to applications, please increase the size of the pool and retry..

每隔一段时间会看到,CONNECTION POOL不断的重新进行连接:
<2006-3-22 下午12时17分56秒 GMT+08:00> ool "MyJDBC Connection Pool": [Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket.>


在WEBLOGIC启动完成后,所有EJB为INACTIVE状态。
启动数据库服务器,稍后,手动重新部署所有的EJB,EJB可以部署成功,前端应用可以正常使用。
此时,此问题已经基本解决,仍需要手动部署EJB。

第三步:
问题描述:

解决方法:
有关部署次序的问题,首先查阅WEBLOGIC文档,http://edocs.bea.com/wls/docs81/faq/deploy.html#744900,得到

WebLogic Server deploys server-level resources (first JDBC and then JMS) before deploying applications.
Applications are deployed in this order: connectors, then EJBs, then Web Applications.
If the application is an EAR, the individual components are loaded in the order in which they are declared
in the application.xml deployment descriptor.

WEBLOGIC先部署服务器端资源,JDBC -> JMS....,然后部署我们的应用,EJB->WEB APPLICATION。


实际从WEBLOGIC启动日志来看,即使打开了Connection Creation Retry Frequency,如果当时数据库不是可用的,CONNECTION POOL
会不断的调度CONNECTION进行重新连接。但是此时,EJB的部署也同时在进行。个人猜测这应该是两个不同的线程(组)分别调度的任务。

现在考虑的是能不能用StartupClass截住EJB的部署过程,粗略的说是如果DATASOURCE没有连接好,或者没有可用的连接池,
就不往下进行EJB部署的过程。
参考:http://edocs.bea.com/wls/docs81/config_xml/EJBComponent.html#DeploymentOrder
DeploymentOrder:
A priority that the server uses to determine when it deploys an item. The priority is relative to other deployable
items of the same type. For example, the server prioritizes and deploys all EJBs before it prioritizes and
deploys startup classes.Items with the lowest Deployment Order value are deployed first.
There is no guarantee on the order of deployments with equal Deployment Order values.
There is no guarantee of ordering across clusters. Default: 1000 Minimum: 0 Maximum: 2N31-1

在部署同一类应用时,按照 DEPLOYMENT LOADER的数值决定,数值越小越先。(EJB的参数在ADMIN CONSOLE界面上叫做LOAD ORDER)
而且上面看来服务器是先部署EJB,再部署STARTUP CLASS,遗憾了。

好在STARTUP CLASS上有两个选项,
    Run Before Application Deployments
    Run Before Application Activations
这两个选项分别可以设置StartupClass分别在系统资源部署之前,以及在系统资源部署和用户应用部署之间启动。
选上Run Before Application Activations。


现在可以了,我写了一个STARTUP CLASS,思路见下:
主代码:
    private void testConnection(){
        while (!isTimeout() && !getConnection()){
            try{
                Thread.sleep(testInterval*1000);
            }catch(Exception ignor){}
        }
        log("DBConnectHolder job finished with following status:");
        log("Timeout:"+isTimeout +",Connection OK:"+isConnected);
    }

测试结果:
只要配置的等待时间足够长,应用服务器先行启动的情况下,等待数据库启动后才进行EJB等等的部署。
(主要考虑如果数据库连接不OK,EJB启动了也没有太大用,还得手工重新部署。)算是比较完满的解决了问题。

另外一个思路是是否可行? 通过MBean, 在CONNECTION 建立起来以后通知一把,进行EJB的重新部署。
没来得及研究,请有经验的同学帮我补充完善。


结论:
其实也没什么结论,只是把自己遇到问题,解决问题的思路写了一下。短时间内阅读的文献有限,可能采用了一些苯方法
,或者走了弯路,也请大家拍砖。
在WL8版本上,数据库连接进行恢复和重新连接的时候,上面提出的几个参数应该是比较重要的,我再次强调一下。
Services->JDBC->Connection Pools->Config->Connections, 点开Advanced Options.
Test Reserved Connections
Test Created Connections
Test Released Connections
Test Table Name
Connection Creation Retry Frequency
 
 

你可能感兴趣的:(EJB)