精华内容
参与话题
问答
  • SOFA企业应用框架

    万次阅读 多人点赞 2018-02-08 10:37:29
    前言从业这么多年,接触过银行的应用,Apple的应用,eBay的应用和现在阿里的应用,虽然分属于不同的公司,使用了不同的架构,但有一个共同点就是都很复杂。导致复杂性的原因有很多,如果从架构的层面看,主要有两点...

    前言

    从业这么多年,接触过银行的应用,Apple的应用,eBay的应用和现在阿里的应用,虽然分属于不同的公司,使用了不同的架构,但有一个共同点就是都很复杂。导致复杂性的原因有很多,如果从架构的层面看,主要有两点,一个是架构设计过于复杂,层次太多能把人绕晕。另一个是根本就没架构,ServiceImpl作为上帝类包揽一切,一杆捅到DAO(就简单场景而言,这种Transaction Script也还凑合,至少实现上手都快),这种人为的复杂性导致系统越来越臃肿,越来越难维护,酱缸的老代码发出一阵阵恶臭,新来的同学,往往要捂着鼻子抠几天甚至几个月,才能理清系统和业务脉络,然后又一头扎进各种bug fix,业务修补的恶性循环中,暗无天日!
    image.png
    CRM作为阿里最老的应用系统,自然也逃不过这样的宿命。不甘如此的我们开始反思到底是什么造成了系统复杂性? 我们到底能不能通过架构来治理这种复杂性?基于这个出发点,我们团队开始了一段非常有意义的架构重构之旅(Redefine the Arch),期间我们参考了SalesForce,TMF2.0,汇金和盒马的架构,从他们那里汲取了很多有价值的输入,再结合我们自己的思考最终形成了我们自己现在的基于扩展点+元数据+CQRS+DDD的应用架构。该架构的特点是可扩展性好,很好的贯彻了OO思想,有一套完整的规范标准,并采用了CQRS和领域建模技术,在很大程度上可以降低应用的复杂度。本文主要阐述了我们的思考过程和架构实现,希望能对在路上的你有所帮助。

    复杂性来自哪里

    经过我们分析、讨论,发现造成现在系统异常复杂的罪魁祸首主要来自以下四个方面:

    可扩展性差

    对于只有一个业务的简单场景,并不需要扩展,问题也不突出,这也是为什么这个点经常被忽略的原因,因为我们大部分的系统都是从单一业务开始的。但是随着支持的业务越来越多,代码里面开始出现大量的if-else逻辑,这个时候代码开始有坏味道,没闻到的同学就这么继续往上堆,闻到的同学会重构一下,但因为系统没有统一的可扩展架构,重构的技法也各不相同,这种代码的不一致性也是一种理解上的复杂度。久而久之,系统就变得复杂难维护。像我们CRM应用,有N个业务方,每个业务方又有N个租户,如果都要用if-else判断业务差异,那简直就是惨绝人寰。其实这种扩展点(Extension Point),或者叫插件(Plug-in)的设计在架构设计中是非常普遍的。比较成功的案例有eclipse的plug-in机制,集团的TMF2.0架构。还有一个扩展性需求就是字段扩展,这一点对SaaS应用尤为重要,因为有很多客户定制化需求,但是我们很多系统也没有统一的字段扩展方案。

    面向过程

    是的,不管你承认与否,很多时候,我们都是操着面向对象的语言干着面向过程的勾当。面向对象不仅是一个语言,更是一种思维方式。在我们追逐云计算、深度学习、区块链这些技术热点的时候,静下心来问问自己我们是不是真的掌握了OOD;在我们强调工程师要具备业务Sense,产品Sense,数据Sense,算法Sense,XXSense的时候,是不是忽略了对工程能力的要求。据我观察大部分工程师(包括我自己)的OO能力还远没有达到精通的程度,这种OO思想的缺乏主要体现在两个方面,一个是很多同学不了解SOLID原则,不懂设计模式,不会画UML图,或者只是知道,但从来不会运用到实践中;另一个是不会进行领域建模,关于领域建模争论已经很多了,我的观点是DDD很好,但不是银弹,用和不用取决于场景。但不管怎样,请你抛开偏见,好好的研读一下Eric Evans的《领域驱动设计》,如果有认知升级的感悟,恭喜你,你进阶了。我个人认为DDD最大的好处是将业务语义显现化,把原先晦涩难懂的业务算法逻辑,通过领域对象(Domain Object),统一语言(Ubiquitous Language)将领域概念清晰的显性化表达出来。相信我,这种表达带来的代码可读性的提升,会让接手你代码的人对你心怀感恩的。借用Abelson的一句话是

    Programs must be written for people to read, and only incidentally for machines to execute

    所以强烈谴责那些不顾他人感受的编码行为。

    分层不合理

    俗话说的好,All problems in computer science can be solved by another level of indirection(计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决),怎样? 是不是感受到间接层的强大了。分层最大的好处就是分离关注点,让每一层只解决该层关注的问题,从而将复杂的问题简化,起到分而治之的作用。我们平时看到的MVC,pipeline,以及各种valve的模式,都是这个道理。好吧,那是不是层次越多越好,越灵活呢。当然不是,就像我开篇说的,过多的层次不仅不能带来好处,反而会增加系统的复杂性和降低系统性能。就拿ISO的网络七层协议来说,你这个七层分的很清楚,很好,但也很繁琐,四层就够了嘛。再比如我前面提到的过度设计的例子,如果没记错的话应该是Apple的Directory Service应用,整个系统有7层之多,把什么validator,assembler都当成一个层次来对待,能不复杂么。所以分层太多和没有分层都会导致系统复杂度的上升,因此我们的原则是不可以没有分层,但是只分有必要的层

    随心所欲

    随心所欲是因为缺少规范和约束。这个规范非常非常非常的重要(重要事情说三遍),但也是最容易被无视的点,其结果就是架构的consistency被严重破坏,代码的可维护性将急剧下降,国将不国,架构将形同虚设。有同学会说不就是个naming的问题么,不就是个分包的问题么,不就是2个module还是3个module的问题么,只要功能能跑起来,这些问题都是小问题。是的,对于这些同学,我再丢给你一句名言“Just because you can, doesn't mean you should"。就拿package来说,它不仅仅是一个放一堆类的地方,更是一种表达机制,当你将一些类放到Package中时,相当于告诉下一位看到你设计的开发人员要把这些类放在一起考虑。理想很丰满,现实很骨感,规范的执行是个大问题,最好能在架构层面进行约束,例如在我们架构中,扩展点必须以ExtPt结尾,扩展实现必须以Ext结尾,你不这么写就会给你抛异常。但是架构的约束毕竟有限,更多的还是要靠Code Review,暂时没想到什么更好的办法。这种对架构约束的近似严苛follow,确保了系统的consistency,最终形成了一个规整的收纳箱(如下图所示),就像我和团队说的,我们在评估代码改动点时,应该可以像Hash查找一样,直接定位到对应的module,对应的package里面对应的class。而不是到“一锅粥”里去慢慢抠。
    image.png
    本章节最后,上一张我们老系统中比较典型的代码,也许你可以从中看到你自己应用的影子。
    sample.png

    复杂性应对之道

    知道了问题所在,接下来看下我们是如何一个个解决这些问题的。回头站在山顶再看这些解决方案时,每个都不足为奇,但当你还“身在此山中”的时候,这个拨开层层迷雾,看到山的全貌的过程,并不是想象的那么容易。庆幸的是我团队在艰难跋涉之后,终有所收获。

    扩展点设计

    扩展点的设计思想主要得益于TMF2.0的启发,其实这种设计思想也一直在用,但都是在局部的代码重构和优化,比如基于Strategy Pattern的扩展,但是一直没有找到一个很好的固化到框架中的方法。直到毗卢到团队分享,给了我们两个关键的提示,一个是业务身份识别,用他的话说,如果当时TMF1.0如果有身份识别的话,就没有TMF2.0什么事了;另一个是抽象的扩展点机制。

    身份识别

    业务身份识别在我们的应用中非常重要,因为我们的CRM系统要服务不同的业务方,而且每个业务方又有多个租户。比如中供销售,中供拍档,中供商家都是不同的业务方,而拍档下的每个公司,中供商家下的每个供应商又是不同的租户。所以传统的基于多租户(TenantId)的业务身份识别还不能满足我们的要求,于是在此基础上我们又引入了业务码(BizCode)来标识业务。所以我们的业务身份实际上是(BizCode,TenantId)二元组。在每一个业务身份下面,又可以有多个扩展点(ExtensionPoint),所以一个扩展点实现(Extension)实际上是一个三维空间中的向量。借鉴Maven Coordinate的概念我给它起了个名字叫扩展坐标(Extension Coordinate),这个坐标可以用(ExtensionPoint,BizCode,TenantId)来唯一标识
    image.png

    扩展点

    扩展点的设计是这样的,所有的扩展点(ExtensionPoint)必须通过接口申明,扩展实现(Extension)是通过Annotation的方式标注的,Extension里面使用BizCode和TenantId两个属性用来标识身份,框架的Bootstrap类会在Spring启动的时候做类扫描,进行Extension注册,在Runtime的时候,通过TenantContext来选择要使用的Extension。TenantContext是通过Interceptor在调用业务逻辑之前进行初始化的。整个过程如下图所示:
    image.png

    面向对象

    面向对象不仅是一种编程语言,更是一种思维模式。所以看到很多简历里面写“精通Java”,没写“精通OO”,也算是中肯,因为会Java语言并不代表你就掌握了面向对象思维(当然,精通Java也不是件易事),要想做到精通,必须要对OO设计原则,模式,方法论有很深入的理解,同时要具备非常好的业务理解力和抽象能力,才能说是精通,这种思维的训练是一个长期不断累积的过程,我也在路上,下面是我对面向对象设计的两点体会:

    SOLID

    SOLID是单一职责原则(SRP),开闭原则(OCP),里氏替换原则(LSP),接口隔离原则(ISP)和依赖倒置原则(DIP)的缩写,原则是要比模式(Design Pattern)更基础更重要的指导准则,是面向对象设计的Bible。深入理解后,会极大的提升我们的OOD能力和代码质量。比如我在开篇提到的ServiceImpl上帝类的例子,很明显就是违背了单一职责,你一个类把所有事情都做了,把不是你的功能也往自己身上揽,所以你的内聚性就会很差,内聚性差将导致代码很难被复用,不能复用,只能复制(Repeat Yourself),其结果就是一团乱麻。
    image.png
    再比如在java应用中使用logger框架有很多选择,什么log4j,logback,common logging等,每个logger的API和用法都稍有不同,有的需要用isLoggable()来进行预判断以便提高性能,有的则不需要。对于要切换不同的logger框架的情形,就更是头疼了,有可能要改动很多地方。产生这些不便的原因是我们直接依赖了logger框架,应用和框架的耦合性很高。怎么破? 遵循下依赖倒置原则就能很容易解决,依赖倒置就是你不要直接依赖我,你和我都同时依赖一个接口(所以有时候也叫面向接口的编程),这样我们之间就解耦了,依赖和被依赖方都可以自由改动了。
    image.png
    在我们的框架设计中,这种对SOLID的遵循也是随处可见,Service Facade设计思想来自于单一职责SRP;扩展点设计符合关闭原则OCP;日志设计,以及Repository和Tunnel的交互就用到了依赖倒置DIP原则,这样的点还有很多,就不一一枚举了。当然了,SOLID不是OO的全部。抽象能力,设计模式,架构模式,UML,以及阅读优秀框架源码(我们的Command设计就是参考了Activiti的Command)也都很重要。只是SOLID更基础,更重要,所以我在这里重点拿出来讲一下,希望能得到大家的重视。

    领域建模

    准确的说DDD不是一个架构,而是思想和方法论。所以在架构层面我们并没有强制约束要使用DDD,但对于像我们这样的复杂业务场景,我们强烈建议使用DDD代替事务脚本(TS: Transaction Script)。因为TS的贫血模式,里面只有数据结构,完全没有对象(数据+行为)的概念,这也是为什么我们叫它是面向过程的原因。然而DDD是面向对象的,是一种知识丰富的设计(Knowledge Rich Design),怎么理解?,就是通过领域对象(Domain Object),领域语言(Ubiquitous Language)将核心的领域概念通过代码的形式表达出来,从而增加代码的可理解性。这里的领域核心不仅仅是业务里的“名词”,所有的业务活动和规则如同实体一样,都需要明确的表达出来。例如前面典型代码图中所展示的,分配策略(DistributionPolicy)你把它隐藏在一堆业务逻辑中,没有人知道它是干什么的,也不会把它当成一个重要的领域概念去重视。但是你把它抽出来,凸显出来,给它一个合理的命名叫DistributionPolicy,后面的人一看就明白了,哦,这是一个分配策略,这样理解和使用起来就容易的多了,添加新的策略也更方便,不需要改原来的代码了。所以说好的代码不仅要让程序员能读懂,还要能让领域专家也能读懂
    再比如在CRM领域中,公海和私海是非常重要领域概念,是用来做领地(Territory)划分的,每个销售人员只能销售私海(自己领地)内的客户,不能越界。但是在我们的代码中却没有这两个实体(Entity),也没有相应的语言和其对应,这就导致了领域专家描述的,和我们日常沟通的,以及我们模型和代码呈现的都是相互割裂的,没有关联性。这就给后面系统维护的同学造成了极大的困扰,因为所有关于公海私海的操作,都是散落着各处的repeat itself的逻辑代码,导致看不懂也没办法维护。所以当尚学把这两个领域概念抽象成实体之后,整个模型和代码都一下子变清晰很多。在加上上面介绍的把业务规则显现化,极大的提升了代码的可读性和可扩展性。用尚学的话说,用DDD写代码,他找到了创作的感觉,而不仅仅是码农式Coding。下图是销售域的简要领域模型,但基本上能表达出销售域的核心领域概念。
    image.png
    关于CQRS简要说一下,我们只使用了Command,Query分离的概念,并没有使用Event Sourcing,原因很简单---不需要。关于Command的实现我们使用了命令模式,因此以前的ServiceImpl的职责就只是一个Facade,所有的处理逻辑都在CommandExecutor里面。

    分层设计

    这一块的设计比较直观,整个应用层划分为三个大的层次,分别是App层,Domain层和Repostiory层。

    • App层主要负责获取输入,组装context,做输入校验,发送消息给领域层做业务处理,监听确认消息,如果需要的话使用MetaQ进行消息通知;
    • Domain层主要是通过领域服务(Domain Service),领域对象(Domain Object)的交互,对上层提供业务逻辑的处理,然后调用下层Repository做持久化处理;
    • Infrastructure层主要包含Repository,Config和Common,Repository负责数据的CRUD操作,这里我们借用了盒马的数据通道(Tunnel)的概念,通过Tunnel的抽象概念来屏蔽具体的数据来源,来源可以是MySQL,NoSql,Search,甚至是HSF等;Config负责应用的配置;Common是一写工具类;负责message通信的也应该放在这一层。 image.png这里需要注意的是从其他系统获取的数据是有界上下文(Bounded Context)下的数据,为了弥合Bounded Context下的语义Gap,通常有两种方式,一个是用大领域(Big Domain)把两边的差异都合起来,另一个是增加防腐层(Anticorruption Layer)做转换。什么是Bounded Context? 简单阐述一下,就是我们的领域概念是有作用范围的(Context)的,例如摇头这个动作,在中国的Context下表示NO,但是在印度的Context下却是YES。

    规范设计

    我们规范设计主要是要满足收纳原则的两个约束:

    放对位置

    东西不要乱放,我们的每一个组件(Module),每一个包(Package)都有明确的职责定义和范围,不可以放错,例如extension包就只是用来放扩展实现的,不允许放其他东西,而Interceptor包就只是放拦截器的,validator包就只是放校验器的。我们的主要组件如下图:
    image.png
    组件里面的Package如下图:
    image.png

    贴好标签

    东西放在合适位置后还要贴上合适的标签,也就是要按照规范合理命名,例如我们架构里面和数据有关的Object,主要有Client Object,Domain Object和Data Object,Client Object是放在二方库中和外部交互使用的DTO,其命名必须以CO结尾,相应的Data Object主要是持久层使用的,命名必须以DO结尾。这个类名应该是自明的(self-evident),也就是看到类名就知道里面是干了什么事,这也就反向要求我们的类也必须是单一职责的(Single Responsibility)的,如果你做的事情不单纯,自然也就很难自明了。如果我们Class Name是自明的,Package Name是自明的,Module Name也是自明的,那么我们整个应用系统就会很容易被理解,看起来就会很舒服,维护效率会提高很多。我们的命名规则如下图所示:
    image.png

    SOFA应用架构

    经过上面的长篇大论,我希望我把我们的架构理念阐述清楚了,最后再从整体上看下我们的架构吧。我讲这个架构命名为SOFA,全称是Simple Object-oriented and Flexible Architecture,是一个轻量级的面向对象的,可扩展的应用架构,可以帮助降低复杂应用场景的系统熵值,提升系统开发和运维效率。
    image.png
    目前框架也准备开源,贡献个社区,让更多的开发者使用,帮助解决他们各自的业务复杂度。
    关于框架源码和介绍,请移步:https://github.com/alibaba/SOFA/

    整体架构

    我们的架构原则很简单,即在高内聚,低耦合,可扩展,易理解大的指导思想下,尽可能的贯彻OO的设计思想和原则。我们最终形成的架构是集成了扩展点+元数据+CQRS+DDD的思想,关于元数据前面没怎么提到,这里稍微说一下,对于字段扩展,简单一点的解决方案就是预留扩展字段,复杂一点的就是使用元数据引擎。使用元数据的好处是不仅能支持字段扩展,还提供了丰富的字段描述,等于是为以后的SaaS化配置提供了可能性,所以我们选择了使用元数据引擎。和DDD一样,元数据也是可选的,如果对没有字段扩展的需求,就不要用。最后的整体架构图如下:
    image.png

    提效工具

    Archetype

    因为框架包含了5个Module,20+的Package,如果手动创建的话很费时,而且很容易出错,所以创建了这个Archetype,可以一键构建框架的所有Artifacts,使用时,只需要将下面的命令中的demo替换成自己应用的名字即可:

    mvn archetype:generate  -DgroupId=com.alibaba.crm -DartifactId=demo -Dversion=1.0.0-SNAPSHOT -Dpackage=com.alibaba.crm.demo -DarchetypeArtifactId=sofa-framework-archetype -DarchetypeGroupId=com.alibaba.sofa -DarchetypeVersion=1.0.0-SNAPSHOT
    

    测试容器

    不管你是不是TDD吧,写几行代码,然后本地跑下测试验证一下总是个不错的习惯。因为代码还是热的,出错也容易定位。但是本地启动PandoraBoot可不是个省心的事,我这台2.3G双核平均也要4分钟,严重的影响了效率。所以开发了这个工具,就是等PandoraBoot启动后,将线程Hold住,然后通过Console控制台输入要测试的方法或者类。使用这个工具很简单。
    首先依赖crm-test:

    <dependency>
       <groupId>com.alibaba.crm</groupId>
       <artifactId>crm-test</artifactId>
       <version>1.0.0-SNAPSHOT</version>
       <scope>test</scope>
    </dependency>
    

    然后将TestApplication修改如下即可:

    public class TestApplication {
        public static void main(String[] args) {
            PandoraBootstrap.run(args);
            SpringApplication.run(Application.class, args);
            TestsContainer.start();//启动测试容器,避免重复启动PandoraBoot
        }
    }
    展开全文
  • 企业应用架构演变之路

    千次阅读 2017-05-06 16:08:36
    企业应用架构是指一整套软件系统的构建,通过合理的划分和设计组合在一起,支持企业方方面面的经营运作。不论是传统企业,还是互联网公司,发展到一定阶段,都需要一整套体系化的应用架构来支撑其运转。良好的、合理...
    作者|杨堃编辑|Gary
    

    企业应用架构是指一整套软件系统的构建,通过合理的划分和设计组合在一起,支持企业方方面面的经营运作。不论是传统企业,还是互联网公司,发展到一定阶段,都需要一整套体系化的应用架构来支撑其运转。良好的、合理的应用架构可以支持企业高效开展业务,控制经营风险,而混乱的、不合理的应用架构则会限制企业的快速发展,成为企业增长与变革的瓶颈。

    企业信息化建设已经发展了几十年,传统企业和成熟互联网企业的应用架构并没有本质的区别。本文将通过一个线下小型门店成长为多元化集团的发展历程,逐步向读者展示企业应用架构的演变和设计的理念。

    完整的企业架构(EA,Enterprise Architecture)分析构建,包括业务架构、应用架构、技术架构、数据架构,本文聚焦应用架构,更加关注软件系统设计与公司经营管理的关系。不论是C端产品经理或者B端产品经理,理解应用架构的建设思路,能够帮助你更轻松的理解公司的业务运转,以及各个系统存在的目的与你所负责工作在整体团队中的定位和价值。

    传统企业的应用架构演变1. 小门店的Excel管理之路

    我们将从一个最简单的案例入手,来展开故事。假设你是一名个体经营者,在小区中开了一家小门店,售卖居民常用的生活用品。门店不大,只有十几平米,平常由你一个人负责经营管理,包括采购,摆货,销售。为了更准确、科学的打理你的生意,你设计了一个Excel文件来管理你的商品与销售数据。实际上你只需要做三张表格,第一张表格存储了你的货品信息,第二张表格存储了你的采购记录,第三张表格存储了你的销售记录。这三张标的结构和关系如下图所示。下图采用了ER模型来描述三张表的逻辑结构,*和1的含义是表和表之间的关联关系,例如采购记录和商品信息是多对一关系,即采购记录表中的每条数据只能对应商品信息表中的一条数据,商品信息表中的一条数据可以对应采购记录表中的多条数据。

    因为你采用了科学的数据表格管理,记录了门店的所有采购入库和销售数据,这让你的经营变得井井有条,通过这些原始数据,你可以准确的管理库存,计算利润,掌握畅销品和滞销品,还能通过数据透视表制作销售日报和月报。实际上你通过以上三张表格管理自己的生意,已经是一个管理软件的雏形了。所有的软件系统无非都是对数据的增删改查操作,可以说,如果使用得当,Excel也可以做出一套小型的软件系统。

    2. 小超市的轻量级ERP之路

    因为你善于使用信息技术来协助你做生意,你的买卖发展迅速,很快,你将小门店升级成为一家小型超市,并且雇佣了几个店员来帮你。作为店长,你兴奋的绘制出自己的第一张组织架构图,梦想着事业会继续壮大。

    因为经营的货品更加丰富,日交易量成倍增长,并且有好几名员工需要做数据录入分析工作,这时Excel已经难以满足经营管理的需要。因此明智的你在开店之前,就决定采购一套ERP软件来协助你管理超市。因为你还处于创业期,资金有限,通过仔细挑选,你选择了一套轻量级的ERP,并且只购买了其中的几个核心模块,这样既可以控制成本,又可以让你经营的软件设备升级。现在,我们可以绘制公司的第一张应用架构图,公司拥有一套系统,包含三个模块。

    3. 通过CRM拉近与客户的距离

    为了更加准确的理解、认识你的客户,同时也为了能够拉近你和客户的距离,你打算通过CRM软件进行更加科学的客户管理。你设计了一套会员积分制度,所有的客户都能免费办理会员,这样你就可以记录下关键的客户信息,而且你的小伙伴建议你开通一个微信公众号,让客户能够通过微信来查询自己的积分,这个主意太棒了!你追加购买了几个ERP的模块,虽然ERP中也包含了CRM模块,但是研究后你认为内置的CRM模块功能有限,不支持对接微信,营销功能也不够强大,因此你新购买了一套CRM软件,和ERP进行了一定程度的对接,同时申请了微信公众号,找外包公司做了一些定制化开发。这样上述想法就都实现了!我们绘制出公司的第二张应用架构图。

    可以看到,核心的客户信息资产模块都在CRM中实现,其中内置了营销模块、消息推送服务Msg模块,包括SMS、EDM(Email Direct Marketing)和微信消息推送, CRM主要聚焦客户资料的管理和营销服务,主要用户为店长和运营人员;ERP主要聚焦于超市的进销存以及财务业务,主要用户为营业员、出纳、采购、库管和会计。请注意,这里已经产生了应用架构设计的概念,公共号,ERP和CRM每个系统都为了解决某一大类的业务问题而存在,有各自清晰地定位、分工和目标用户,每个系统相对独立又互有关联,内置若干模块,每个模块都是为了解决某一大类业务问题下的某一小类问题而设计。在这张图中我们使用了分层描述,靠近C端用户的微信公众号在最上层,支持业务运转的ERP放在中间层,偏底层的客户信息集成CRM放在最下层,这样可以清晰地看出几个系统的层次关系,同时也在一定程度反映了系统和业务之间的逻辑对应关系。

    4. 中型连锁超市的架构之路

    业务进展很顺利,你已经开了五家中型连锁超市了,员工数量达到了几百人。公司走上了正轨,标准化的管理分工已经成型,不同职能单元各司其职。为了有效管理团队,并且让内部流程更加顺畅,你邀请专业的IT咨询公司帮你重新梳理了公司的业务目标,组织架构,运营流程,通过引入OA,HRM以及重构ERP等手段,对不合理的制度,低效的流程进行了改造。公司成立了信息技术部,其中项目部配合咨询公司以及软件外包公司进行系统改造或实施新系统,运维部负责保证服务器、网络的稳定。

    你理解数据对公司发展的重要性,所有的管理决策都应该基于对数据的分析和判断,因此你邀请咨询公司帮你强化公司的数据分析能力。咨询顾问建议你实施数据仓库(Data Warehouse)和BI(Business Intelligence)项目,原因有几点:1. ERP系统和CRM系统都有报表模块,但两个系统的数据相互孤立,不利于整合分析。2. 业务系统的底层数据结构并不适合做复杂的数据分析,常见的多维分析更需要一套数据仓库常用的星形数据结构和雪花型数据结构。3.成熟的BI软件套件可以让你的报表分析与多维数据探查更轻松,其中的仪表盘更能够让你轻松掌控公司全局的核心指标变化。4. 企业经营中很常见的一个问题就是经营分析指标统计口径太多,造成管理混乱和沟通障碍,除了在管理上规范公司级指标的定义,也需要一套底层数据架构,消除上游各个异构系统的孤岛和屏障,统一管理汇总数据和指标计算。

    咨询顾问建议,虽然目前公司的业务系统还没有到非常复杂的阶段,但数据仓库可以帮助企业更快速高效准确的理解、捕获、使用数据,做好基础建设工作,培养员工的数据分析意识和方法,通过数据来进行决策。随着业务的拓展和系统复杂性的提升,数据仓库的存在价值将越来越明显。

    在数据仓库项目中,同时构建了数据集市(Data Mart)。数据集市介于BI展现层和DW数据底层之间,是数据仓库的数据子集。数据仓库的服务对象通常为全公司或全集团,但是不同部门可能有自己的数据分析诉求与指标管理诉求,这时候通过统一的数据底层,封装出针对某个部门使用的小型数据集市,可以保证数据流的合理性、可追溯性,同时研发部门可以完全复用DW和BI的技术能力,轻松地设计实施DM。

    如果希望数据仓库在企业中真正发挥作用,不仅仅是软件系统实施问题,更重要的是公司层面的经营分析思路体系化,指标管理规范化,以及数据部门组织架构、与业务部门合作流程设计问题,同时还需要提升全员数据化管理运营的概念和意识。软件本身并不能解决企业的问题,只有配套的架构、流程、制度与意识,才能发挥软件的功效。

    5. 应用架构跟随业务而变

    由于公司经营良好,很多商品可以从供应商处拿到很好的价格,经过供应商授权,公司决定开展2B业务,成立了大客户销售部,公司将作为供应商的B端渠道,挖掘企业客户。为了让销售工作高效展开,对销售人员进行严格的过程管理,同时也为了保留客户资料,避免销售独占客户资源,根据CTO建议,公司决定实施操作型OCRM(Operating CRM)项目。同时由于各部门经常出现个性化的软件开发诉求,软件外包维护的成本高,效率低,公司决定招聘研发团队,用自己的队伍进行软件的二次开发。

    在设计OCRM系统时。CTO面临两个选择:

    方案一:新做一套独立于现有CRM的OCRM

    优点:OCRM系统已有成熟的软件可以选择,无需从头开发;两个系统边界清晰,分工明确,便于未来各自的发展与演变。

    缺点:应用架构会略有复杂,需要将原有的CRM和OCRM做数据打通,对原有的客户模型做升级。

    方案二:在原有的CRM基础上开发新模块

    优点:新开发的模块完全基于公司业务流程和模式设计,适配程度高。

    缺点:新开发模块成本高速度慢,系统边界模糊,导致以后维护升级时模块管理的混乱。

    综合评估两套方案实现的成本和速度,考虑到对未来业务变化的灵活支持,同时为了避免影响核心CRM业务的稳定性,CTO决定采用方案一,让两个系统各自聚焦,互相独立,边界清晰,虽然无形中增加了公司应用架构的复杂性,但可以快速实施支持当前的紧迫业务,并灵活应对未来公司的销售业务变化。

    一般来讲B端客户的数据模型和C端客户差异非常大,B端客户模型关注组织架构和人员角色的描述,C端客户模型关注客户本身个人信息的描述,即便应用系统中将客户模型和操作型系统分开建设,客户模型一定会做成两套以支持不同的上下游业务系统。上图为了简化表述,只绘制了一个模块“客户信息”,但读者应该认识到该模块应该包含B端、C端两套客户模型。实际上有的公司会明确将两套客户模型在应用架构中分开设计并且分别建设,以便更加准确的体现应用架构中的业务概念。

    另外读者需要注意的是,广义上来讲,CRM代表一种企业对待核心客户资源的管理理念和运营方法,CRM是一种概念而非某一个独立的应用系统。大型的企业涉及多条业务线,不同的业务线有不同的客户群体,企业需要有统一的客户视图和管理理念,以及强大的IT系统支持,来实现准确的客户接触点管理,充分挖掘客户群体实现精准销售,积极有效的维护企业和客户的关系。CRM体系化的系统建设中包含了客户建模,会员积分管理,营销中心,销售线索和过程管理,小型数据仓库或数据集市,统一客户视图,客户画像和数据挖掘,电话销售中心等等。不同的企业对系统的划分和团队的管理各不相同,但所有CTO都应该明白CRM是一套应用体系,而不仅仅是某个单一的独立应用系统。

    至此,我们已经绘制出一套一般企业的简化版应用架构图,以及一张常见的组织架构图。可以看到,应用系统的建设,是根据业务的发展变化逐步完成的,每个系统都有独立存在的意义和价值。

    6. 传统企业如何管理软件开发

    在上一节的组织架构图中,CTO引入了需求管理部的子部门。传统企业内部的软件升级开发,一般会由业务部门将需求提交给需求管理部受理,需求管理部常设BA岗位(Business Analyst),负责受理、评估业务方需求,形成软件方案设计,输出需求文档,提交给开发人员开发。BA非常像互联网企业的PM岗位,区别是互联网企业的PM决策权更高,更加深度的参与、影响业务。BA以及IT部门的的权责范围取决于企业对信息化建设重要性的认知程度,以及团队负责人在企业的决策权和影响力。一般来讲传统企业的CTO或CIO汇报对象为COO,很少进入公司最高决策层,而在互联网企业CTO或产品VP都属于最高决策层。

    传统企业更加倾向于瀑布式软件开发,对研发、运维流程的管理更加严谨,因为传统企业业务变化慢,对系统的每一次调整改造都非常慎重,而互联网公司业务变化调整快,必然要求软件开发时效性高,对软件设计的严谨性做出一些让步,因为很有可能发生的情况是,软件还没有开发完毕,业务或流程已经再次发生变化。

    企业的信息化管理有很多标准的管理模型,例如COBIT,ITIL,CMMI,ISO27001,覆盖了开发管理,服务管理,数据管理等方方面面的规范和标准。很多成熟的互联网企业也会执行使用这些标准来提升IT能力对企业管理效率的提升和经营风险的控制。

    多元化业务带来的应用架构演变1.    在线商城业务带来了互联网化管理

    公司的零售业务发展进入了瓶颈期,CEO需要寻找新的增长点。经过评估,决定开展电商业务,新成立了电商部,从市场上聘来了某电商平台VP作为部门负责人,直接给CEO汇报。为了学习互联网公司,以技术力量推动业务创新,电商部组织结构参考了一般互联网公司组织结构,有自己独立的研发团队,设置了产品岗位,产品技术总监给电商部负责人汇报。电商部受到CEO极度重视,给与极高自治权和最高资源支持,同时CEO还将之前线下的客服团队升级为公司一级部门,直接给CEO汇报,统一处理线上线下的客服与售后业务。

    新业务开展,大家干劲十足,因为电商部产品技术总监和公司CTO之间不存在汇报关系,产品技术总监为了快速推进项目,所有决策基本只是告知CTO。产品技术总监作为纯互联网背景专家,认为购买现成软件套件不利于系统的二次开发和自主维护,长远来看会限制公司业务发展,希望整套系统实现自主研发。虽然CTO极力反对,但经过电商部负责人和产品技术总监的游说,CEO听取了总监的建议,并且总监承诺自己的研发团队效率极高,一定会在承诺之日交付系统。

    产品技术总监设计的应用架构体系,包括PC和移动版的前端应用,以及完整的后端系统,包括订单、售后、客户信息、会员、营销、账号、CMS。此外,仓储、财务系统会接入现有ERP的服务,配送模块直接与第三方配送服务商系统对接。对于这个架构设计,CTO比较不满,认为客户信息和账号管理不应该重复建设,而应该统一规划管理,但产品技术总监一心快速推进实施,对于信息技术部开发效率低的情况他早有耳闻,他可不希望被一些不可控力影响导致自己的项目延期,因此CTO的抗议他不予理会。

    升级后的客服部门,新建了20人坐席的电销中心,以支持主要来自于线上的电话客服诉求。新成立的客服团队需要CallCenter系统开展业务,虽然CallCenter的主要服务群体是线上业务的客服话务员,但CEO为了在一定程度上安抚CTO的不满情绪,将CallCenter项目安排给CTO负责。CTO采购了一套成熟CallCenter来支持400热线业务,对此安排电商部的产品技术总监没有什么异议,但在CallCenter的实施中却出现了问题。因为CallCenter系统只负责电话作业,其中的客户资料一般由上游系统提供。但是公司现有两套客户资料,一套是保存在CRM的线下业务客户资料库,一套是在线商城的客户资料库。为此只能在CallCenter中新增一套客户库,将另外两套客户库数据同步过来,这样客服人员才能在CallCenter中查到公司级别的完整客户信息。

    2.    信息孤岛与主数据管理

    电商系统如期上线,业务发展迅速,电商团队的运营和产品人员年轻,聪明,充满活力,思维活跃,玩法众多,电商技术团队响应迅速,产品经理和技术团队的无缝配合,让技术力量真正推动了业务的增长。公司赚钱了,老板很开心。但很多问题也同时暴露了出来。我们先来看看之前的应用架构。

    之前为了快速上线,有一些应用架构遗留问题没有解决。现在公司有三套客户资料库,线下客户通过微信公共号访问CRM系统中的客户信息,在线商城的客户通过线上商城访问e-Store系统的客户信息。当客户致电400时,电销业务员(TSR)访问的是从e-Store和CRM同步过来的客户信息。

    线上客户关注公共号后,查不到自己的资料,这让客户感觉很诡异。

    线下客户想在线上商城下单,发现之前登记的账号不能使用,需要重新注册完善资料,客户很烦躁。

    数据同步30分钟一次,有时候客户刚修改完资料再致电400,客服查到的客户信息不是最新的,让客户很生气,客服很苦恼。

    有的客户喜欢打电话让客服改资料,因为客户资料是单向同步,客服无法协助客户修改资料,客户很气愤,为什么你们连这点服务都做不好!

    很多客户在线上线下都消费,但由于在数据仓库中冗余出了两个客户对象,不论是线上团队还是线下团队,都无法做更准确的客户画像和跨渠道消费行为分析。

    CEO很生气,找到CTO和电商产品技术总监,质问怎么回事。CTO回答,我们遇到了严重的信息孤岛问题!由于CRM和商城后台数据互相孤立,导致核心客户资源不同步,不统一,让公司无法得到一个完整准确的客户视图。如果要解决这个问题,必须对应用架构进行改造,并且改造比较耗时。CEO很郁闷,没想到应用架构不合理会影响到业务发展,也没有想到组织架构的设计会导致应用架构出问题。为此,CEO做了一些调整,产品技术总监实线向电商部经理汇报,虚线向CTO汇报;总体来讲产品技术总监对电商业务销售端负责,CTO对全公司IT架构管理和其他所有系统负责。经过善意的沟通,CTO和产品技术总监的矛盾消除了,大家决定合力解决问题。

    解决数据信息孤岛的方法很简单,那就是只保留一份客户信息库,这份客户信息库保存最核心的,与业务单元无关的客户属性和资料。至于积分、会员等扩展属性依然由各个应用系统维护管理。调整后的应用架构图如下:

    将客户信息库独立,商城、CallCenter、CRM和微信公共号通过统一接口调用Customer Profile存储的核心客户档案,不论客户或业务员从哪个端口查看或修改信息,变化对其他端口都是透明、实时的。实际上这就是客户主数据管理(Customer MDM)的设计理念。

    在企业应用系统建设中,不可避免的会遇到信息孤岛问题,信息孤岛是指因为各种原因,每个应用系统独立建设时,没有和外界系统做良好的打通,导致应用系统之间存在流程或数据的孤立性,最终给业务带来严重影响。解决数据信息孤岛的经典方法就是主数据管理(MDM)的思想,主数据管理通过应用架构的拓扑设计,配合相应的管理手段,帮助企业存储、识别唯一的关键数据,避免企业内部关键数据的冗余和不一致问题。常见的主数据有客户主数据,商品主数据等。

    主数据管理的设计理念应该自始至终贯穿企业应用架构的设计过程,需要注意的是,企业应该在合适的阶段实施主数据管理和治理。主数据将应用架构变得更复杂,在初期阶段实施时需要投入更多时间和资源,而在企业发展的某些阶段,快速迭代上线意味着对商机的捕获和市场变化的迅速跟进,一个合格的架构师应该在应用架构设计和公司业务发展之间做出合理权衡,要根据现实的情况和资源,敢于在应用架构的和理性上做出妥协和让步。

    主数据经常作为底层数据应用来管理,因此在架构图中我们将它和DW并列画在最底层。

    3.    抽离共性模块全面服务化建设

    公司业务发展稳定,各个系统底层做过几次技术重构,性能更强健。为了让各个应用系统更加聚焦,提升稳定性,节约开发成本,避免重复劳动,CTO和产品技术总监讨论后决定对一些公有服务从各自应用系统中剥离,统一进行服务化改造升级,为以后公司新业务的开展打好基础。例如,将CRM和商城后台的消息模块功能合并,将商城支付模块单独剥离,设计实施了集成化的权限管理系统Auth,给全公司多个应用提供统一的权限管理服务,控制公司运营风险。

    CTO和产品技术总监合作加强了数据团队建设,设立了数据挖掘团队,丰富了客户画像,加强了经营分析能力,产生了更多的策略输出。数据策略输出不仅给在线商城提供了更强劲的推荐策略,也为CRM,运营人员提供了更丰富的策略运营、精准定向活动推送支持。

    4.    强健的底层架构快速支持新业务开展

    公司在寻找新的增长点,计划开展个人理财业务。公司的组织架构有了新的调整,管理模式也有了新的提升,形成了集团化治理模式,成立了财务共享中心,人力资源共享中心。新设立的理财事业部,和零售事业部、电商事业部一起,调整为独立核算事业部编制,事业部聚焦经营和销售,集团层面给事业部提供基础运作支持。信息技术部也与时俱进,将之前的需求管理部调整为产品部,信息技术部主要负责CRM、CallCenter、ERP、OA、HRM、DW、BI等应用系统,保证集团职能部门运作,为事业部的应用系统提供基础架构和底层服务支持。

    因为集团IT应用架构已经非常强健,理财业务的系统构建可以迅速展开,CTO和理财事业部的产品总监沟通后绘制了集团应用架构图,理财业务只需要建设一套C端APP和一套基本的管理后台,而类似于客户数据,支付,Push服务,DW和BI都直接使用集团现有系统,无需重新开发。


    CTO和产品总监讨论后,认为上述架构图还存在一点问题,账号管理不应该单独创建,集团已经有着很成熟的统一客户管理理念,多套账号管理模块会再次造成信息孤岛问题。因此决定将现有的账号管理模块也进行平台化、服务化升级,给理财业务提供支持。集团层面的Passport系统诞生了。更新后的架构图如下。


    这里顺便解释一下,为什么本文对所有软件系统都称为系统,而互联网公司则习惯称其为产品。

    互联网的发展催生了产品经理的岗位。产品经理常分为C端产品经理,B端产品经理(包括商家端和运营管理中后台)等。B端产品线中,有CRM产品经理,供应链产品经理等。在互联网公司似乎不太在意区分产品和系统的叫法,到底两者有何区别?

    实际上,所谓产品是指企业提供的商品或服务,给企业带来利润。早期的互联网公司多为虚拟经济形态,面向用户的软件系统就是公司给消费者提供的商品或服务,因此聚焦软件功能设计的人员被称为产品经理。而互联网公司是一类高度依赖信息技术能力驱动业务的公司,对各类软件系统都倾向于自主建设,因此不论是面向客户的系统,或面向企业内部的系统,软件设计人员都统一叫做产品经理,其职责定位就是负责软件的设计和实现,软件系统习惯被称为产品;而在传统企业,负责软件设计的人员一般都叫做需求分析师或系统分析员,软件系统习惯被称为系统。

    其实怎么称呼都无所谓,本文统一叫做系统。

    企业通用应用架构设计1.    通用企业应用架构图

    对上文的应用架构图做一些简化和调整,以便更加准确的体现应用架构的共性以及与业务的对应关系,得到一张更加清晰简洁的企业级应用架构图。


    第一层是对外系统。所有给企业外部客户使用的系统都在这一层,包括官网,普通用户或客户使用的C端。如果是类似于美团,天猫这种平台性质的业务,还会包括给商家使用的商家端。这类系统站在与客户接触的最前线,是公司实现商业模式的桥头堡。

    第二层是对应C端系统的管理后台。常见的管理后台都会包含订单、CMS、商品等模块。每个C端业务形态都会对应一个管理后台,有些管理后台的模块可能会被抽离出来集中维护,例如风控,消息服务,客户主数据。

    第三层是业务单元支持系统。绝大多数企业业务的开展,必然不能单纯靠线上的运作来实现经营,而可能包含电话销售,客服,地推,仓配等一系列业务单元共同运作。业务单元的运作需要强大的系统支撑。

    第四层是职能单元支持系统。企业发展到一定规模后,必然会有完善的职能单元作为后勤部门支持业务单元的运转和企业的正常运作,例如法务、财务、人力、客服,每个部门的正常运转都需要相应系统的支持。

    第五层是基础架构支持系统。信息化建设到达一定程度后,企业有必要将通用功能服务化,平台化,以保证应用架构的合理性,提升服务效率。这类系统主要给其他应用系统提供基础服务能力支持。

    第六层是数据底层,和第五层类似,这一层主要集中在数据层面的统一和封装,对各个下游系统提供数据服务。

    以上六层划分涵盖了企业所有的应用系统建设,每一个应用系统的存在都将定位在六层中的某一层。上图示例的系统涵盖了绝大多数正常企业经营运转常见的应用系统,在现实世界中,应用系统数量会远远多于上图所示,例如商业银行可能会有成百上千个系统存在。但是理解一个常见企业的组织结构,部门定位,以及上述应用架构图形成的原因,可以让你更准确快速的理解、掌握、设计任意一个应用系统。

    2.    不同类型企业的应用架构图示例

    因为一般企业的组织架构设计,职能单元的设计基本没有太大区别,而以上简化版的应用架构图映射了一个标准化企业的各个常规业务单元,且涵盖了绝大多数企业中标准的应用系统,所以我们可以将不同互联网企业的应用架构图映射到上图中。下面我们用三个例子,向读者演示不同业务形态、发展阶段的公司,其应用架构的可能形态。作者并未在以下公司任职,或与相关内部人员探讨过其公司应用架构,以下示意图均为作者根据几个公司的业务特点和发展阶段,所做的推测。

    首先以美团点评为例。美团的业务模式主要为供需平台建设,帮助消费者和服务提供方撮合交易。外部系统包括了C端系统和商家端系统,C端系统为消费者常用APP,商家端系统为商家提供商品管理,交易管理,推广管理,经营分析等功能。C端或商家端都对应后端管理系统,方便企业内部对整个平台进行管理、营销、风控等。平台需要发掘更多的商户资源入驻,因此会有销售过程管理的OCRM系统;平台需要对C端客户提供客服与售后支持服务,相信美团点评的业务量,一套专业的CallCenter系统必不可少;美团提供了自营的配送服务,TMS系统必然成为标配(也有可能是SCM中的模块)。由于美团业务不涉及自营的实物货物买卖服务,没有仓储体系,因此推测没有WMS系统(或者ERP中包含了WMS模块但是没有启用)。O2O业务需要管理大量线下门店,因此GIS(Geography Information System)系统不可或缺,对于实力较强的公司,可能还会开发独立的POI(Point of Information)管理系统(也有可能是GIS中的模块)。至于财务、OA、Passport、Auth、BI、DW、MDM等,必然都是公司标配。

    接下来再以今日头条为例。今日头条构建了信息流资讯类C端,吸引网民使用,这类产品最常见的盈利方式为广告变现。在公司经营之初,可能采取了市面上的DSP平台来完成APP的广告管理(当然也可能从来没有采用过),为了更好的设计广告产品,相信现在一定有自己的广告投放管理平台,因此公司会有给广告主使用的B端广告投放管理系统。(当然也有可能还没有这类平台,作者在百度工作时很多商业变现产品投放管理都是PM和广告主线下沟通后通过内部平台操作的)。因为业务模式以广告投放为变现手段,因此后端系统可能没有交易类后端复杂,但基本的CMS和风控(反垃圾、反作弊、合法合规)必然是有的。

    公司需要盈利,就需要售卖产品,售卖产品永远不可能只在线上运作,必然会有BD团队支持,因此今日头条也会有CRM系统,管理对象为广告主而不是网民。但是WMS、TMS系统这类系统估计就不需要了。至于CallCenter,笔者查询了官网,没有找到相关的客服热线,猜测还没有建设。今日头条的早已度过创业期,标准的管理软件应该配备齐全,例如OA,HRM;不同的基础架构支持系统,在当前阶段有可能有,也有可能没有,例如Auth,Pay,MDM等。作为一个纯技术公司,BI,DW当然是标配。

    最后的例子,我们挑一个相对规模小,产品形态单一的例子,例如墨迹天气,万年历这类工具类应用的公司。这类公司在创业初期,不考虑变现的情况下,团队小,产品简单,应用架构图也会非常简单,在产品发布时,只需要实现官网、C端、后台管理、账号和会员管理就足够了。当然随着公司的发展,常见的变现手段之一就是广告投放,可能会继续演变到类似于今日头条的应用架构。

    以上举了三个例子,让读者更好的理解应用架构演变和公司业务模式以及发展阶段的关系。在实际工作中,应用架构的建设与面临的情况会复杂得多,只要理解了以上简化版的例子,可以更容易理解实际工作中的场景。

    3.    企业应用架构设计的一些建议

    最后,我们来谈一谈如何合理的设计企业应用架构。不论是架构师,产品条线负责人,或某个系统的产品负责人,都要有架构设计的理念和知识,尤其是后端产品经理,必须充分理解企业应用架构的基本概念。这里给出一些应用架构设计的建议。

    系统定位和边界要清晰,对应的业务定位和边界要清晰

    一套应用系统的存在,都是为了解决某一类业务问题,对应某一个业务板块。如果业务板块或业务单元定义模糊,也会导致对应的应用系统定位混乱。

    系统要实现松耦合,高内聚

    系统要对外界透明,简单,易理解,与外部系统的接口要简明,扼要,灵活。内部模块高度聚合,粒度越细越不可拆解。

    易变的,尝试中的新业务要避免影响现有业务的稳定性对新业务的支持,可以考虑新建独立微小型应用系统,以便避免改造成熟核心系统,影响其稳定性和健壮性。

    系统之间数据要实现单向流转

    系统之间尽量保证单向数据流转,确保数据流可回溯,数据的一致性和可追溯性。混乱的数据流转管理会造成应用架构管理的灾难。

    架构设计核心目标是支持业务,有些时候不合理的存在是合理的

    应用架构存在的首要目标是支持业务,很多成长性企业或初创公司面对生存的压力,不能为了保证架构的合理性而拖延系统实施速度导致企业错过发展时机。这种情况在互联网型企业更为常见。业务还在试错期,系统需要尽快保证支持业务试错,如果一上来就谈论整体架构的合理性,很可能花费巨大成本实现了合理架构后,新业务已经取消或失败。优秀的架构师和CTO要懂得在合理架构设计和灵活多变的业务发展之间做出智慧的权衡取舍。

    对于CTO或公司架构师,要保证整体企业应用架构的合理性,只要大框架合理,局部的偏差可以忽略,修正的成本也比较小,如果大框架有偏差,修正的代价会非常高。对于产品条线负责人,要保证局部框架的合理性,避免出现设计不合理造成的返工和补救工作。很多时候架构师或条线负责人要做出判断,是做一套新系统,还是修改老系统,新系统如何定位,老系统如何调整定位;数据如何流转,系统之间如何关联,底层数据如何打通;是否要复用其他系统模块,是否要将某些模块抽象化,服务化,平台化。对于产品经理,要在系统级别的粒度做出类似问题的判断,能够识别出可能存在的系统演变风险,及时升级控制不了的问题,避免做出错误决策。

    企业架构是一套庞大复杂的体系,本文是对其中应用架构部分,结合作者实际工作经验的浅薄理解,业界有着众多的企业架构建设规范和指引,例如Zachman,EAP,TOGAF,这些框架涵盖了信息技术和企业战略结合实施的方方面面,感兴趣的读者可以做更深入的学习。

    展开全文
  • 企业应用系统大全

    2018-01-15 15:00:59
    在企业规划信息系统中,需要了解到企业应用的名录。该文档描述了企业信息化常用的软件信息名录。
  • 什么是企业应用

    2016-12-21 20:12:45
    看到“企业应用“这次术语, 在你的下意识里,第一反应能想起哪些相关的词?我的条件反射是: ERP, CRM, HRM, BI, CMS ......企业应用这个词听起来...
        

    看到“企业应用“这次术语, 在你的下意识里,第一反应能想起哪些相关的词?

    我的条件反射是: ERP,  CRM, HRM, BI, CMS ......

    企业应用这个词听起来很高大上,  但是什么“企业应用”?  我发现我没法下一个准确的定义。

    回顾下我的工作经历, 应聘的时候似乎都是要做"企业应用" 开发。

    毕业后第一份工作就是做很热门的OA系统,就是所谓的办公自动化,包括了邮件、工作流、表单、文档系统等公司信息化需求, 用户肯定是部署OA的企业内部人士,算是最基本的企业应用开发吧。

    后来做了欧洲的税务系统,实现他们各种各种复杂的业务逻辑,用户也是税务局的员工, 应该是标准的企业应用。

    再后来做一个庞大的系统来支持公司的产品销售,用户既有公司的销售人员,也有外部的用户。 系统相当复杂, 由很多子系统组成,各个子系统还存在着复杂的关系, 接口五花八门,有的用Webservice , 有的用数据复制, 有的用MQ, 甚至还有邮件接口和FTP接口,  这应该也是一个典型的企业应用。

    似乎一个企业应用就是帮助企业干活的信息系统,满足企业日常运营,  帮助他们完成流程的信息化。

    人称软件教父的Martin Flower 非常善于抽象,   在著名的《企业应用架构模式》一书中他就针对企业应用抽象出这么几点:

    1. 企业应用一般涉及到持久化数据

    初一看似乎是废话: 如果数据不能持久化,应用也没什么意思了。

    实际上重点是企业数据的生存年限相当的长, 甚至比访问这些数据的程序都要长,无论硬件、操作系统、应用程序怎么变,数据都不能受到损害。

    2. 企业应用一般涉及大量数据

    这是毫无疑问的, 一个企业运行过程中绝对不仅仅产生几千,几万条数据。

    3. 企业应用涉及到很多人同时访问数据

    如果是内部系统还好, 要是对外的Web系统, 那用户量可能非常大。

    4. 企业应用涉及到大量的用户操作界面

    有几百个界面毫不为奇, 用户使用频率差异很大,特别是这些用户没有技术背景。

    5. 企业应用很少独立存在, 通常需要与散布在企业周围的其他应用进行集成。

    这些各种各样的系统是在不同时期, 用不同的技术构建起来的, 把他们集成起来的痛苦经历过的码农才知道。

    但是互联网应用像淘宝,京东商城是否属于企业应用的范畴?    Martin Flower并没有明确说明。互联网应用符合了上面的第2,3两点,  数据量巨大, 高并发访问, 技术上要求规模大、扩展性强、可靠性高 。

    既然难于区分,  我想不妨根据用户的不同, 分为两个大类:


    1. 面向企业用户

    ERP(企业资源规划),  CRM(客户关系管理) , HRM(人力资源管理),SCM(供应链管理), BI(商业智能) ,还有各种各样根据企业的需求做的定制软件(例如营销系统) 等应该属于这一类。

    这类应用的用户数不会像互联网应用那样特别巨大, 但是业务逻辑一般比较复杂, 为了实现这些变态的,多变的逻辑经常得付出巨大的代价。

    稍微大点的企业都会涉及到应用之间的集成问题, 这又是一个大坑。

    由于用户主要是企业内部人员, 直接用于企业的生产环境,  一旦出错, 整个公司的活动都可能受影响, 所以对可靠性, 稳定性要求较高。

    这类应用一般都是收费的,并且价格不菲。 既然是掏了真金白银, 系统出了故障,客户一般会怒气冲冲的跳起来找售后。

    2. 面向消费者用户

    电子商务、社交、娱乐、通信等互联网应用属于这一类,相比而言, 消费者对于出错的容忍度要高一点 :  你肯定不会因为微信发不了朋友圈而去找腾讯要赔偿, 最多骂几句而已。

    由于这类应用的用户量巨大, 高并发访问的特质, 即使是简单的业务逻辑,实现起来也很不容易, 例如从数据库读取信息然后展示, 如果是几十个人或者上百人访问,可能直接发出SQL查询数据库就搞定了;  如果有几万甚至几十万访问, 那非得搞一些缓存,分布式,页面静态化等技术来搞定了。  


    由于用户是直接的消费者, 产品的体验至关重要,用起来不爽, 用户马上用脚投票,分分钟抛弃你。


    当然这些互联网应用肯定有后台的管理系统,用来做运营、营销和数据分析, 这又属于第一类的范畴了。

    码农翻身相关历史文章推荐:


    Java EE

    我是一个线程

    我是一个Java class

    Java:一个帝国的诞生

    JDBC诞生记

    JDBC后传

    一个不安分的JDBC驱动

    JSP:一个装配工的没落

    Javascript: 一个屌丝的逆袭

    Spring本质系列(1) -- 依赖注入

    Spring本质系列(2) -- AOP

    Http 历险记(上)

    Http 历险记(下)—Struts的秘密

    三层架构和MVC那点事儿

    Java帝国之 Java Bean(上)

    Java帝国之 Java Bean(下)

    计算机网络

    我是一个路由器

    我是一个网卡

    TCP/IP之大明邮差

    TCP/IP之大明内阁

    TCP/IP之蓟辽督师

    张大胖的socket

    IE为什么把Chrome和火狐打伤了?

    对浏览器村的第二次采访

    节约标兵IE的自述

    EMail诞生记

    EMail诞生记(下)

    操作系统

    我是一个进程

    CPU阿甘

    CPU阿甘之烦恼  

    我是一个键盘

    我是一块硬盘(上)  

    我是一块硬盘(下)

    那些烦人的同步和互斥问题  

    冯·诺伊曼计算机的诞生

    数据库

    小李的数据库之旅(上)

    小李的数据库之旅(下)

    张大胖学数据库

    数据库村的旺财和小王

    你看到的只是冰山一角, 更多精彩文章,尽在“码农翻身” 微信公众号, 回复消息"m"或"目录" 查看更多文章

    有心得想和大家分享? 欢迎投稿 ! 我的联系方式:微信:liuxinlehan  QQ: 3340792577

    0?wx_fmt=jpeg

    公众号:码农翻身

    “码农翻身”公众号由工作15年的前IBM架构师创建,分享编程和职场的经验教训。

    展开全文
  • 几种企业应用集成方式的比较

    千次阅读 2017-12-29 10:35:25
    尤其是很多企业应用的系统,因为我们定义的很多子系统是为了解决某个特定的问题或者问题域,在后续随着业务的发展和变化对于系统也会有更多的集成要求。于是,集成主要有哪几种方式?他们各有什么特点呢?这些问题就...

    前言

         我们做过的大部分系统其实并不是自己从头开始设计和实现的,很多时候是基于现有的基础再做扩展或者和现有的系统集成。尤其是很多企业应用的系统,因为我们定义的很多子系统是为了解决某个特定的问题或者问题域,在后续随着业务的发展和变化对于系统也会有更多的集成要求。于是,集成主要有哪几种方式?他们各有什么特点呢?这些问题就一一的浮现出来。这里主要针对一些原来个人项目中接触过的问题,结合一些前人的经验做一个总结。

    企业集成要点

        通常来说,我们需要将多个应用系统集成起来是的他们之间能够相互交互。出于系统演化和需求变更的影响,由于系统的差异导致我们集成的时候面临的困难也比较繁杂。很多时候我们最开始在设计某些系统的时候根本就没有考虑到集成的需要。因此在集成的时候主要会考虑一下几个要点:

    • 应用耦合度:这一点也和软件工程中的基本设计思想是契合的。即我们要求系统之间的依赖达到最小化,这样当一个系统发生变化的时候也会对另外一个系统产生尽可能小的影响。也就是我们所说的松耦合。
    • 侵入性:当进行集成的时候,希望集成的系统和集成功能的代码都尽可能的变动小。
    • 技术选择:不同的集成方案需要不同的软硬件,这些牵涉到开发和学习的成本。
    • 数据格式:既然系统要集成,从本质上来说就相当于两个系统的通信。那么相互通信的系统就要确定交换的数据信息格式来保证通信的正常进行。我们接触过的SOAP, REST web service, CORBA等都有特定的消息定义标准。
    • 数据时间线:集成还有一个需要考虑的就是当一个系统将需要传递数据发送给另外一个系统的时候,他们传送时间要尽可能少。这样可以提升系统整体运行的效率,减少延迟。
    • 数据或功能共享:有的应用集成还考虑到功能的集成共享。这种功能的共享带来的好处是使得一个系统提供的功能在另外一个系统看来就好像是调用本地的功能一样。一些典型的应用集成比如说RPC(远程方法调用)就符合这种特征。
    • 远程通信:通常我们系统调用是采用同步的方式。可以在一些远程通信的情况下,采用异步的方式也有它的优点,比如说带来系统效率的提升。同时也使得系统设计的复杂度变大。
    • 可靠性:我们不仅仅是设计系统集成方案,就是在一些简单系统应用里面也会考虑到,如果某个部分出错了或者失效了该怎么办?有什么办法可以提高可靠性?

        OK,有了前面这些要点,我们再结合目前几种主要的集成方式来一一讨论吧。    

    文件传输(共享)

         文件共享传输的方式是一种我们能想到的很简单直观的办法。它的典型交互场景如下:

     

         在这种场景下,我们一个应用产生包含需要提供信息的文件,然后再由另外一个应用来通过访问文件获取信息。在这里,集成部分所做的事情主要是将文件根据应用的不同需要做格式的转换。考虑这种集成方式,我们有几个重要的问题需要考虑:

    • 文件的格式:考虑到不同应用系统传递消息的具体样式不一致,A应用产生的文件如果能够给B应用直接使用是最好的了。尤其是如果如果有B应用的原生支持,对于集成来说将大大提高效率。因此,我们一些常见的方法是传递XML或者JSON格式的文本。 当然,在一些UNIX系统里面也有通过纯TXT文本传递信息的。
    • 另外一个比较重要的问题就是什么时候产生文件,什么时候处理文件。因为我们一般都需要一定的时间来产生文件,我们不太希望文件产生的太频繁。而且,在一个应用产生文件的时候怎么保证另外一个应用这个时候不去修改它呢?如果文件产生完了怎么通知另外一个应用呢?还有就是,我怎么知道另外一个应用已经处理过我处理的文件了?我们产生的文件会不会有重名的冲突?文件被处理完之后该怎么办?删除它还是重复再应用?这些问题是在消息传输比较频繁时很容易发生的。这些问题的发生会导致两个应用系统之间信息的不同步或者信息的错误,这也是采用纯文件传输的弊端。
    • 当然,在一些应用场景之下,文件传输还是有其优点的。在一些信息交换不是很频繁,而且对于信息的及时性要求不太高的情况下,这种方式还是值得考虑的。我们可以采用一些timer job的方式来产生和消费文件。只要保证两者不产生冲突和他们正确的执行顺序。集成的效果还是可以达到的。另外,采用文件传输还有一个优点就是对于集成的系统来说它比较完美的屏蔽了集成的细节。每个系统只要关注符合标准格式的文件内容,具体实现和数据交换他们都不需要关心。 

    共享数据库

         还有一种集成方式也比较常见,就是共享数据库。在很多应用开发的场景下,我们的数据库是相对独立提供服务的一部分。所以对于其他系统的对接也就比较容易,这种集成的方式如下图:

        和前面文件共享传输的方案比起来,这种方案有一个相对的优势,就是可以保证数据的一致性。在原来的方案中,如果文件要传输给多个应用的话,我们是没办法保证所有应用的数据是同步而且一致的。有可能有的快有的慢。而在这里,所有的数据都是统一存储在公共的数据库里,也就不存在这样的问题了。对于任何一个系统产生的数据或者变化,另外一个系统也就马上可以看到。

         当然,这种方案也有它不足的地方。首先一个问题就是对于多个应用来说,这个共享数据库需要能够适应他们所有的场景。不同的应用考量的点是不一样的,要能适应所有的需求对于数据库这一部分就显得尤其的困难。还有一个就是性能方面的问题,不同的应用可能会同时访问相同的数据导致数据访问冲突,因此也会带来如死锁等问题。

         所以说,这种方案出现问题的根源在于用一种统一的数据模型来解决各种不同的应用需求是并不现实的。

     

    RPC(远程过程调用)

         远程过程调用的方法在早些年的时候也比较常见。典型的如Java的RMI。典型的应用场景如下:

         以典型的java RMI为例,当我们需要访问远程方法的时候,需要定义访问的接口,然后通过相关工具生成skeleton和stub。然后一端通过stub给另外一端发送消息。在应用A本地的代码中访问stub看起来还是和调用本地方法一样,这些细节都由stub给屏蔽了。其他的技术如COM, CORBA, .net Remoting都采用了RPC的思路。

        RPC的这种思路能够很好的集成应用开发。当然,由于这种机制也会带来一定的问题,比如说java RMI或者.net remoting。他们都局限于一个平台,好比说我应用A是用java做的,那么如果要和另外一个系统通过RMI集成的话,那个系统也必须是java做的。另外,他们其实还是一种紧耦合。我们RPC调用是用的一种类似于系统api的同步调用,当一端发出调用请求的时候会在那里等待返回的结果。如果另外一个系统出现故障也会对调用方产生很大影响。而且我们用RPC调用的时候默认期望消息是按照发送的顺序给接收方的。但是由于各种环境的影响会使得接收的结果乱序,这样也可能会导致系统执行出现问题。所以从可靠性来说还是存在着一定的不足。

    消息队列

         看来前面几种集成的方式,我们再来看看消息队列的方式。消息队列的集成方式如下图:

         所有应用之间要通信的消息都通过消息队列来传输,由消息队列来保证数据传输的异步性、稳定性等。总的来说,这看起来有点像网络连接结构。所有数据通过一条可靠的链路来进行通信。

        那么,这种集成方式有哪些特征呢?

    •     更好的应用解耦:像以往采用文件传输或者共享数据库的方式需要知道文件或者数据库在哪里。对于RPC的方式来说甚至要知道对方的IP地址才能进行方法调用。这样的依赖太强烈。而且还对开发运行平台也有依赖。而现在这种方式则是只要双方规定好通信的消息格式,各自都只要发消息给消息队列就可以了。这就好比是两个人写信,一个人只要把要写的内容整理好再交给邮局,剩下的事情他就不用操心,全让邮局给他办了。这样,不管对方是什么语言开发的系统,只要他们采用统一的消息格式,java开发的系统也就能够和C++, .net等平台的系统通信了。
    • 消息的可靠性:我们具体发送消息的任务相当于交给了消息队列。所有提交的消息有消息队列里的message router来投递。这有点像网络概念里的路由器一样,根据一个发送方指定的地址并转发到另外一个地方。同时,消息队列也根据不同的需要将消息进行持久化,这样保证消息在投递的过程中不会被丢失。
    • 系统可靠性:如果对消息队列和RPC的方式做一个对比,这就好比是生活中打电话和发短信的区别。在打电话的时候,我们是必须期望接电话的对方在电话旁边能够接收响应。而如果接收人不在或者忙的话,打电话的这一方就只能在这里干等。这就是系统不够健壮的地方,一旦另外一方系统出故障,系统就没法正常运作。而且要保证能够正常通信,需要系统双方都同时就位。而发短信的这种消息方式则不然,消息可以准确的送达到对方,如果对方暂时忙消息也会保存在那里。等有空的时候会进行回复。至少保证了有效信息的传递。这种特性也就是保证了系统的异步执行,从某种角度来说也提升了系统性能。

        综合上面的这些讨论,消息队列算是一种兼顾了性能、可靠性和松耦合的一种理想集成方式。目前实现消息队列的产品有很多,比如微软的MSMQ, 开源产品ActiveMQ, RabbitMQ, ZeroMQ等。后续的文章还会对消息队列的应用和内部机制做深入的分析。

    总结

         应用系统集成的方式有很多,最常见的几种有文件传输,数据库共享,远程方法调用以及消息队列。他们在解决某些特定领域的问题时有自己的特长。综合来说,消息队列算是一种比较理想的解决方案。不同事物或者不同领域之间也有很多的相似性,在研究消息队列的时候会发现他们和网络的体系结构思想非常相似。

    展开全文
  • 《轻量级Java EE企业应用实战:Struts2+Spring4+Hibernate整合开发(第4版)》是《轻量级Java EE企业应用实战》的第4版,第4版保持了前几版内容全面、深入的特点,主要完成全部知识的升级。  《轻量级Java EE企业...
  • 轻量级Java EE企业应用实战(第3版) 代码

    千次下载 热门讨论 2012-04-19 23:26:08
    轻量级Java EE企业应用实战(第3版) 的所有源码(随书光盘中提出),因上传空间问题将所有jar包提出放在“libs”目录下,如果用哪个可以自己找一下。内有readme.txt自己看下。 急用的兄弟下吧!
  • 轻量级Java EE 企业应用实战,轻量级Java EE 企业应用实战
  • 轻量级Java EE企业应用实战(第4版):Struts 2+Spring4+Hibernate整合开发(含CD光盘1张)(国家级奖项获奖作品升级版,四版累计印刷27次发行量超10万册的轻量级Java EE经典著作) 李刚 编著  ISBN 978-7-121-...
  • <br /> 轻量级Java EE企业应用实战(第3版)——Struts 2+Spring 3+Hibernate整合开发 李 刚 编著 ISBN 978-7-121-12814-1 2011年2月出版 定价:89.00元(含光盘1张) 16开...
  • 《轻量级Java EE企业应用实战(第5版)》-- 书的配书光盘,书中的代码按章、按节存放。文件里的txt文件里存储的是该光盘的百度云链接。
  • Java EE企业应用实战

    千次阅读 2010-08-26 13:21:00
    前 言 目前Java EE应用的开发方式大致可分为两种:一种以Spring、Hibernate等开源框架为基础,这就是通常所说的轻量级Java EE应用;另一种则以EJB 3+JPA为基础,也就是本书所介绍的经典Java EE应用。在EJB 3出现以前...
  • 本光盘是《轻量级Java EE企业应用实战(第5版)》一书的配书光盘,书中的代码按章、按节存放。文件里的txt文件里存储的是该光盘的百度云链接。
  • 轻量级Java EE企业应用实战(第三版)完整源码. 由于其中lib包太多了。而小弟只能上传50M文件,所以提取出其中第10章和第7章的lib,应该包含了所有jar了吧,欢迎下载哦!
  • 本光盘是《轻量级Java EE企业应用实战(第4版)》一书的配书光盘,书中的代码按章、按节存放,即第2章、第2节所使用的代码放在codes文件夹的02\2.2文件夹下,依此类推。
  • 有没有《经典Java EE企业应用实战——基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发》 的光盘内容?
  • 链接:https://pan.baidu.com/s/1KCR8ZVIcSGZyMnXtkc31FQ 提取码:2f07 复制这段内容后打开百度网盘手机App,操作更方便哦
  • 参考资料 Java EE 应用的分层模型 Domain Object领域对象层 DAOData Access Object数据访问对象层 业务逻辑层 控制器层 表现层 Java EE应用的架构 ...轻量级Java EE企业应用实战(第4版) Java EE 应用的分层模
  • 下载地址:网盘下载李刚编著的《轻量级Java EE企业应用实战(第4 版Struts2+Spring4+Hibernate整合开发(附光盘)》 是《轻量级Java EE企业应用实战》的第4版,第4版 保持了前几版内容全面、深入的特点,主要完成全部 ...
  • 轻量级Java EE企业应用实战(第3版):Struts 2+Spring 3+Hibernate整合开发PDF下载地址 由于PDF文件太大 所以选择上传下载地址。
  • 轻量级Java EE企业应用实战(第5版)——Struts 2+Spring 5+Hibernate 5/JPA 2整合开发是《轻量级Java EE企业应用实战》的第5版,这一版保持了前几版内容全面、深入的特点,主要完成全部知识的升级。 《轻量级Java ...
  • 以前看书从来不做笔记,导致dangshi
  • 光盘下载地址 http://pan.baidu.com/s/1qWQboT2  提取密码 x7ni
  • Java EE企业应用开发教程》源码

    千次阅读 多人点赞 2019-08-27 22:37:28
    将《Java EE企业应用开发教程Spring+Spring MVC+MyBatis》整本书全部源代码分享给大家。 链接: https://pan.baidu.com/s/1SZQ1wHvCTDa_2IIgOqj4QQ 提取码: hwhb(永久有效) 请不要让好资源被埋没,谢谢! ...
  • JavaEE 从入门到放弃(一):Java EE 是个什么东西

    万次阅读 多人点赞 2018-07-09 19:34:09
    从整体上认识 JavaEE,看看 JavaEE 的主要内容。
  • 今天开始阅读李刚的书《经典JAVA EE企业应用实战 基于WebLogic JBoss的JSF+EJB3+JPA整合开发》这本书, 并记录下读书笔记,以方便以后参考。 Java EE应用大致可分为如下几层: 1,Domain Object(领域对象)层:此...
  • 持久化对象 1、持久化类的要求 2、持久化对象的状态 3、改变持久化对象的状态的方法
  • 轻量级Java+EE企业应用实战,包含各种技术的使用轻量级Java+EE企业应用实战,包含各种技术的使用
  • java EEjava SE的区分

    万次阅读 多人点赞 2018-04-15 22:35:57
    JavaEE是指Java Enterprise Edition,Java企业版,多用于企业级开发,包括web开发等等。也叫J2EE。JavaSE通常是指Java Standard Edition,Java标准版,就是一般Java程序的开发就可以(如桌面程序),可以看作是JavaEE...
  • 资源名称:轻量级Java EE企业应用实战 (第4版)资源目录:第1章 Java EE应用和开发环境 11.1 Java EE应用概述 21.1.1 Java EE应用的分层模型 21.1.2 Java EE应用的组件 31.1.3 Java EE应用的结构和优势 41.1.4...

空空如也

1 2 3 4 5 ... 20
收藏数 1,103,840
精华内容 441,536
关键字:

企业应用