ESFramework介绍之(22)―― 服务器系统自动升级

    (本文名字取为“服务器系统自动升级”,实际上适用于所有应用程序自动升级的情况。)
    前文介绍了在服务器或客户端应用程序运行的过程中,插件如何自动升级、更新。基于前文相同的理由,AS、FS、IRAS也需要有自动升级的功能。
     与插件在运行时动态更新不同,服务器系统无法在运行时动态更新,只有在服务器系统重新启动的时候,才是自动升级的切入点。
(1)对于功能服务器FS,可以采用持续/逐个更新的方式,即依次重启每个功能服务器。这样可以避免功能服务被中断的情况发生。需要注意的是,只有当目标FS上没有功能请求时,才可重启该FS,否则,会导致终端出现发出请求没有响应的糟糕的用户体验。解决方案是:在FS重启之前,FS向对应的AS报告自己马上将重启,这样,AS不会再将请求分派到该FS上,一段时间后,本FS上就没有功能请求了,于是可以顺利重启了。
(2)对于IRAS与AS,则需要在重启前满足本系统中没有功能请求的条件,这可以通过一段时间不接受终端连接请求来做到。如果不能停止AS服务,则可以在升级本区域AS的时候,先启用备用AS(可以通过端口映射在主AS和备用AS之间切换),当升级完成后,再切换回来。

    上面已经提到,当服务器重启的时候是系统升级的切入点,这个切入点一般在Main函数中,并且位于Application.Run之前。如下面示例代码所示:

                #region 系统升级                
                 if(MainClass.AsConfig.UpdateEnabled)
                {
                    DataCenterBase.Common.DataCenterHelper dataCenterHelper = (DataCenterBase.Common.DataCenterHelper)MainClass.SpringContext.GetObject("dataCenterHelper") ;
                        
                    //如果有新版本
                    if(dataCenterHelper.GetAppServerNewVersion() > MainClass.Version)
                    {
                        string dir = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) ;
                        //升级程序的路径
                        string updateExePath = dir + "\\" + MainClass.AsConfig.UpdateExeFileName ;
                        //启动升级程序、并退出Main
                        EnterpriseServerBase.Common.AdvancedFunction.StartApplication(updateExePath) ;                
                        return ;
                    }
                }                
                #endregion

    需要自动升级的系统(比如上面的AS)中与升级相关的代码大致就这么多,而本文我们重点要关注的是升级程序的实现。升级程序中核心接口是IAutoUpdator,位于ESFramework.Deploy命名空间中:

    public interface IAutoUpdator
    {
        void Start() ;
        void Cancel() ;

        IUpdateAssistant UpdateAssistant{set ;}
        IUiReporter      UiReporter{set ;} 

        event CbSimple UpdateFinished ;
    }

    Start方法将启动升级过程,当升级完成的时候,将触发UpdateFinished事件。升级开始时,IAutoUpdator读取本地配置文件中中应用程序和各个dll及相关文件的版本信息,然后与获取的最新版本信息相比较,以决定要升级哪些exe或dll,要删除哪些dll,要新下载哪些exe或dll。针对每个exe或dll(甚至是有升级需要的重要文件),都有一个OneUpdate对象与之对应。

    public class OneUpdate
    {
        public UpdatingType UpdateType =  UpdatingType.Keep ;
        public string URL ;
        public string FilePath ;
        public string FileName ;
        public float  NewVersion ;
    }

    /// <summary>
    /// UpdatingType 升级类型
    /// </summary>
    public enum UpdatingType
    {
        Add ,Remove ,Update ,Keep //keep 表示不需更新
    }

    这与前文的插件升级是相同的。有人会问,为什么插件升级和应用程序升级不做成一样的组件,这样可以更多的复用啊?那是因为它们升级的模式是不一样的,插件是动态升级的,而应用程序本身只能是静态升级的(当然,即使你动态升级了这个应用程序中加载的插件)。
    如果要顺利的完成升级,有些必要的信息需要获取,比如最新版本的版本号,最新版本的服务器系统exe及相关dll的下载地址等等,这些是通过IUpdateAssistant接口提供的:

    public interface IUpdateAssistant
    {
        IUpdateInformation[] GetUpdateInformation() ; //获取最新版本文件(exe、dll等)的下载地址信息
        FileInfo[]           GetFileInfoToUpdate() ;  //获取要升级文件(exe、dll等)的当前版本
        string               GetFileDirectory() ;

        // 通常操作本地配置文件
        void                 ReviseFileVersion(string fileName ,float newVer) ; //增加或修改
        void                 RemoveFileVersion(string fileName) ;
    }

    public class FileInfo
    {
        public string FileName ;
        public float  Version ;        
    }

    public interface IUpdateInformation
    {
        string FileName {get ;set ;}
        string URL {get ;set ;}
        float  Version {get ;set ;}
        string FileType {get ;set ;}         
        bool   IsValid{get ;set ;}
    }

    不同的应用对IUpdateAssistant的实现是不同的。比如有的把最新版本的服务器系统exe及相关dll存放在数据库中,有的则可能放在某个Web上,以通过URL下载获取,等等。 有时新版本的应用程序可能需要删除旧版本中的某些不再需要的dll或其它辅助文件,RemoveFileVersion用于这个目的。而当应用程序及相关dll升级完成后,就需要更改本地配置中的相应版本号,ReviseFileVersion提供了此功能。    
    IAutoUpdator通过IUiReporter接口将升级的进度信息通知给UI,这样用户就对升级的进程就了然于胸了。

    public interface IUiReporter
    {
        void Initialize(int minVal ,int MaxVal ,int val) ;
        void Set(int val) ;
 
        void ShowMessage(string msg) ;
    }

    当有重要事件发生(比如网络断开)而导致升级失败,IUpdateAssistant会通过IUiReporter的ShowMessage方法给出通知。借助于上述的各个辅助接口,实现IAutoUpdator就非常easy了,实现源码参见SFramework.Deploy.AutoUpdator类。

    在AutoUpdator的帮助下实现你自己的自动升级程序可以这样做,首先建立一个新的WinForm项目,根据你应用的需要,实现上面列出的各个辅助接口,然后将这些实现装配给AutoUpdator,就像这样:

        public Form1()
        {            
            InitializeComponent();

            this.autoUpdator = new AutoUpdator() ;
            this.autoUpdator.UiReporter = this ;
            this.autoUpdator.UpdateAssistant = new UpdateAssistant() ;
            this.autoUpdator.UpdateFinished += new CbUpdate(autoUpdator_UpdateFinished);
        }

    然后在Load事件中启动升级:

        private void Form1_Load(object sender, System.EventArgs e)
        {
            this.autoUpdator.Start() ;
        }

    最后,当升级完成时,需要重新启动新版本的应用程序:

        private void autoUpdator_UpdateFinished()
        {
            MessageBox.Show("升级完成!") ;

            string apppath = System.IO.Directory.GetParent(Application.ExecutablePath).ToString();
            EnterpriseServerBase.Configure.XmlParser xmlParser = new EnterpriseServerBase.Configure.XmlParser(apppath + "\\" + "VersionInfo.xml");    

            //启动新版本的应用程序
            Process downprocess = new Process();            
            downprocess.StartInfo.FileName = string.Format("{0}\\{1}" , apppath ,xmlParser.GetConfigValue("HostInfo" ,"StartAppName")) ;
            downprocess.Start();

            this.Close() ;
        }

    当前的设计,主要支持从Url下载最新版本的文件(这可从IUpdateInformation接口的URL属性看出),这也是最常见的方式。当然你可以将最新版本的文件存放在数据库中,这时就需要将IUpdateInformation接口定义修改一下即可适应。发挥你的创造力吧,欢迎和我交流你的想法!
    感谢关注!

