抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

采用模式和泛型技术为应用增加策略控制 (动态部分)

2007 年 4 月 15 日

策略对象的适用

这部分主要讨论如何用上面设计好的策略对象影响各类具体业务逻辑的问题。从使用上看,这种适用包括两个层次,一个是从元数据层次对于业务实例的影响,另一个是更精细颗粒度层次的逻辑嵌入部分。类似的概念可以类比.NET CLR 的代码访问安全(CAS, Code Access Security)的概念,即有关的策略控制定义可以采用声明方式(Declarative)和显式调用方式(Explicity)。

图 1:策略对象的适用

对一个抽象的业务逻辑调用过程而言,策略对象的适用分散在 5 个环节,包括:

  1. 输入数据的适用。
  2. 执行业务实体元信息的适用。
  3. 执行业务实体内部逻辑过程中的适用。
  4. 输出数据的适用。
  5. 有可能还会对调用上下文进行必要的控制,主要用于对于策略对象自身所需要的各类上下文进行维护。

同时还要考虑适用执行过程中的异常处置,策略的适用过程本身可能产生各类异常,但考虑到策略是同本身是一个纵向嵌入到业务系统的部分,因此要根据调用上下文对于异常的容忍程度进行不同的定义,目的是确保“业务逻辑在策略控制下平稳运行”。

业务数据的适用

业务数据自身的适用主要针对业务数据集合中的关键字段进行检查,实现上既可以针对每类数据定义独立的 MatchRule,也可以通过一个更为普适和抽象的基于规则匹配的 MatchRule。例如:在本文示例中如果企业根据其安全要求,定义了如下策略“本系统内部所有涉及到客户姓名的内容全部采用加密方式保存”,自然对于日志而言写入日志的用户姓名也要加密(至于后续的解密则会由审计部门处理,他们可以看到明文的用户姓名)。设想的业务情形如下:

  1. 企业中在“客户资源系统”、“在线销售系统”、“原材料进销存系统”三个系统中都会涉及客户姓名。
  2. 客户姓名在三个系统中分别称为“UserName”、“Contact”、“KH”,而且“UserName”本身又包括 FirstName、LastName 和 MidName。

这样如何对于业务数据适用就会有一个常规的实现方式:

图 2:常规方式的数据适用

这种方式的思想就是“一事一议”,而且通过“接口—〉抽象类—〉实体类”这种方式对于实际的匹配规则进行两个层次的抽象和多态复用,不过一个缺点就是工作成本相对比较大,尤其对于一个长期持续的企业信息化建设过程而言,姓名、联系方式、员工性别、健康资料等信息也很可能陆续面临不同的处理方式,同样的随着企业新应用系统的不断上线,相关的扩展工作也会在水平方向快速扩展。这样对于策略控制系统自身而言会因为实体类型纵横两个方向的快速膨胀出现“类型海洋”的现象。纵向(继承关系)上可以采用桥模式(Bridge Pattern)解耦。

图 3:通过桥模式从向解耦数据规则匹配

注:对于水平方向的扩展可以采用 Decorator 结合 Visitor 方式来适应,不过因为这里 IMatchRule 的功能相对固定,所以这里不进行展开。)

上面的讨论主要基于单个字段信息的修改和扩展进行考虑,但实际上往往这类策略要同时涉及多个字段的组合,例如:所有高层领导特批的财务审批过程严禁保存(包括日志系统、报表系统、短信通知系统都要禁止),实际企业应用中更为繁琐和繁琐的策略性要求也会频繁出现,因此如果频繁的采用上面处理方法那么反复开发、测试和部署的成本都会快速增加。那么面对这种业务化快速变化的适用环境,增设一个具有业务化规则理解能力的规则引擎(Rule Engine)也许就非常必要了。这里“所有高层领导特批的财务审批过程严禁保存”表示为:

业务表达式
!(IsSupervisor(‘UserName’) && InclueAccountingField())

