避免重启你的应用程序 一

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

转自:javaresearch.org

在开发测试阶段,某个功能模块出错或者功能需求改变,这时候程序员通常会修改源代码,然后重新编译,停止应用程序,重起应用程序。然后检测修改得功能是否正确,是否满足需求。很好,这一切在开发测试阶段都没有问题,无可厚非。不过到了应用正式上线就出现麻烦了。重启应用会导致系统不可用,或者导致用户请求、响应丢失。甚至有的系统本生就要求为系统动态添加功能,在没有为你的应用添加防止重启动的策略前,通常能做的是到凌晨2点趁用户少的时候重启你的应用或者是暂时切换到备份系统。

如果你的系统也遇到过或者将不可避免的遇到这样的问题,那在这篇文章里,几个解决办法可以供你选择使用。

一:在启动前,保存未被处理的请求和未发给用户的响应。较好的方式是将接收请求,发送响应的模块与你处理应用逻辑的模块分开设计。如现在的web服务器,可以在你重新部署(redploy)的时候暂把用户的请求保存到队列,等到部署成功后在提交给处理逻辑的模块。又如,接收请求,发送响应的模块是不同的应用。与应用逻辑模块之间通过文件(把请求序列化成一个文件)等方式交换数据,这样在你的逻辑应用重启后,仍然可以继续读取请求

二:如果更新的功能是纯数据的,那么,采用动态配置,避免重启动。比如,一个web系统,提供reloadConfig界面,重新从配置文件里读取数据。一个java应用程序,你可以在你的应用程序里启动一个检测线程,检测文件是否被改变,如果改变,则自动重新转载配置。如下例子:

public ConfigChecker extends Thread

{

SystemManager sm = null;

long time ;

public ConfigChecker(SystemManager sm) throws ApplicationException

{

this.sm = sm;

time = getConfigFileTime();

}

pulblic void run()

{

while(!interrupted())

{

try

{

long newTime = getConfigFileTime();

if(newTime!=time)

{

time = newTime;

//重新装载配置

sm.reloadConfig();

}

Thread.sleep(1000*3)

}

catch(Exception ex)

{

return ;

}

}

}

public long getConfigFileTime() throws ApplicationException

{

try

{

File f = new File(sm.getConfigFile());

return f.lastModified()

}

catch(IOException ex)

{

throw new ApplicationException(ex.getMessage())

}

}

}

这种方式适合你要动态改变的是纯数据,它要求你应用中的数据不能写死在代码里,而是通过文件配置。通过重新从配置文件里读取数据避免重启动

三:如果更新的功能包括应用逻辑,也就是class改变了,那就稍微麻烦点,你需要了解ClassLoader的原理。使用你定制的ClassLoader重新Load 已经编译好的class,就好比你重启应用一样。下面将简单介绍ClassLoader原理,以及举出一个例子来说明如何避免重启应用程序

在开发测试阶段,某个功能模块出错或者功能需求改变,这时候程序员通常会修改源代码,然后重新编译,停止应用程序,重起应用程序。然后检测修改得功能是否正确,是否满足需求。很好,这一切在开发测试阶段都没有问题,无可厚非。不过到了应用正式上线就出现麻烦了。重启应用会导致系统不可用,或者导致用户请求、响应丢失。甚至有的系统本生就要求为系统动态添加功能,在没有为你的应用添加防止重启动的策略前,通常能做的是到凌晨2点趁用户少的时候重启你的应用或者是暂时切换到备份系统。

如果你的系统也遇到过或者将不可避免的遇到这样的问题,那在这篇文章里,几个解决办法可以供你选择使用。

一:在启动前,保存未被处理的请求和未发给用户的响应。较好的方式是将接收请求,发送响应的模块与你处理应用逻辑的模块分开设计。如现在的web服务器,可以在你重新部署(redploy)的时候暂把用户的请求保存到队列,等到部署成功后在提交给处理逻辑的模块。又如,接收请求,发送响应的模块是不同的应用。与应用逻辑模块之间通过文件(把请求序列化成一个文件)等方式交换数据,这样在你的逻辑应用重启后,仍然可以继续读取请求

二:如果更新的功能是纯数据的,那么,采用动态配置,避免重启动。比如,一个web系统,提供reloadConfig界面,重新从配置文件里读取数据。一个java应用程序,你可以在你的应用程序里启动一个检测线程,检测文件是否被改变,如果改变,则自动重新转载配置。如下例子:

public ConfigChecker extends Thread

{

SystemManager sm = null;

long time ;

public ConfigChecker(SystemManager sm) throws ApplicationException

{

this.sm = sm;

time = getConfigFileTime();

}

pulblic void run()

{

while(!interrupted())

{

try

{

long newTime = getConfigFileTime();

if(newTime!=time)

{

time = newTime;

//重新装载配置

sm.reloadConfig();

}

Thread.sleep(1000*3)

}

catch(Exception ex)

{

return ;

}

}

}

public long getConfigFileTime() throws ApplicationException

{

try

{

File f = new File(sm.getConfigFile());

return f.lastModified()

}

catch(IOException ex)

{

throw new ApplicationException(ex.getMessage())

}

}

}

这种方式适合你要动态改变的是纯数据,它要求你应用中的数据不能写死在代码里,而是通过文件配置。通过重新从配置文件里读取数据避免重启动

三:如果更新的功能包括应用逻辑,也就是class改变了,那就稍微麻烦点,你需要了解ClassLoader的原理。使用你定制的ClassLoader重新Load 已经编译好的class,就好比你重启应用一样。下面将简单介绍ClassLoader原理,以及举出一个例子来说明如何避免重启应用程序

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航