web动态部署(热部署)

今天跟大家探讨一下关于web动态部署,也就是热部署的问题。说这个之前,先说一个敏捷开发的原则。

【最小发布、增量开发】

我们在做项目时,设定的期限都特别长。总是想第一个版本就想把所有想到的问题都做完,以至于项目一再延期。所以我们应该改变我们的开发策略。采用敏捷开发的方式。

这里我想强调的有2点,1.最小发布。2.增量开发

对于最小发布,就是要在第一版中把核心功能实现,即立即发布第一个版本。在实际的开发中,公司为了抢占市场,都会尽可能早的发布一个V1.0的版本。能有效的占领市场,同时对于开发人员来讲,可以减少对项目的排斥情绪。因为项目拖得越久,开发人员就会越疲惫,就会消极怠工,bug数会直线上升。这显然对与开发是极其不利的。

而增量开发,则是没增加一个功能模块,就要发布一个版本。保证在规定的时间内,至少可以让用户使用到新的功能。而且,采用增量开发的技术,也从可以降低模块之间的耦合性。人不可能一口吃成胖子,项目也一样,需要分阶段,分目标的去开发。中国还实行“五年计划”,更何况我们的项目呢。

【热部署】
热插拔,这个词儿可能只有在硬件中听过,在软件开发中可能没有听过。而热部署,跟热插拔一样,就算没听过,看到这个词儿也能想出个1,2,3来。
不错,热部署就是系统在运行过程中,可以对功能进行可配置,而不用停止或关闭系统。不用我说大家也能想到它的好处吧。
解耦,灵活性自然不必说,最重要的是用户可以按自己的喜好,个性化设置自己的系统,这对于用户来说是非常欢喜的。有这样的系统,没有人会去选择死板一块的系统。而且也同时印证和支持了最小发布和增量开发的方针。增量开发,每开发一个功能,就采用热部署,对系统进行在线升级。

说了这么多废话,还是给了代码看看吧,毕竟实践是检验真理的唯一标准。

热部署,主要用到了xml文件来实现动态效果。菜单用xml文件来存储,系统动态读取xml文件来动态生成菜单。例子菜单分为2级,一级菜单在同一个xml文件中,二级菜单存在放各自对应的文件夹中的xml文件里。

一级菜单存放在Config文件夹下的ChildSystem.config:

<?xml version="1.0" encoding="utf-8"?>
<!--系统中的子系统或子模块。-->
<childsystem>
  <system name="GoodsManager" value="商品管理" assembly="GoodsManager.dll" />
  <system name="UserManager" value="用户管理" assembly="UserManager.dll" />
</childsystem>

商品管理二级菜单存放在GoodsManager文件夹下的App.config:

<?xml version="1.0" encoding="utf-8"?>
<Pages>
  <page name="socket" value="测试界面" url="~/GoodsManager/Socket.aspx" />
  <page name="config" value="配置页面"  url="~/GoodsManager/Configer.aspx" />
  <main>
    <name>GoodsManager</name>
    <author>longxuan</author>
    <version>1.00</version>
    <assmebly>GoodsManager.dll</assmebly>
  </main>
</Pages>

用户管理二级菜单存放在UserManager文件夹下的App.config:

<?xml version="1.0" encoding="utf-8"?>
<Pages>
  <page name ="internet" value="网络时间" url="~/UserManager/InternetTime.aspx" />
  <page name="socket" value="测试界面" url="~/UserManager/Socket.aspx" />
  <page name="config" value="配置页面"  url="~/UserManager/Configer.aspx" />
  <main>
    <name>returnCashStrategy</name>
    <author>longxuan</author>
    <version>1.00</version>

主界面Default.aspx ,拖入一个TreeView控件,name修改为TreeViewMU,添加SelectedNodeChanged事件。后台代码:

using System;
using System.IO;
using System.Web.UI.WebControls;
using System.Xml;