说明:

  1. 这里有两个业务函数 IsSupervisor()和 IncludeAccountingField()。
  2. 对于字段的提取则是通过业务函数通过字段名称列表传递。
  3. 由于匹配规则最后的结果是个“是 / 否”命中的结果,因此这里两个业务函数返回结果是 bool,它们间的关联也通过 bool 运算连结。

图 4:通过业务规则引擎扩展 IMatchRule

元数据(metadata)的适用

由于元数据的类型相对比较固定,因此使用上可以不通过上面业务数据适用部分那些相对复杂的规则扩展机制,而采用常规的 IMatchRule 实现和继承机制既可,可供选择的元数据对象:

  1. 命名空间
  2. 属性和自定义属性
  3. 类型名称
  4. 方法属性信息
  5. 方法返回值信息
  6. 方法名称信息
  7. Assembly 元数据
  8. 其他可以通过反射机制活的元数据

这方式的设计结构上相对更加简单,可以采用下面的扩展设计:

图 5:结合反射机制的元数据策略匹配适用

执行逻辑策略适用

对于执行逻辑部分的策略适用由于需要被业务逻辑部分显示调用,因此既可以有策略系统实现部分 IMathRule,同时也可以把自己度交给企业内部各个业务系统,让它们自定义并 IMatchRule。作为这个最细颗粒度的策略适用情形而言,可用的使用规则可以表示为:

规则适用集合 {可用策略适用规则} =
{业务数据适用规则适用} ∪
{元信息使用规则适用} ∪
{策略系统执行逻辑规则适用} ∪
{应用自定义执行逻辑规则适用}

适用响应过程

适用响应本身的调用过程并不复杂,在增加了上文的相应链式结构之后只需要在响应模式层通过 Callback 发起一个 Invoke() 方法,后续的调用就会自动的依次执行,比较复杂的步骤在于响应委托(Delegate)与具体执行方法的绑定过程。因此为了隔离策略系统对于策略对象 PolicyBase 的使用和具体 PolicyBase 对象的复杂的绑定构造过程,这里引入了工厂模式(Factory Pattern) + 构造器模式(Builder Pattern)。策略系统对于 PolicyBase 的使用全部通过 PolicyFacotryBase 获得,而在 PolicyBase 实例化之后相关的委托绑定工作则是通过 PolicyCallHandlerBuilder 完成,绑定的依据则是由 PolicyBase 执行上下文(动态的回调方法)结合响应机制的配置部分(配置好的相对固定的回调方法)获取的。

图 6:适用响应对象的生成机制

适用执行过程中的异常

策略控制作为一个纵向贯穿其他业务流程的“外壳”内容,在其使用匹配、响应机制、自身调度逻辑甚至于具体 PolicyBase 内部都有可能产生异常。但是由于其执行过程已经和外部业务控制部分有所关联,因此如何保证不同等级策略对象不同异常情况下的处理措施就成为一个必须考虑的问题。首先,处置的决定是个双方面的对碰结果,在考虑到策略异常严重程度同时也要兼顾到业务流程自身的时效性、连贯性;其次,总体上策略系统需要有一个默认异常容忍程度,也就是总体上控制策略对象在外界看来的异常行为;其三,为了适应对碰过程,需要对于原有业务逻辑进行一定程度的适应性修改,为了把影响减小到最小程度,要尽量围绕元数据扩展。

注:如果业务逻辑处理方法内部也需要在不同执行步骤间切换其重要性,那么需要额外定制相关上下文重要性属性的表示机制,本文不展开这个部分)

图 7:策略异常处置过程的静态设计

说明:

  1. 整体的策略系统异常容忍程度由 PolicyExceptionSwitch 管理,由于相关的读取和更新过程频率相对很低,因此被设计为一个单件模式(Singleton Pattern)的部分,他仅仅通过一个静态的 LoadTolerationLevel()方法一次性的获得当前的容忍度配置,并通过静态的 CurrentLevel 属性供外部策略系统访问。
  2. 对于应用的改造仅需要应用一个 CriticalLevelAttribute 装饰在方法、类之上,只需要采用声明(Declarative)方式使用。
  3. 策略系统自身的错误全部继承自 PolicyExceptionBase,它与业务逻辑的重要程度对碰依据共同引用的 CriticalLevel 枚举完成,至于是否可以最终报出异常则是通过 PolicyExceptionBase 自己的 CouldRaise 方法在权衡了 TolerationLevel、应用 CriticalLevel 和策略对象自身 CriticalLevel 三方后的结果。

