用应用程序域实现软件系统的热插拔

某些软件系统作为服务来运行,需要长时间的高可靠的运行,也许一年时间内只允许停顿一次维护,那么如果在运行过程中我们需要更新某一功能模块,该怎么办呢文描述了怎样用NetAppDomain机制来解决这一问题。

 

不许重新编译整个系统就可以更新某个模块的方法我们都知道,那就是用反射功能,比如Assembly.Load,可以在代码层动态加载某个模块。但要实现真正的运行过程中动态更换,我们必须有一个机制,首先把旧的版本从进程中卸载,然后载入新的版本,不幸的是,我们没有一个Assembly.UnLoad方法,我们必须寻找其他途径。

 

AppDomain为解决此问题提供了更好的方案,由于一个进程内可以有多个AppDomain,每个AppDomain之间隔离性很好,我们可以在运行过程中加载和卸载某个AppDomain

 

AppDomain怎么通信的呢们想到了Remoting,Remoting的一个重要功能是可以支持AppDomain之间的通信,我们需要一个实现MarshalByRefObject接口的类来作为调用的通道。

 

下面是代码实现,两个AssemblyAppDomainTest,作为我们的主系统,NewDomainFunction,作为我们需要频繁升级的模块。主程序每隔50秒(现实中太短了,这里只是演示)把系统的日志文件压缩,只压缩最老的100文件。NewDomainFunction实现了文件压缩的功能。

 

首先看主程序:

 

static void Main()

{

                     Console.WriteLine(“Start test…”);

                     while(true)

                     {

                           Console.WriteLine(“Start zip log files…”);

 

                           Evidence adevidence = AppDomain.CurrentDomain.Evidence;

          

                           AppDomain newDomain =System.AppDomain.CreateDomain(“MyDomain”,adevidence);

          

                           RemoteHelper helper =

                                  (RemoteHelper)newDomain.CreateInstanceAndUnwrap(“AppDomainTest”,”AppDomainTest.RemoteHelper”);

                           helper.ZipLogFile(100);

                          

                           AppDomain.Unload(newDomain);

 

                           Console.WriteLine(“Zip log files done…”);

                           System.Threading.Thread.Sleep(50000);

                    

                     }

              }

 

这里是接口类RemoteHelper:

public class RemoteHelper:MarshalByRefObject

{

              public RemoteHelper()

              {

                    

              }

 

              public void ZipLogFile(int fileNumber)

              {

                     string funFullName=System.Configuration.ConfigurationSettings.AppSettings[“NewDomainFunction”];

                     if(funFullName.Length==0)

                           return;

 

                     Assembly asm=Assembly.Load(funFullName);

                  Type zipLogType=asm.GetType(“NewDomainFunction.ZipLog”);

                     Object[] zipLogArguments=new object[]{fileNumber};

                     MethodInfo zipLogMethodInfo =

                           zipLogType.GetMethod(“ZipFiles”);

                     zipLogMethodInfo.Invoke(Activator.CreateInstance(zipLogType),

                           zipLogArguments);

              }

       }

 

压缩模块的AssemblyName配置在config文件中

<add key=”NewDomainFunction” value=”NewDomainFunction, version=1.0.3273.17760, Culture=neutral, PublicKeyToken=cc277552af2314ec” />

 

当需要更新模块时,我们做两件事情:

用新的Assembly替换掉旧的,直接覆盖,(当正在压缩文件时不可以,避开这个时间段)

更改配置文件中的NewDomainFunction名字。

 

下面是压缩模块的代码:来源:kevinkevin

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2008年11月14日
下一篇 2008年11月15日

相关推荐