namespace PluginTest
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ShowChildSystem();
            }
        }

        /// <summary>
        /// 子系统、子模块的显示
        /// </summary>
        private void ShowChildSystem()
        {
            string xmlpath = Server.MapPath("~\\Config\\ChildSystem.config");
            if (!File.Exists(xmlpath)) return;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlpath);
            var selectSingleNode = xmlDoc.SelectSingleNode("childsystem");
            if (selectSingleNode != null)
            {
                XmlNodeList nodelist = selectSingleNode.ChildNodes;

                TreeViewMU.Nodes.Clear();

                foreach (var VARIABLE in nodelist)
                {
                    TreeNode node = new TreeNode();
                    XmlAttributeCollection xmlAttributeCollection = ((XmlNode)VARIABLE).Attributes;
                    if (xmlAttributeCollection != null)
                    {
                        node.Text = xmlAttributeCollection["value"].InnerXml;
                        node.Target = xmlAttributeCollection["assembly"].InnerXml;
                        node.Value = xmlAttributeCollection["name"].InnerXml;
                    }
                    TreeViewMU.Nodes.Add(node);
                }
            }
        }

        protected void TreeViewMU_SelectedNodeChanged(object sender, EventArgs e)
        {
            ChildSystemManager();
        }

        /// <summary>
        /// 子系统、子模块的管理
        /// </summary>
        private void ChildSystemManager()
        {
            string xmlpath = Server.MapPath("~\\" + TreeViewMU.SelectedNode.Value + "\\App.config");

            if (!File.Exists(xmlpath)) return;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlpath);
            var selectSingleNode = xmlDoc.SelectNodes("Pages//page");
            if (selectSingleNode != null)
            {
                XmlNodeList nodelist = selectSingleNode;

                TreeViewMU.SelectedNode.ChildNodes.Clear();

                foreach (var VARIABLE in nodelist)
                {
                    TreeNode node = new TreeNode();
                    XmlAttributeCollection xmlAttributeCollection = ((XmlNode)VARIABLE).Attributes;
                    if (xmlAttributeCollection != null)
                    {
                        node.Text = xmlAttributeCollection["value"].InnerXml;
                        node.Value = xmlAttributeCollection["name"].InnerXml;
                        node.NavigateUrl = xmlAttributeCollection["url"].InnerXml;
                    }
                    TreeViewMU.SelectedNode.ChildNodes.Add(node);
                }
            }
        }
    }
}

每次开发一个新的功能模块,或者子系统,把网页放到一个文件夹中,并在该文件夹中写好App.config文件,然后放到已经部署好的系统根目录下,对一级菜单配置文件稍作修改即可。不用关闭系统,重新发布,重新启动。这对与大型系统是极为重要的,比如金融,电力、水利系统等,关闭一秒钟的损失都是不可估量的。而热部署是解决这类问题的一个很好的例子。

动态修改配置文件的类这里不再赘述,在《重新演绎动态编译类,打造灵活多变的系统》中发表过一篇类似的Config配置修改类,可以做参考。

时间: 2024-09-24 06:25:17

web动态部署(热部署)的相关文章

热部署 java web 运维-在部署web应用的时候,怎么才能不影响正常用户的访问实现热部署?比较主流的方案是怎么样的

问题描述 在部署web应用的时候,怎么才能不影响正常用户的访问实现热部署?比较主流的方案是怎么样的 在部署web应用的时候,怎么才能不影响正常用户的访问实现热部署?比较主流的方案是怎么样的.假如我只有一台服务器 有没有必要在一台服务器上配置两个web应用来提高服务的可用性 解决方案 负载均衡,多台服务器备份,然后部署的时候,先部署一台,把流量都导到另一台处理业务,等部署好后,开始逐步分配流量,进行监测看业务是否运行正常 如果没什么问题,那么就进行另一台的部署,同样的流程 解决方案二: 负载均衡,

Tomcat热部署和虚拟目录配置

1.Tomcat如何配置热部署 默认就是  1 <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> 如果要实现IDE修改代码的自动部署,可以使用第三方工具 http://www.zeroturnaround.com/jrebel/ 1.解压缩包 2.执行java -jar jrebel-setup.jar 3.会