策略对象适用的说明

经过上面步骤确保 PolicyBase 可以根据需要用匹配规则在多个层次、多个方法适用到具体的业务执行对象,并且通过适用响应过程对于命中的对象或者策略系统自身、策略系统外部通过委托进行调用。总体的适用流程如下:

图 8:策略的适用总体流程

图 9:示例日志系统静态布局

具体到示例日志系统,一个可选的策略适用布局如下:

  1. 业务数据适用:ILogEntity 和 ISource 作为日志系统的入口可以将业务数据策略的适用布置在这个类型上,相应的 ITraceListener 作为日志系统的出口,也适合采用业务数据适用方式。同时,IRender、IFilter 作为直接操作业务数据形式的类型,一样也适用这种模式。
  2. 元数据适用:元数据一般作用于相对宏观调节的部分,示例日志系统中 FilterManagerBase、LogWriter 作为类似角色的类型非常适于采用元数据适用方式。
  3. 执行逻辑适用:原则上这种适用模式可以应用于日志系统中任何类型,但一般而言除非非常必要不应该采用这种模式。即便适用,在本示例中也应该应用于某些细枝末节的类型上,例如:IRender、IFilter、IPublisher、ITraceListener 这些接口的实现类。对于某些远程组件调用,由于其逻辑位置可能位于业务系统(例如:本文的日志系统)内部、也有可能采用委托方式位于外部逻辑部分,物理位置上可能跨越不同的服务器,可以根据保护敏感服务器、限制网络访问方式的目的继承 PolicyBase 完成一个类似 IPSec 功能的 IpSecPolicy,将企业内部各个应用平台对于敏感 IP、敏感网络访问方式的适用以一个策略对象的方式实现,进而通过嵌入每个相关应用的关键执行逻辑部分的办法实现应用层的 IP 访问逻辑控制。

策略的调度

在完成了上述策略对象的定义并将其与具体业务逻辑点对点的适用完成后,接下来的工作就是设计如何从一个毛坯的角度考虑一组策略对象 PolicyBase 的调度问题,主要包括:

  1. 策略对象的聚合:包括线性结构的策略对象集合、层次结构策略对象集合,并且通过这个聚合关系可以表示出不同策略间执行的依赖关系。
  2. 策略对象的缓冲和更新计划:考虑到策略对象自身的过期机制本身是个动态的过程,因此对于一个高可用持续运行的企业信息系统而言,策略系统自身要有维护能力,换言之就是根据业务逻辑的调用需要适时加载、缓冲和替换掉策略对象。
  3. 策略对象的持久化和实例化:虽然策略对象的编译结果是以二进制的 Assembly 方式保存在 I/O 上,但是考虑到运营的需要很多策略对象所依赖的配置信息一般都是以平文本或者 XML 化的配置文件方式保存在持久层,因此持久化与实例化的调度关系需要增加额外的机制来管理。
  4. 策略对象持久阶段的安全保护:由于策略系统本身被设计为一个贯穿了企业所有应用换几个机制,因此其影响力贯穿到企业整个信息环境之中,为了确保相关策略在发布到一个分布式系统环境后仍然可以忠实地执行企业策略定义的初衷,必须要为策略对象提供可以验证其真实性、保护其私密性的机制。

策略对象的聚合