上一篇文章:ESFramework介绍之(20)―― 插件自动升级

转到  :ESFramework 可复用的通信框架(序)
    

   

时间: 2024-10-30 06:52:51

ESFramework介绍之(22)―― 服务器系统自动升级的相关文章

系统自动升级win10如何恢复原来的系统?

系统自动升级win10怎么回事 在新一轮免费升级推送后,微软悄然修改了用于升级的应用"Get Windows 10",用户收到的弹窗就是它.而且只给了两个选项,"Upgrade Now"(现在升级)."Upgrade Tonight"(今晚升级),用户稍不注意就会点错,也就难怪"被自动"升级了. 而且,从2016年初开始,Windows 10升级在Windows Update里边将变成推荐更新,即默认勾选.以后有更新提示的话,

怎么禁止win7系统自动升级windows10系统的方法

1.我们先进入到win7系统中这样先来让它自动升级到 Win10功能来取消,具体操作如下: 2.在开始菜单点击"运行"然后输入"gpedit.msc"打开系统的"本地组策略编辑器"如下图所示操作: 3.运行gpedit.msc如下所示,重新禁用上述策略设置即可: 4.打开计算机配置 - 管理模板 - Windows组件 - Windows Update: 5.在右边列表找到“Turn off the upgrade to the latest v