tomcat 和 jboss的热部署(热发布)问题

所谓的热部署(热发布)(下面称为"热部署"),就是说,在web工程发布之后,不可避免的,会遇到修改BUG的问题.现在的热部署就是为了解决这个问题,其功能就是说:在不停止web服务的同时,对jsp和java类进行修改,修改后的效果同时还能够在页面上显示出来.节省了调试时间,提高了效率.不过,修改配置文件是个例外,如果对配置文件做修改,一定要重启web服务.         常用的web服务器一般为tomcat和jboss,现一一做介绍.         1.tomcat热部署      

深入探索Java热部署

简介 在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现 方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作. 对于某些大型的应用来说,每次的重启都需要花费大量的时间成本.虽然 osgi 架构的出现,让模块重启 成为可能,但是如果模块之间有调用关系的话,这样的操作依然会让应用出现短暂的功能性休克.本文将 探索如何在不破坏 Java 虚拟机现有行为的前提下,实现某个单一类的热部署,让系统无需重启就完成某 个类的更新. 类

spring-boot 速成(2) devtools之热部署及LiveReload

JRebel热部署插件相信很多人都知道,但是这是一款商业插件,spring-boot框架也提供了类似的功能,即:devtools,关键是免费的! 使用方法如下: 一.添加 devtools依赖 dependencies { compile('org.springframework.boot:spring-boot-starter-web') compile('org.springframework.boot:spring-boot-devtools') compileOnly('org.proj

ODM规则执行服务器RES支持热部署的两种方式

规则集的热部署是指在规则集版本发生变化时,规则执行组件 (XU) 可以自动接收到规则集版本更新的通知 , 从而自动加载最新的规则集,整个过程用户不需要重启任何组件.业务规则管理系统实现了业务规则和应用程序逻辑的分离,业务用户可以在业务逻辑放生变化时,即时的更新业务规则,部署最新的规则集到规则执行服务器.而规则集的热部署则保证了在业务逻辑发生变化时,业务规则管理http://www.aliyun.com/zixun/aggregation/18477.html">系统服务的连续性. ODM

深入探索 Java 热部署

在 JAVA 开发领域,热部署一直是一个难以解决的问题,目前的 JAVA 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.对于某些大型的应用来说,每次的重启都需要花费大量的时间成本.虽然 OSGI 架构的出现,让模块重启成为可能,但是如果模块之间有调用关系的话,这样的操作依然会让应用出现短暂的功能性休克.本文将探索如何在不破坏 JAVA 虚拟机现有行为的前提下,实现某个单一类的热部署,让系统无需重启就完成某个类的更新. 类加载的探索 首先

springboot + devtools(热部署)

技术介绍 devtools:是boot的一个热部署工具,当我们修改了classpath下的文件(包括类文件.属性文件.页面等)时,会重新启动应用(由于其采用的双类加载器机制,这个启动会非常快,如果发现这个启动比较慢,可以选择使用jrebel) 双类加载器机制:boot使用了两个类加载器来实现重启(restart)机制:base类加载器(简称bc)+restart类加载器(简称rc). bc:用于加载不会改变的jar(eg.第三方依赖的jar) rc:用于加载我们正在开发的jar(eg.整个项目里

Java服务器热部署的实现原理

[本文转载于Java服务器热部署的实现原理] 今天发现早年在大象笔记中写的一篇笔记,之前放在ijavaboy上的,现在它已经访问不了了.前几天又有同事在讨论这个问题.这里拿来分享一下. 在web应用开发或者游戏服务器开发的过程中,我们时时刻刻都在使用热部署.热部署的目的很简单,就是为了节省应用开发和发布的时间.比如,我们在使用Tomcat或者Jboss等应用服务器开发应用时,我们经常会开启热部署功能.热部署,简单点来说,就是我们将打包好的应用直接替换掉原有的应用,不用关闭或者重启服务器,一切就是