最简单的方式就是一个线性结构,也就是可以通过 List 来实现策略的聚集,但是考虑到企业应用中策略对象的执行本身往往具有相互间的依赖关系,在排除了循环依赖之后策略的聚合关系可以被描述为层次型结构。而对于高层的策略系统使用而言,如果执行过程必须要了解聚合后的复杂内部组织关系,那么随着业务要求快速变化导致的聚合关系组织结构变化也会对策略系统的维护引发不利的影响。为此需要每种聚合关系下的抽象集合类型自身具有简单的可遍历接口的,解决方式也参考上文采取的迭代器模式(Iterator Pattern)。同时为了简化客户程序所需要面对的策略聚合结构,直接扩展 PolicyBase,使其同时也具有容器特性的组合关系,也就是用组合模式(Composite Pattern)改造 PolicyBase。

图 10:增加了迭代器和组合特征后的 PolicyBase

说明:

  1. PolicyBase 内部保存了一个 DependentPolicys 的属性,用于引用所有以来的 PolicyBase,同时也为 PolicyBase 的联动提供可能。
  2. 通过 IEnumerator + yield Return T 的方式 PolicyBase 为遍历提供可能,这样可以在客户程序不了解内部组织的情况下按照顺序方式访问到 PolicyBase 中的依赖对象。
  3. 对于线性结构的聚合可以简单的通过 List 获得,而随着策略系统的负责,如果需要采用后面所说的层次型结构的情况,因为 PolicyBase 的 Composite 特性所以不需要额外引入新的对象。

策略对象的缓冲和更新计划

由于影响力的全局性,策略系统自身的运行效率将会对企业整个信息环境的运行效果产生一定的影响,为此要借助必要的缓冲机制为整个策略系统助力,因此调度的主要工作集中在一个内存中缓冲的对策略对象,而外围仅仅围绕这个缓冲机制提供加载和销毁的更新机制。

图 11:策略对象缓冲和更新抽象逻辑视图

图 12:策略对象的缓冲和更新静态结构

说明:

  1. 为了充分利用缓冲,所有策略对象的获取(当策略适用于上文提及的数据对象、元数据对象和业务流程对象)全部通过 PolicyCacheManager 间接获取,接着客户程序可以通过引用 PolicyCacheManager 以一个字典的方式按名称依次访问每个策略缓冲 PolicyCache 对象。PolicyCacheManager 内部通过一个 Regist 方法注册 PolicyBase,判断后将没有被缓冲的 PolicyBase 通过 PolicyCache 的构造函数包装为一个对应的 PolicyCache,然后缓冲到字典 Caches 中。
  2. 考虑到后续 PolicyCacheManager 可能的扩展,所有 PolicyCacheManager 的获取通过一个工厂方式的 PolicyCacheManagerFactory 获得。
  3. 相关 PolicyCache 的维护则是通过集中的 PolicyCacheScheduler 参考 PeriodOfValidadity 结构并交由每个具体 PolicyExpirationWorkItem 完成的。
  4. 为了减轻 PolicyCacheScheduler 的工作量,增加了一个适于异步调用的 PolicyCacheExpirationHandler 委托(Delegate),PolicyExpirationWorkItem 在获得 PolicyCacheScheduler 的定义后自身(而不是再次经由 PolicyCacheScheduler)与缓冲对象交互。

策略对象的持久化和相关安全性加固

这部分是整个策略系统进一步从逻辑抽象到实际物理部分的衔接,它主要管理缓冲部分的外延——持久层,考虑到企业内部不同应用的安全敏感性本身不同,而且不同应用的数据库、存储选型也不同,因此需要增加不同的 Provider 类型来适应这些不同。为了剥离不同角色的 Provider,并为进一步组合提供可能,这里设计的 Provider 包括两类:Store Provider 和 Encryption Provider,前者负责与持久层交互的 Provider,后者负责提供相关加密处理的支持。在 Store Provider 之上通过抽象的 Store 对象来完成抽象的持久化操作。静态设计如下:

图 13:策略对象的持久化和安全性加固设计