Win8.1系统自动登录帐户设置技巧

  在Win8.1系统中SkyDrive和本地"文件"整合成为一个新功能.要使用SkyDrive,我们就需要使用微软账户登陆Win8.1系统.如果Win8.1系统使用本地账户登陆系统,在配置SkyDrive时会提示需要切换至微软账户登陆系统才能使用SkyDrive,并保持现有设置不变.相对于普通家庭用户,如何每次开机都输入密码,会觉得很繁琐,甚是麻烦-下面系统之家小编就为大家介绍一下Win8.1系统自动登录帐户设置技巧! 1.首先按下"Win + R"组合键调出&q

如何关闭360安全卫士的自动升级?

有部分用户反应开机后打开360安全卫士,感觉变样了,原来是软件自动升级了.有些用户不习惯用新版的,今天给大家介绍把软件中的自动升级关掉的操作方法,,需要的朋友可以参考下. 不知道大家有没有这种经历,某天开机后打开360安全卫士,一看不认识了?原来是软件自动升级了.但是有些人根本不乐意升级.今天小编就教大家把软件中的自动升级关掉. 1.首先打开360安全卫士,右上角一个小箭头,选择"设置" . 2.在设置的"升级方式"窗口下的升级方式中,选择不自动升级.   只需要小

解决win10自动升级后无法激活的问题

Win10升级后无法激活的解决方法: 1.在Cortana搜索栏输入CMD,然后在第一个结果点击右键,选择"以管理员身份运行" 2.专业版用户,请输入下面的命令: slmgr.vbs -ipk NKJFK-GPHP7-G8C3J-P6JXR-HQRJR 3.企业版用户,请输入下面的命令: slmgr.vbs -ipk PBHCJ-Q2NYD-2PX34-T2TD6-233PK 4.然后我们按键盘的回车键,执行好之后再输入下面的命令. slmgr.vbs -ato 好了这样的你会发现系统

ESFramework介绍之(20)―― 插件自动升级

    当我们的服务平台搭建成功后,所需要做的主要事情就是开发服务端功能插件(IFunAddin)和客户端插件(IPassiveAddin),每个插件对(AddinPair)实现了一组相似或相近的需求/功能.     好了,我们已经开发了十多对插件对,然后分别XCopy到了各个服务器节点上,"整个系统"已经投入了运行.通过前面的介绍(回顾),相信大家对我们的"整个系统"有了个大致的映像.我们的IRAS服务器通常只存在于一个节点上,而我们的AS和对应的多个FS通常分布

自动升级系统的设计与实现(源码)

(最新OAUS版本请参见:自动升级系统OAUS的设计与实现(续)) 对于PC桌面应用程序而言,自动升级功能往往是必不可少的.而自动升级可以作为一个独立的C/S系统来开发,这样,就可以在不同的桌面应用中进行复用.基于ESFramework的文件传送功能,我实现了一个可直接复用的自动升级系统OAUS,现在将其分享给大家.这篇文章将着重介绍OAUS的相关背景.使用方法,至于详细的实现细节,大家可以直接下载源码研究.如果了解了OAUS的使用,源码的理解就非常容易了.如果需要直接部署使用自动升级系统,那么

介绍IBM Power服务器的三种不同系统固件升级方法

主要给出每种方法升级系统固件的例子,通过图以及文字说明对这三种系统固件升级方法进行详细介绍,从而使用户更好的掌握固件升级,降低固件升级过程中的故障. 对所有类型的 Power 服务器,其都有系统固件(Firmware).IBM 会定期的在固件服务网站上发布最新的更新包,这些更新包能够保证服务器更加稳定.高效的运转.http://www.aliyun.com/zixun/aggregation/13879.html">系统管理员就需要根据所管理的服务器的情况,定期到网站下载更新包,并对 Po

ESFramework介绍之(7)-- 服务器代理IServerAgent

    (本文原作于2006.03.15,第一次修正于2006.06.06,修正后适用于ESFramework V0.3+)     (本文是ESFramework对客户端开发的支持特性之一 ,如果要按顺序阅读,请转到ESFramework介绍(序))         分布式系统的构建一般有两种模式,一是基于消息(如Tcp,http等),一是基于方法调用(如RPC.WebService.Remoting).深入想一想,它们其实是一回事.如果你了解过.NET的Proxy,那么你会发现,方法调用和消