zoukankan      html  css  js  c++  java
  • 多层分布式设计模式

        原来就想写一些关于分布式的设计。正好目前开发的GIX4项目中,需要对客户端的许多操作进行记录。这个功能的设计或多或少能说明,一般情况下,多层的分布式系统应该如何设计。现在我就对这个功能进行描述。

    功能描述

        GIX4项目中有个审核日志记录功能,它需要以下功能:

        需要把客户的所有操作记录下来,以便支持审计。如,当用户进行:登录、打开模块、查看数据、点击按钮……等操作时,把相关的数据全部在服务器的数据库中记录下来,这些数据有:操作类型、操作时间、操作内容、操作者、客户端机器名等。

        在服务端对某些特定的事件进行记录,如:计算出错。

    设计目标

        这个模块需要支持以下目标:

        *为客户端代码、服务器端代码都提供简单统一的接口。

        *需要异步记录。

        *如果扩展为多级物理层时,也需要使用相同的接口。

    设计

        先把设计完成的图贴出来,然后再逐一描述:

    image

    图1 全部类图

    通用部分

        首先,API设计之初,先根据需求,定出使用的接口。它们包含两个类:一个是贫血数据类AuditLogItem,一个是对AuditLogItem进行操作的静态类AuditLogService。AuditLogService暂时公布两个静态方法,一个记录日志方法Log(),另一个方法是异步记录LogAsync()。如下:

    image

        由于各物理层都使用AuditLogService的方法,而实现不同。这里把使用了Provider模式,提取接口IAuditLogProvider,这里就不再需要异步方法了:

    /// <summary>
    /// 审计功能提供程序
    /// </summary>
    public interface IAuditLogProvider
    {
        /// <summary>
        /// 记录指定的日志
        /// </summary>
        /// <param name="log"></param>
        void Log(AuditLogItem log);
    }
    

        除了最终与数据库通信的服务器外,其它节点都默认使用ClientAuditLogProvider作为提供程序。此提供程序使用了ICommunication,而ICommunication则是负责向“下一节点”通信并提交日志记录功能。

    GIX4实现部分

        这部分主要是两个类:ServerAuditLogProvider 和 CSLACommandCommunication。

        ServerAuditLogProvider 使用CSLA的类库把AuditLogItem转换为相应的数据库模型存入数据库中:

    public class ServerAuditLogProvider : IAuditLogProvider
    {
        public void Log(AuditLogItem log)
        {
            var dbItem = AuditItem.New();
    
            dbItem.Title = log.Title;
            dbItem.Content = log.Content;
            dbItem.User = log.User;
            dbItem.MachineName = log.MachineName;
            dbItem.Type = log.Type;
            dbItem.LogTime = log.LogTime;
    
            dbItem.Save();
        }
    }

        CSLACommandCommunication 则是使用WCF和CSLA命令模式作为基础框架,让当前节点把请求发送给下一节点,下一节点接到请求后,使用本节点的提供程序Provider来处理请求。其中重要的代码在内部类AuditServerCommand中,如下:

    [Serializable]
    public class AuditServerCommand : Csla.CommandBase
    {
        private AuditLogItem _logItem;
    
        public AuditServerCommand(AuditLogItem logItem)
        {
            if (logItem == null) throw new ArgumentNullException("logItem");
    
            this._logItem = logItem;
        }
    
        protected override void DataPortal_Execute()
        {
            //server log
            AuditLogService.Log(this._logItem);
        }
    }

     

    整个过程

        整个过程其实很简单,一图胜千言:

    image

     

    后记

        其实本次设计过程的思路很简单:分析要提供的API(场景驱动)、分析分布式实现的差异、编写基础部分、编码与重构。

        其实熟悉CSLA的人应该知道,它里面的通信机制也是采用了类似的方式实现的。所以这应该算是一种分布式的设计模式吧。 :)

  • 相关阅读:
    技术面试之经验总结
    为何只有两篇文章?
    LOJ6364 烂柯
    mysql批量更新数据(性能优化)
    一个对象的key引发的血案
    总结与元素坐标相关的属性(再也搞不混了)
    利用nodejs搭建服务器,测试AJAX
    初探jquery之强大丰富的选择器
    Web前端开发规范手册
    IE8下标签float导致的bug。
  • 原文地址:https://www.cnblogs.com/zgynhqf/p/1682403.html
Copyright © 2011-2022 走看看