说明:

  1. 这部分虽然多变,但是逻辑流程本身相对简单,使用上需要在 PolicyBase 的实例化过程中通过抽象的 PolicyStoreBase 经由 PolicyStoreFactoryBase 间接获得。
  2. PolicyStoreBase 则根据配置基于逻辑层面的持久化操作通过调度抽象的 IStoreProvider 和 IEncryptionProvider 来完成安全加固后的持久化操作。

策略调度的说明

策略调度过程完成了策略系统架构的必要高层逻辑机制,相关机制在基础的策略对象之上实现了从持久层一直到逻辑聚合的过程,下面的介绍就有关是怎么将这些调度机制排列组合(也就是架构过程),并增加相关适应性措施确保其可以被部署到企业信息环境中。参考本文示例,现有的技术组成高层逻辑视图如下:

图 14:策略系统的核心逻辑组成

说明:

  1. 策略适用作为核心的交接组成,部分位于核心框架内,部分外延到外部业务逻辑系统,这其中一方面包括日志系统自定义的业务逻辑适用也包括基本策略对象的回调委托。
  2. 为了让整个核心更加“聪明”、更贴近于逻辑层(虽然调度和适用部分没有展开),但是相关更新规则、聚合依赖关系一样可以建立在整体的规则引擎之上。
  3. 现有策略核心部分暂时只完成了有关异常的生成,但是没有对完成其响应机制,主要原因在于其相关处置需要在更上面的整体架构层次与企业环境的其他服务进行集成。 ## 策略系统的架构

上文中策略系统的核心已经设计成型,并且使用到了“企业安全服务”和“持久层服务”两个外部服务,本节的主要重点则是关注与“怎样设计一个易于部署和运行维护”的系统架构。这主要包括如下几个方面:

  1. 提供完善的配置系统,确保系统上线后可以在生产环境下由系统管理人员(而不是开发人员)对于运行的系统进行配置,并且相应的配置更改可以快速的被策略系统感知。
  2. 提供实时运行监控措施,确保一般的运行监控人员可以随时把策略系统当作一个“灰盒子”(相对于二进制系统的“黑盒子”和完全静态代码状态的“白盒子”而言),随时看到各个组成的健康状态、吞吐量等运行指标。
  3. 对于来自核心的异常(也就是违背策略的调用或者是策略系统自身的运行异常)定义何种通知机制,如何按照企业环境中不同角色的要求把他所需要的异常按照指定的方式提供出去。
  4. 最后就是策略系统自身如何适应 Scale out 方式的高可用扩展。

配置管理机制

配置机制的主要目的是为策略系统提供集成测试阶段、准运行阶段、生产运行阶段的动态管理,配置主要包括两个颗粒度层次:

  1. 面向策略系统运行结构的配置
  2. 面向具体策略对象的配置(包括其匹配规则、响应机制)

考虑到策略系统自身是个对象化系统,而配置信息本身以层次型的 XML 或关系数据库方式存在,因此需要在它们之间作一个过渡,也就是配置到对象的映射系统,笔者称之为 COM(Configuration – Object Mapping)。在 System.Configuration 中已经有了一套对象化的配置信息基类可以加以利用:

  1. System.Configuration.ConfigurationElement
  2. System.Configuration.ConfigurationElementCollection
  3. System.Configuration.ConfigurationSection
  4. System.Configuration.ConfigurationSectionCollection
  5. System.Configuration.ConfigurationSectionGroup
  6. System.Configuration.ConfigurationSettings
  7. … …

但是使用上由于策略控制的全局性,因此现有 System.Configuration 还需要进行部分扩展从而利于策略系统的展开:

  1. 策略本身具有层次性,因此策略系统的配置文件可能同时具有企业级的也具有应用级的,例如:本文示例的日志部分可能仅仅是一个进销存项目的一个部件,同时该项目还包括数据访问部分、授权管理部分,因此该项目可能需要有自身的应用层策略,用于贯穿日志、数据访问、授权等部分,同时他还要遵循企业全局性的一些策略要求。因此,策略系统对该项目实际控制内容的配置来自于两个方面,相应的配置节(Configuration Section)和配置节组(Configuration Section Group)也可能物理的分散在不同配置文件中。实现上可以采用 ConfigurationLocation 定义相关配置节(或配置节组)的外部地址,然后通过平台的配置机制借助上面列举的统一配置类型反馈配置信息,目的就是对于策略系统核心部分而言看到的是逻辑上唯一的配置文件。
  2. 对于每个 PolicyBase 而言(尤其是自定义的策略类型),他的配置节本身是多样化的,而且复杂程度各异,例如:上面提到的“用户姓名保密策略”和“仿 IPSec 网络访问策略”所需的配置节层次关系本身就存在很大的差异。为了简化配置文件部分的工作,可以考虑采用 XML 数据库方式保存各个分散的配置节,同时使用的时候也需要提供类似的对象化配置类型,实现上可以考虑 XPath + DOM 方式完成一个抽象基类,并在各 PolicyBase 实体子类中利用基类的通用 XPath 定位机制扩展出自己的对象化配置类型。

总体架构结构如下:

图 15:策略系统的配置子系统

说明:

  1. 所有提供给策略系统核心的配置项全部对象化,这个集中的工作由“配置对象系统”完成。
  2. 全局配置文件通过 ConfigurationLocation 指定,并通过 System.Configuration 与本地配置合并为一个统一的配置,以 System.Configuration 相关对象化配置类的形式提供给“配置对象系统”。
  3. 自定义的配置信息保存在支持 XML 存储(也可以采用注册表、LDAP 保存,不过实现上相对繁琐)的配置库中,通过“自定义配置解析库”借助 XPath 和 DOM 的解析生成自定义配置节(配置节组)的对象化配置类型,统一提供给“配置对象系统”。

运行监控机制

对于运行系统的检查更多内容可以很宽泛的归纳到“运行监控”范畴,不仅仅设计必要的日志采集系统,还要对集成的各个产品进行实时运行状况的监控。一般可以通过 MOM 配合 SMS 完成类似工作,应用级的 Performance Counter 也会提供很多实时的运行指标。在充分“假于物也”的前提下,可以按照下面的步骤实施相关运行监控措施:

图 16:运行监控实施步骤

说明:

  1. 运行指标需求分析阶段主要收集策略系统监控所需要的主要度量指标,并将其分门别类。
  2. 然后,根据企业现有监控产品的技术覆盖,尽量多的将可以由工具完成的工作划归过去,只把需要定制的内容划入自定义开发范畴。
  3. 考虑到策略系统对于策略核心部分影响尽可能小的因素,采用基于属性(Attribute)的元数据扩展机制。属性使用 System.Diagnostics 提供的 Performance Counter 类型定义各性能指标所依赖的性能计数器。
  4. 最后,整个平台(工具、自定义开发性能属性)归口到 CLR 和操作系统平台的 WMI 体系上。

策略系统的通知机制

从某个程度上说,如果策略系统总是“默默无闻”得做着后台存技术处理,那么它的价值将大打折扣(甚至于说成为无意义的运行负担),只有当它可以有效地把策略执行情况报告出来,并为企业各个层面的相关人员所了解才真正完成了策略系统一个技术投入到技术产出的过程。通知机制总体上是个异步的过程,不同角色人员首先选择(或者被配置)其所关心的策略通知类型,接着在某时某刻策略系统发现有需要的内容就按照预先定义好的数据保存形式和传输方式呈递过去,这里有个时间差,选择的过程和实际的呈递过程可能相差几秒钟、几天、几个月,甚至根本就没有呈递。因此,这里采用“出版——预定”的模式通过在策略系统中增加一个通知协调措施异步的代理这个过程的执行。

步骤一:前期策略通知的预定过程

图 17:策略通知自系统前期预定

说明:

  1. 首先通知机制根据核心部分的异常定义内容分类列出各类可能提供的事件情况。
  2. 然后,业务用户或者业务角色根据自己的工作需要借助“预定界面”展示的参考列表选择需要预定的通知事件,并且将所需了解的事件(及其数据格式、发送方式等)登记到“预定情况列表”。

步骤二:策略系统事件的收集

图 18:策略事件收集

说明:

  1. 系统各处的异常均通过相应的 Provider 集中,然后汇总到“策略系统事件列表”。
  2. 每个 Provider 负责将分散的事件信息统一成事件列表所需要的格式。
  3. “策略系统事件列表”除了保存每个事件本身外,还需要为每个事件增加一个时间戳(TimeStamp)用于保存事件的次序,增加一个事件源管理,确保事件的可追溯性。
  4. 同时考虑到某些业务环节(例如:本文示例中按照“用户姓名保密策略”需要为日志 LogEntityBase 的相关字段加密,但是由于企业安全服务不稳定会导致该“业务数据适用”频繁失败)可能会短时间内频繁产生大量同信息事件,为了不对整个策略系统造成严重负载,这里需要增加一个根据最近最少算法(LRU)的缓冲部分,用于合并短期内反复出现的事件。

步骤三:通知的生成

上述步骤完成了事件的定义、事件的收集,但是发生的事件不一定要通知,这里通过“通知生成”机制完成这个转化过程:

图 19:策略系统通知的生成

说明:

  1. “通知生成机制”借助规则引擎来对碰“策略系统事件列表”和“预定情况列表”,当发现满足要求的事件后,将必要的事件内容和预订内容打包保存到“策略系统通知列表”。

步骤四:通知的发布

在通知内容生成后,“通知发布机制”的作用就是按照描述的内容把通知呈递给业务用户(或属于某些业务角色的一组用户)。

图 20:通知的发布

说明:

  1. 发布主要完成两项工作:按照预先定义的呈现方式包装通知、按照预先选择的呈递方式发送通知。“通知呈现方式处理”部分完成前者,各类不同的呈递通道(Exchange、MSMQ、FTP、HTTP、SMS)完成后者。
  2. 各个呈递通道部署上要尽量采用企业现有各类网络服务,对于具有短信平台的企业更多的可以把通知发布和通知响应集成,通过移动的智能设备在一个更大的物理范围内扩展策略系统的影响。

至此,上述 4 个步骤完成了一个起始于用户回归于用户的闭环,确保整个策略系统与用户的联动,完成了相应技术投入到技术产出的过程。

图 21:策略系统的用户联动

高可用问题

上文介绍了如何把策略管理对用户服务,如何将运行维护人员纳入到策略系统中的问题,下面就是如何尽可能得让这种应用环境持续可用。通过提升硬件配置(Scale Up)方式获得更高的可用性的途径暂不考虑,如何确保策略系统可以适应企业内部跨应用环境的水平展开(Scale Out)是一个必须解决的问题,也就是如何确保策略系统可以在一个冗余设备的环境下以一个逻辑整体的方式持续作用于企业信息化环境的问题。

从上文的介绍不难发现,调度部分、适用部分、运行监控部分(由于采用了分布式方式的 WMI)、通知部分本身都是可以拆解的执行体,唯有他们依赖的配置部分由于具有全局性的配置文件和应用自定义配置库存在,因此需要在展开的时候确保各个节点间内容的一致性,也就表明这个部分是需要实施高可用的关键部分。由于设计上自定义配置库一般采用数据库方式,因此这部分利用企业现有数据库集群扩展即可,而全局性的配置文件因为内容相对简单,文件容量也相对不多,使用文件集群有些大材小用,因此仅仅需要在企业内部 Web 服务器集群中选择一个位置,允许内部各个使用了策略控制的应用通过 URL 方式访问即可,至此解决了策略系统的全局依赖信息的高可用扩展。

图 22:高可用部署

总结

本文从“第一块砖头”开始介绍了整个策略控制环境的内容,从适用、调度、架构等几个侧面说明了一个个逻辑控制机制如何最终形成一个可以持续运行的系统。策略化控制作为企业信息化发展到一定阶段业务和技术共同潜在(或者已经浮出水面)的需求,如何实施上既要保证其控制到位、又要把对生产环境其他应用的影响降至最小是个持续优化的过程。

本文很多篇幅的设计是基于一个相对复杂成型的企业信息环境而言,实际实施中各位架构师和设计师朋友可以参考并裁减不合体的部分。同时,策略的适用上不仅仅包括文中提及的业务数据适用、业务执行逻辑适用、元数据适用三个纬度,数据库(或企业资料库)使用、应用生命期流程管理、编码规范性等这些不同层次的技术或管理要求同样可以作为策略适用纬度,依据上文的抽象化适用设计一样可以快速泛化出一个个可执行单元,并最终作用于各类企业应用中。


作者简介:王翔,全国海关信息中心高级架构师,从事海关主要广域分布式系统的设计和实施,多次参与各业务系统的优化。此外,作为信息安全工作组副组长,他还一直致力于应用密码技术和公钥基础设施保障海关业务的安全运行。此外,他还是《程序员》杂志的专栏作者。

编辑注:感谢百合网技术总监刘如鸿对本文的技术审校。

2007 年 4 月 15 日 21:34880
用户头像

发布了 61 篇内容, 共 58316 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

FontAwesome图标大全

入门小站

工具

架构学习模块二

George

【布道API】关于 API 分页

devpoint

API REST API 9 月日更

模块七课后作业

NewBranSTONE

#架构实战营

推荐三个实用的 Go 开发工具

AlwaysBeta

go golang golang新手 Go 语言从入门到实践

SpringMVC框架介绍

咿呀呀

springmvc 笔记 9月日更

网红郭老师遭全平台账号封禁,违背公序良俗的网红该被封杀

石头IT视角

模块七作业:王者荣耀商城异地多活架构设计

Felix

我在 InfoQ 创作的思路规划

baiyutang

写作技巧 9月日更

微服务架构下的熔断框架:hystrix-go

互联网架构师小马

Java中的流程控制之if语句

IT蜗壳-Tango

9月日更

Redis集群docker部署

非晓为骁

redis Docker redis集群

使用 Jackson – 将字符串转换为 JsonNode 对象

HoneyMoose

阿里P8整理出SQL笔记:收获不止SOL优化抓住SQL的本质,带你领略SQL的世界!

Java 白

Java MySQL 架构 面试 架构师

网络攻防学习笔记 Day129

穿过生命散发芬芳

日志分析 9月日更

2021年阿里高频Java岗面试真题:分布式+中间件+高并发+算法+数据库

Java技术那些事

Java 编程 程序员 面试 计算机

区块链赋能供应链金融风险管控探析

CECBC区块链专委会

去中心化身份务实

CECBC区块链专委会

如何修改 Discourse 的域名

HoneyMoose

金九银十保驾护航!面试还不懂Java高并发编程看阿里这份最新笔记就够了!

程序员小毕

Java 程序员 架构 面试 高并发

谈 C++17 里的 FlyWeight 模式

hedzr

c++ 设计模式 Design Patterns 享元模式 flyweight

linux之ssh命令

入门小站

Linux

13. AlphaGO带给人类的启示到底是什么

数据与智能

人工智能

架构实战营 1 期模块 7 作业——业务异地多活架构

tt

架构实战营

在 Discourse 中如何使用输入对话框

HoneyMoose

Navicat Premium 查询 x 列时不显示

玄兴梦影

MySQL navicat select

阿里内部流传的JDK源码剖析手册!GitHub已获上千万的访问量

Java 白

Java 编程 架构 jdk 面试

Java 8 及其后续版本的新遍历 forEach

HoneyMoose

原来搭建淘客项目如此简单,app、web、小程序轻松搞定

Silently9527

Java uniapp 淘宝客开源

国家发改委:利用区块链等新技术开展绿色电力交易试点

CECBC区块链专委会

IntelliJ IDEA 快速插入 for 循环

HoneyMoose

Study Go: From Zero to Hero

Study Go: From Zero to Hero

采用模式和泛型技术为应用增加策略控制(动态部分)-InfoQ