精华内容
下载资源
问答
  • 微服务开发中的数据架构设计

    千次阅读 2018-03-18 23:08:04
    原文:微服务开发中的数据架构设计 关注微信公众号:「GitChat 技术杂谈」 一本正经的讲技术 【不要错过文末彩蛋】 前言 微服务是当前非常流行的技术框架,通过服务的小型化、原子化以及分布式架构的弹性...

    GitChat 作者:陈伟荣
    原文:微服务开发中的数据架构设计
    关注微信公众号:「GitChat 技术杂谈」 一本正经的讲技术

    【不要错过文末彩蛋】

    前言

    微服务是当前非常流行的技术框架,通过服务的小型化、原子化以及分布式架构的弹性伸缩和高可用性,可以实现业务之间的松耦合、业务的灵活调整组合以及系统的高可用性。为业务创新和业务持续提供了一个良好的基础平台。本文分享在这种技术架构下的数据架构的设计思想以及设计要点,本文包括下面若干内容。

    • 微服务技术框架中的多层数据架构设计
    • 数据架构设计中的要点
      • 要点1:数据易用性
      • 要点2:主、副数据及数据解耦
      • 要点3:分库分表
      • 要点4:多源数据适配
      • 要点5:多源数据缓存
      • 要点6:数据集市

    为了容易理解,本文用一个简化的销售模型来阐述,如下图。图1显示了客户、卖家、商品、定价、订单的关系(这里省略支付、物流等其他元素)。

    enter image description here

    图1 销售模型

    在这个销售模型中,卖家提供商品、制定价格,客户选择产品购买、形成销售订单。根据微服务的理念设计,可以划分为客户服务、卖家服务、商品服务、定价服务、订单服务,以及公共服务(比如认证、权限、通知等),如图2所示。

    enter image description here

    图2 微服务功能

    微服务架构中的多层数据架构设计

    分布式架构一般把系统分为 Saas(Software-as-a-Service)、Paas(Platform-as-a-Service)、Iaas(Infrastructure as a Service )三层。其中 Saas 层负责对外部提供业务服务,Paas 层提供基础应用平台,Iaas 层提供基础设施。微服务垂直嵌入这三层服务之中,相互独立。因此数据架构设计时需要考虑三层服务对数据的关注点,又要考虑微服务的独立性。

    数据架构的分层设计

    图三 分布式·微服务构架
    图3 微服务技术框架

    如图3所示,Iaas 层提供程序运行的物理基础环境(这边涉及很多硬件·网络内容,在本文中省略)。Pass 层细分为三层,基础服务层,主要负责数据存储处理;事务框架层,主要负责微服务的注册·调度管理、分布式事务处理;应用服务层、主要实现各个微服务的 API,供其它微服务直接调用以及 Saas 层的服务调用。Saas 服务就是公开对外提供的业务服务。

    数据架构自下向上相应的分为 Raw Data 层、Logic Data(inner)层和 Logic Data(outer)层(Iaas 中主要以基础硬件环境为主,在本文中省略)。Raw Data 层是基于数据库、文件或者其他形式数据内容。Logic Data(inner)层是微服务 API 使用的逻辑数据,比如客户数据、订单数据等等。Logic Data(outer)层是对外服务提供数据,比如客户订单数据。因此,我们的数据架构的分层结果如图4所示。

    enter image description here

    图4 数据分层架构

    除此之外,很多情报会以画面或报表的形式展现出来。因此在 Logic Data(outer) 之上,可以构建 Information Block(常用的信息块)、通过 View type(显示模式)的设定后,最终 View 展现出来。

    如图4所示,越靠近对外服务层,客户对设计者的影响度越大,越需要从使用性、易用性、适用性等考虑。反之,越远离对外服务层,设计上更关心数据的存储。

    数据三层架构的好处是实现数据从系统实现到业务实现的逐层过渡,实现业务数据和系统数据间的松耦合。同时实现业务的灵活扩展和系统的灵活扩展。

    数据架构设计中的要点

    上面讲述了数据架构的分层设计,下面讲述数据架构设计中的要点。

    要点1:数据易用性

    数据无论用什么方式实现,其最终目的都是为业务(或者是客户)使用的。因此,在对外提供服务的时候,数据的易用性非常关键。

    enter image description here

    图5 数据易用性

    如图5所示,客户信息在 Logic Data(inner) 层中为了数据的柔软性和非冗余,把人员信息拆成若干子表来存储。比如,人员地址表可以无限多的存储客户地址信息。这样的好处在于每次人员地址更新时,不用直接更新人员地址,而是生成一个新的地址数据,原有的地址信息作为历史数据得到保存,易于数据快速恢复和历史信息追踪。但在 Logic Data(outer)层提供外部数据的时候,首先考虑的是一次性能提供足够用的信息(毕竟查询的操作大大高于修改的操作),减少业务场景中不需要的信息。比如对一般客户只提供三个常用地址的时候,数据设计中地址1、地址2和地址3放在一张表中。

    要点2:主、副数据及数据解耦

    每个微服务 API 的数据完全独立是不太现实的,比如订单中需要有商品、客户(包括收货者)、卖家以及价格等数据。如果这些数据都在订单服务 API 中管理,那么客户情报的变更、价格调整等信息都要同步给订单 API 中数据,数据的耦合度就会变得非常高。在数据设计的时候,需要考虑降低数据间的相互依赖性。因此,首先需要确定每个微服务 API 的主数据和副数据。主数据指微服务 API 的核心数据,这种数据的增删改主要集中在某个微服务 API 中,比如订单服务 API 中的订单数据。副数据指参照或者映射其他微服务 API 的数据,比如订单服务 API 中的商品数据、价格数据等。其次,为了降低数据之间的耦合度,用数据关联表来表征数据间的关系。如果想去掉数据间的关联关系,直接去掉关联表即可,对数据本身的没有任何影响。具体如图6所示。

    enter image description here

    图6 主、副数据及数据解耦

    要点3:分库分表

    随着业务数据量不断增加,单一数据库或单一数据表中会积累大量的数据,比如订单数据,随着时间推移和客户数量的增加,产生的订单数据也会越来越多。当数据累积到一定程度后,数据操作的性能会大幅下降,也就是我们常说的数据库“带不动了”。所以,在数据架构设计阶段就应该考虑数据的分库分表。

    如图7所示,分库,即我们把订单数据分为当前数据应用库、历史数据库、历史归档数据库。当前数据应用库用来支持新订单的生成以及执行中订单的增删改查。历史数据库(这里举例分为最近3个月和最近1年)当客户想看过往订单的时候才使用。历史归档数据(按年间归档)原则上不直接对客户公开,用于备查、统计分析。对于当前数据应用库,可以继续再分库,按客户号范围来分库。这样每个数据库的大小都能得到有效控制。分表,即把一条信息分别存储在两张或多张表中。比如把订单信息按基本信息和详细信息分表,就可以适用于订单的基本信息查询和订单详细信息查询。总之,分库分表的核心就是控制单一数据库的负荷(数据量和数据信息量),通过多表多库来应对业务数据量的增长。

    enter image description here
    图7 分表分库

    要点4:多源数据适配

    传统的关系型数据库之外,有多种多样的数据源,比如图像、声音、视频等多媒体数据文件或数据流,CSV、TXT、Doc、Excle、PDF、XML 等各种异构数。这些数据都需要做相应的处理,转换成可管理的数据信息。因此在数据架构设计的时候,需要给不同性质的数据源配置相对应的读写适配器,同时也需要有统一调度的地方,如图8所示。

    enter image description here

    图8 多源数据适配

    要点5:多源数据缓存

    数据处理的性能除了处理逻辑的复杂度以外,还有很大一部分是目标数据的操作时长(含对硬件磁盘设备的读写以及网络的传输)。网络速度特别是光纤的使用后已经大幅度提高,但机器磁盘的读写效率并没有显著提高,因此减少磁盘读写是提高效率的一个重要途径。数据缓存就是把常用的数据(不会经常更改的数据)、最近使用数据放到内存中。这样就可以大幅降低系统对硬件磁盘设备的操作开销,提高整个数据系统的性能,如图9所示。

    enter image description here

    图9 数据缓存

    要点6:数据集市

    数据集市是一个很大的话题。当现有的数据不能简单地通过几个表数据关联以及简单加工后就可以供业务使用的时候,就需要考虑构建数据集市。数据集市以数据运用的观点来分析加工数据,通过多源数据的导入、清洗、加工、视图做成等一系列的数据操作后,为业务提供可用的、稳定的数据源。例如,对销售分析中、什么样的客户喜欢什么样的商品、价格对销售金额的影响、销售金额跟地区日期的关联关系等多维度分析,就要用数据集市的概念,如图10所示。

    enter image description here

    图10 数据集市

    数据承载着信息,好的数据架构设计会使业务系统变得更加流畅、更加容易理解和维护。本文只是总结一些在实际工程中的体会,供大家分享。如果有不足之处、也请大家补充、赐教。

    【GitChat达人课】

    1. 前端恶棍 · 大漠穷秋 :《Angular 初学者快速上手教程
    2. Python 中文社区联合创始人 · Zoom.Quiet :《GitQ: GitHub 入味儿
    3. 前端颜值担当 · 余博伦:《如何从零学习 React 技术栈
    4. GA 最早期使用者 · GordonChoi:《GA 电商数据分析实践课
    5. 技术总监及合伙人 · 杨彪:《Gradle 从入门到实战
    6. 混元霹雳手 · 江湖前端:《Vue 组件通信全揭秘
    7. 知名互联网公司安卓工程师 · 张拭心:《安卓工程师跳槽面试全指南
    展开全文
  • 嵌入式软件开发工程师谈软件架构设计

    千次阅读 多人点赞 2017-02-19 17:45:45
    以自己的实际经历讲述下曾经对一个嵌入式设备应用软件的架构设计和优化: 笔者曾经接手过一个项目,项目采用单进程多线程的模型,项目中包括几个模块,以a, b, c, d,e代表。这个项目的业务逻辑决定这几个模块有...

    嵌入式软件开发工程师谈软件架构的设计

    注:此处嵌入式特指基于linux平台,单片机和其他rtos不在讨论范围

    • 笔者从事嵌入式软件开发有6,7个年头,bsp,驱动,应用软件,android hall,framework等都有涉猎。平时除了关注嵌入式行业的发展,也多少对Web,后台服务端,分布式等方向的技术有一些关注。

    • 近期有萌生换个行业方向的想法,想做做后台服务器相关的开发,由于之前工作中并没有这方面的实际需求,只是自己平时关注,了解了些知识,比如:NIO,epoll,ngnix,zeromq,libevent,libuv,高并发,分布式,redis,python,tornado,django,涉猎比较杂,都了解个皮毛,不精。意外的是屡屡被互联网行业鄙视,面试机会都寥寥无几。

    • 此时我想到底是什么问题呢,难道嵌入式出身的已经这么不受待见了吗?想当初,嵌入式,驱动开发,可是趋之若鹜的行业(有点夸张,不过8,9年前嵌入式可是听着比做java web的要牛逼些哦)

    问题总是有原因的,我说下自己的理解:

    嵌入式是否真的高大上之为什么没有嵌入式软件架构师?

    • 打开拉勾等招聘网站,搜索架构师,会出现各种系统架构师,web架构师,后台服务端架构师等等,但是唯独很难看到嵌入式软件架构师。嵌入式软件不需要架构吗,驱动不需要架构吗?答案是当然需要,不过为什么没有这方面的职位?

      我的看法:目前国内的嵌入式开发主要分为嵌入式底层开发和嵌入式应用开发,嵌入式的底层开发一般叫做驱动开发,或者bsp开发,有时也有称之为linux内核开发,名字听着都很高大上的感觉。

      这么高大上的名字为什么没有架构师呢:linux kernel的架构师是linus等一众linux kernel开发维护者,因为本身linux kernel或者操作系统就是一个通用的平台,解决通用的问题,linux开源届的大牛都已经制定好了架构规则,留给可发挥的地方并不多,大部分工作只需要按照规则框架填充就可以了,而且以目前国内大部分公司的业务需求,只是在做外围设备的集成,嵌入式平台的porting,搭建裁剪,业务需求完全不会超过kernel里提供的功能范围。导致没有什么新的架构需要开发人员去设计,实现。那嵌入式bsp开发人员都在做什么:除了调试多种多样的外设,替硬件擦屁股,就是解些稳定性的bug了(这里对具体工作不详细描述了,调试外设只会增加一些经验,增加广度,对提高深度贡献不大,只是按不会调试-》会调试-》调试的快这个路线发展,而解稳定性问题确实是需要一些积累经验)

      而嵌入式上的应用开发,一般业务逻辑比较简单,被很多人忽略,所以招聘方也会感觉没有什么必要找架构师级别的了。

    至此感觉嵌入式行业的确不需要架构师,被互联网行业的鄙视也没什么大惊小怪的。

    • 但的确是这样子的吗?对于嵌入式底层的开发,有能力对kernel,驱动架构提出架构层优化的,国内的开发人员应该不多,所以对于大部分普通人,还是不要“妄想”做Linux kernel的架构师了(当然我相信国人中一定存在有这个能力的大牛),发现,解决一些bug,到更靠谱些。

    那么对于嵌入式应用层的开发,我们真的不需要架构吗?

    • 以自己的实际经历讲述下曾经对一个嵌入式设备应用软件的架构设计和优化:
      笔者曾经接手过一个项目,项目采用单进程多线程的模型,项目中包括几个模块,以a, b, c, d,e代表。这个项目的业务逻辑决定这几个模块有不少关联。
      例如:最初的设计中a模块是一个状态监测模块,它会基于监测到的状态调用b,c模块的接口实现一些功能(多线程的好处就是直接调用很方便,所以开发人员大多这么干,简单粗暴),但是需求总是千变万化,加入一个f模块,f模块也需要对a模块监测的状态进行一个处理,按照之前的套路,完成这个功能分两步:1,在f模块提供个接口,2,在a模块中调用该接口。至此新需求已经“完美”的解决了。

    • 前面提到需求总是千变万化的,新的需求又来了,客户提出定制需求,需要加入另一个g模块,同样处理a模块监测的状态,但是该定制需求不需要刚刚加入的f模块,此时最简单粗暴的方式是,定义一个宏,区分该定制需求和之前的通用需求,build两个程序版本。这样的做法看似简单,但后面如果定制需求逐渐增多,维护这么多定制版本程序就是个噩梦,代码管理和通用性也会是很大的问题,同时代码中充斥着对不同宏定义的差异化处理,#ifdef xxx;do_something;#endif比较好的做法是加入设备型号版本的动态监测,用一个build程序版本动态支持所有的定制需求,这样减少了对不同build程序的维护。但是这种做法只解决build程序的版本维护工作,没有解决宏定义差异化处理的问题,只是会将之前的宏判断,改为动态设备版本号判断,如果这些差异化的判断只集中在一处进行,也不会引起大的复杂化的问题,但显然这个是不好保证,有可能这些差异化的处理会蔓延到整个项目的各个角落,这样项目维护起来就会变成一场噩梦。

    • 不需要什么高深的软件思想,大部人都会想到把差异化的部分提取出来,放在一个统一的地方集中管理,对差异化的修改只集中在这个统一管理的地方。
      通用做法就是采用callback设置钩子,然后在callback中定制差异化的需求,对callback的处理做差异化的配置,对应到上面例子,就是在a模块添加一个钩子,然后在系统初始化时,根据设备版本号的不同,差异化定制callback处理函数,同时要将这些定制callback处理函数放在同一地方处理,否则仍然分散在各个角落里就没有意义(前一种方式不放置钩子是无法将这些差异化配置放在一起的),这样处理带来的另外一个好处是,我们对功能性需求的改变,不会影响到a模块的处理,也就是我们添加功能,不需要修改a模块的代码了(前一种方式要修改a模块的调用流程),这样也就实现了一个模块的分离。

    • 至此第二种的方案的架构(其实也谈不上架构了)相比第一种方案已经有了不少提升,至少让开发人员稍微轻松了些,对于其他定制需求,开发人员之需要修改这个callback处理,关注差异化部分就可以了。

    软件是需要不断进化的,第二种方案是最优解吗,当然不是,还有优化空间吗?

    下面先跑个题,谈谈多线程/多进程模型的优缺点,主要谈多进程的优点了:

    教科书上的解释就不提了,首先我对大的项目是推崇多进程模型,无关性能,主要原因有:

    • 模块的解耦:很多开发人员维护开发的多线程模型项目应该都多少会存在下面的问题:跨模块间的直接调用,如果不相信,好,你的项目一定是分模块的吧,现在随机的删掉一个模块,build下看能build通过吗(只需要build不需要运行),我相信大部分情况下一定会遇到某个函数调用,某个全局变量找不到的情况,这种情况说明你的模块间存在强耦合了。由于多线程天然的优势,地址空间的相互可见,导致直接调用十分容易,很多经验尚浅的工程师,很容易就写出直接调用的简单粗暴的接口,如果遇到个static接口的函数,图方便也会把static去掉,直接拿过来用了。这样整个工程随着功能不断的添加,模块间的交叉越来越多,耦合越高。

      而我之所以推崇多进程的原因就是,多进程能从物理上隔绝了这种“方便”的通讯方式,导致在想实现一个模块交互时,会多思考下这个交互是必要的吗,如果是必要的,则会进一步思考接口定义是否简单明了(因为进程间的通讯相对会麻烦些,开发人员会本着能减少交互,明确接口的想法去仔细考虑接口,协议的定义,否则折腾的是自己了),这如同人生,如果一直顺风顺水,人们可能不会想太多,思考太多,而如果道路上有些坎坷,则会有另一种感悟吧。

      所以我的想法是多进程的模型会逼迫你去更多的思考想程序的设计,物理上减少模块的耦合

    • 抽象通用组件,分离通用功能和业务逻辑功能:当把一个多线程模型修改为多进程模型的过程中,经常会发现有些接口代码重复的出现在多个进程模块中,因为之前接口函数是在一个进程空间,大家都可以直接调用的,比如接口A被模块a,b调用,模块a,b分离为两个独立的进程后,接口A需要在a,b中分别实现了,无需解释,重复代码这个在软件工程中是大忌,必须消除。做法也很简单,将这些被多个模块调用的接口分离处理做成lib,供其他模块调用,当你完成这部分工作后,你发现了什么,是不是剥离的接口,可以作为整个项目的通用组件存在了,完美的情况下,lib下的代码是通用基础组件,各个模块中是独立的业务处理模块。

    • 方便定位问题:多线程模型中当又一个线程异常退出,会导致整个进程退出,当然通过一些crash信息,可以定位是那个线程死掉,但如果这些线程模块是由多个小组,人员维护,当整个进程崩溃掉后,如何判断由那个小组解决,会是一个大的问题,而且有时还会出现的现象是挂在一个线程,但其实是另外一个线程模块引起的(耦合的祸端),遇到这种情况,难免出现小组间的扯皮,推诿。(自信的工程师都认为我的代码没有问题)

      而如果采用多进程的模型,好吧,你的服务进程挂了,你自己找原因吧,没什么可争辩的了。

    • 方便性能测试:多线程种单个线程的资源占用不是很好查看(至少有些嵌入式系统没有完善的命令),当整个进程资源消耗很高时,如何判断定位时那个模块线程的问题,同3一样难以抉择,而如果是多进程的模型,谁的进程占了好多资源,谁就去查下吧,其实这个还是个颗粒度的问题,同样的系统,划分成多个进程,单个进程的复杂度一定比只有一个进程的复杂度低的多,复杂度降低,也就更容易定位查找各种问题。

    • 分布式部署:互联网行业一直强调的分布式,云啊什么的,嵌入式行业就很苦逼了,貌似不需要什么分布式吧,其实也对,大部分情况下,嵌入式采用单芯片,独立运行,分布式遇到的很少。但如果万一那天你在一个设备中,将本来一个芯片完成的功能分散到两个芯片中处理呢,多进程的扩展就容易的多了。

      这只是举个特殊的例子,其实嵌入式设备就是个分布式的行业,只是一开始就已经实现分离了,而不是从集中到分布式的路线发展起来的。

    • 方便公司的代码权限隔离:其实我鄙视这种做法,公司要相信自己的员工,但鉴于诚信在中国已经。。。。,做些隔离也无可厚非了。
      多线程模型下,前面讲到如果去除一个模块,你可能都不能build了,那么是要把所有代码暴露给所有的工程师吗,显然不能,所以各个模块只能提供库的形式了,不过我觉得将通用功能接口组织成通用库是正常的做法,而如果把和业务相关的模块也提供成库,就有点。。。。

    至此在补充一下,以上所有的优点,其实都不是很关键的点,都不能够让多进程有绝对的优势压倒多线程模型,只是从个人的角度觉得,多进程模型更能强迫工程师思考解决一些问题。(而这些问题有经验的工程师无论什么模型都会思考的)

    上面说了这么多,该考虑下把之前项目的例子改成多进程模型,否则就只是纸上谈兵了,下面开始:

    首当其冲的问题就是:选择多进程的通讯方式,多线程间的直接调用是不能用了,那么如何选择多进程的通讯方式呢?

    • linux下提供很多ipc方式,此处不一一列举,对于非大数据量的控制,通讯消息的传递,比较好的方式是采用socket,本机上更多采用unix socket方式,(这种方式有什么好处?当你有需要把单一系统做成分布式系统时,优势就明显了)

    • 但是仅仅采用socket来实现前面例子的功能,同样会存在一些问题:
      还是前面的例子,首先说明前面我们优化后的第二种方案在多进程模型已经不能在继续使用了,原因比较简单,应该不需要解释。。。

    • 简单的做法即基于方案一,把直接调用改为socket通信(定义好通信协议即可),但是熟悉socket开发的工程师都清楚,开始socket通信要先进行一些前期的工作(主要就是连接,将两个模块关联起来),所以前面的例子会变成这个样子,模块a要和模块b,c建立连接,如果加入f模块,模块a还要和f模块建立连接。这样情况在心里画一张连接图就会发现好像我们织了一张蜘蛛网,节点间的关系错综复杂,而且和方案一一样,我们添加一个和a关联的模块,就要修改模块a的代码,而且这种情况比多线程模型还有繁琐复杂的多了。这种做法绝对是个噩梦。

      好吧如何解决,我想很多人一定想到了采用总线分发的方式。了解android系统开发的会想到binder,了解openwrt的会想到ubus,了解桌面会想到dbus,互联网行业的开发者一定也知道redis里提供的sub/pub模块。

      上面的binder,ubus等原理很简单,就是建立一个消息中心,构建一个转发路由模型,所有其他模块之间不直接交互,而是采用消息中心转发,路由,而如何决定路由规则,则采用订阅/发布的观察者模式来进行规则的定义。(嵌入式开发或者c语言开发者,经常会误以为设计模式是和面向对象语言关联的,是面向对象语言独有,虽然有很多大牛做了这方面的普及,但鉴于有些开发者的信息渠道比较闭塞,导致这种想法仍然十分盛行)

      基于这个模型,我们上面例子的需求就很好解决了,加入一个消息中心模块,所有需要通信的模块只同该消息中心模块连接,然后订阅自己感兴趣的事件,当事件发生时,只需要进行相应的处理就可以了。

      这样上面的模块b,c订阅模块a的事件,当模块a检测到某事件时,发布该事件,该事件先到达消息中心,在由消息中心转发给模块b,c,而对于新加入的模块f,也只需要订阅该模块,而不需要在修改到模块a的代码,使功能的扩展十分方便。

      同时对于前面提到的定制化开发同样得到了简化,如果定制化版本需要加入模块g,这样只需要定制化版本中将模块g作为一个独立进程启动,然后订阅模块a的事件即可,而定制版本和通用版的区别就在于是否启动模块g的进程,从而实现了软件工程的一个目标:功能的添加如同搭积木一样,只需要把一个模块插入(启动)或拔出(不启动)即可,功能的改变只局限在一个或某几个模块间,对主体框架不会有任何影响。

    以上大概描述了对一个项目需求逐步优化的过程,例子看似是基于嵌入式项目,但貌似对软件工程同样适用。

    • 来到互联网行业:
      查看下各大网站架构师对本网站技术架构变革分享的文章,首先提到的一般都是,基于业务将之前的一个应用服务器功能拆分,更加细化(比如电商对登录,注册,交易,商品,卖家等业务服务的拆分),然后将拆分出来的服务部署在多台服务器上,来提供并发。这里是否有些耳熟,和前面讲到的多线程到多进程的划分是否有相似呢。

      拆分后同样遇到通信的问题,此时很多消息中间件应运而生,比如阿里的duboo,简单了解下这些中间件的原理,无外乎订阅发布,RPC等机制,可以说大同小异,而难点在于协议的制定和性能处理的提升。

      在对照下互联网行业的负载均衡方案,仿佛那个负载均衡的前端也像一个消息中心了。

    行文至此,只是想说明一个问题,软件的设计是相通的,基于的思想是相同的,虽然嵌入式行业的业务逻辑相对比较简单,但其实在仔细思考后,仍然会有很多架构上的改进,设计。

    但是让我感到悲哀的是,有些嵌入式开发者,鉴于业务逻辑的简单,感觉采用一些不那么好的处理方式也能解决问题,不去思考如何去优化,改进。比如上面例子的方案一,如果在定制需求不多的情况下,维护起来也没太大问题,即使定制需求多了,再招些初级程序员也能维护的过来,一个人一套代码负责一个项目的公司也不是不存在。

    同样互联网行业和嵌入式行业也不应该存在一个不可以逾越的高墙,我们更应该关注的是通用的软件工程思想。

    展开全文
  • 敏捷开发中的架构设计

    千次阅读 2015-04-04 20:31:57
    敏捷开发对软件架构设计产生了一定的影响,让人产生敏捷开发中“轻架构设计”的印象。文章就笔者经验,和大家一起讨论一下敏捷中的架构设计这个话题。...这就好比建筑架构设计和建筑工程管理之间的差别一样

    原文地址:http://developer.51cto.com/art/200907/134068.htm



    敏捷开发对软件架构设计产生了一定的影响,让人产生敏捷开发中“轻架构设计”的印象。文章就笔者经验,和大家一起讨论一下敏捷中的架构设计这个话题。

    首先,笔者认为敏捷开发是一种软件过程方法和工具,敏捷开发本身并不能代表架构设计。这就好比建筑架构设计和建筑工程管理之间的差别一样,两者是建筑的两个方面。相同的软件行业也是类似的情况,软件架构设计描述的是事物本身,而敏捷开发描述的是创建这个事物的过程。所以敏捷开发和架构是没有直接替代关系的两个范畴。


    但敏捷开发后,架构设计(内容和形式上)还是有了一定程度的变化。


    1. 敏捷开发中架构设计的方式


    这里的架构设计方式,指什么时候进行架构设计,并以什么样的方式进行架构设计,如Iteration中新需求引入时,重构的方式,Code is Design的方式等。


    下图描述了敏捷开发前和后架构方式:


    敏捷开发前和后架构方式


    上图中,敏捷开发后软件架构设计的方式产生了变化:敏捷开发把原先软件过程前期的架构设计,分散到了整个敏捷开发软件过程中


    看到敏捷开发中分散化的架构设计,想起公司财务中的"马克威茨资产组合理论",用马克威茨这个诺贝尔大师的理论来解释敏捷开发中的分散架构形式,却也行得通。


    “马克威茨资产组合理论”中说道:可以通过分散投资使收益率不变而方差(风险)减少。通俗一点讲也就是不要把鸡蛋放在一个篮子里。资产组合分散化后,可以做到收益率不变的情况下,风险减少。


    这里的风险指的是波动,也就是方差。这和软件工程中的风险有异曲同工之意,即软件工程中的风险指:需求的波动,数学化后就是需求的方差。然后可以按照统计定理推论出,把架构设计组合化,并分散化,有益于收益率不变的情况下,减少软件风险。(中间的推导过程省略,有兴趣的朋友参考相应文献)。


    如果按照资产组合理论,下面这些就是软件架构设计中的组合,把一次性软件过程前期30%(甚至更多)的架构设计,换成如下的软件架构组合:


    (1)引入新需求后的架构。每个Iteration中,新需求引入前,都可以进行构思和架构。


    (2)重构产生架构。先让软件运行,再重构其代码。那么软件的架构随着重构自然而然的在软件过程中产生


    (3)开发过程中的设计:以前是设计完后开发,现在是边设计边开发。


    (4)其他


    所以敏捷开发不是轻架构设计,而是依然注重架构设计。只不过架构的方式变化了,变得更加有效且风险更小。


    2. 敏捷开发中架构设计的内容


    传统的架构设计,包括架构和设计两个方面、其中设计可以包含详细设计,如详细的UML图(详细的类图,顺序图等),详细的API设计以及接口描述,存储层数据库表字段设计等等。


    出于下面两个方面的考虑,敏捷开发不适合这种架构设计内容:


    (1)在当今的快速变化的社会中,业务需求和技术也都快速变化着,在软件过程前期花费30%(甚至更多)的时间进行架构设计,要么开发出来的软件不符合市场需求,要么就是一旦需求变动,造成较大的改动成本。如,作者了解的一个电子商务产品,当前所做的功能都是两年前规划设计的,而且如有新需求发生,需要下个版本才会采纳,导致整个产品脱离市场和客户的需求。


    (2)架构设计包含两个方面,一是:架构,二是:设计。其中设计中的详细设计需要大量的时间,包含详细的流程,API,数据结构等设计。但软件开发阶段的Code编码阶段,同样蕴含了很多详细设计的内容,所以二者之间存在着Repeat Yourself的情况。换句话说,现在敏捷开发提倡Code is design,而以前是Design is code。但问题是,软件开发人员维护一套Design,外加一套Code,不堪重负,效率低。所以,现在是Code is Design盛行,敏捷盛行。


    基于这两种原因,敏捷中将传统的架构设计分成:架构 + 设计


    (1)敏捷开发的架构保留架构部分


    (2)转移设计到Code编码阶段、重构阶段、Unit Test阶段等。


    分离后,敏捷开发中的架构就轻装上阵,内容可以包括:


    (1)软件的架构层次,层次化是软件产品架构中很重要的一部分。


    (2)产品和技术选型


    (3)各个组件的结构,以及的关系


    (4)重要模块,和重要类的说明。但无需设计全部的类,和类的方法。


    (5)….


    而详细设计阶段,则在Code编码和UT单元测试阶段进行。这个阶段重构很重要,重构使你的软件架构和组件结构自然呈现


    所以在敏捷开发中架构设计的内容发生了变化:敏捷开发中止于架构,轻详细设计。但详细设计不是消失不见了,而是转移到了开发阶段,也即是:Code is design。这样既能拥抱变化,又规避风险,又Don't Repeat Yourself。


    3. 敏捷开发中架构设计的人员


    敏捷开发后,软件过程变化了,架构形式变化了,随之相应的人员的责任和需要素质也会变化。


    这里不说整个软件过程中的人员角色,以及职责和能力,如组长,经理,测试人员,开发人员等。这不是说这些的地方。可以另外的文章再继续。


    这里强调的是,敏捷开发架构设计变化后,对开发人员提出了更高的要求,要超越Code is Code阶段,达到Code is Design的要求。如上面我们分析,敏捷开发中架构设计内容变化后,一部分的设计职责转移到了开发人员身上。所以开发人员不仅需要是技术专家,不仅能够写很好的程序,还需要有架构设计思想和能力,能够在开发过程中不断重构出Design。


    总结


    架构描述的是软件本身的结构,敏捷开发描述的是制造这个软件的过程,他们二者是软件科学的两条脉络,互相影响。不管敏捷与否,架构设计依然软件中最重要之一,是软件开发人员的进阶目标。

    
    展开全文
  • 敏捷开发对软件架构设计产生了一定的影响,让人产生敏捷开发中“轻架构设计”的印象。文章就笔者经验,和大家一起讨论一下敏捷中的架构设计这个话题。 首先,笔者认为敏捷开发是一种软件过程方法和工具,敏捷...

    敏捷开发对软件架构设计产生了一定的影响,让人产生敏捷开发中“轻架构设计”的印象。文章就笔者经验,和大家一起讨论一下敏捷中的架构设计这个话题。

    浅谈敏捷开发中的架构设计!(干货)

     

    首先,笔者认为敏捷开发是一种软件过程方法和工具,敏捷开发本身并不能代表架构设计。这就好比建筑架构设计和建筑工程管理之间的差别一样,两者是建筑的两个方面。相同的软件行业也是类似的情况,软件架构设计描述的是事物本身,而敏捷开发描述的是创建这个事物的过程。所以敏捷开发和架构是没有直接替代关系的两个范畴。

    但敏捷开发后,架构设计(内容和形式上)还是有了一定程度的变化。

    1. 敏捷开发中架构设计的方式

    这里的架构设计方式,指什么时候进行架构设计,并以什么样的方式进行架构设计,如Iteration中新需求引入时,重构的方式,Code is Design的方式等。

    下图描述了敏捷开发前和后架构方式:

    浅谈敏捷开发中的架构设计!(干货)

     

    上图中,敏捷开发后软件架构设计的方式产生了变化:敏捷开发把原先软件过程前期的架构设计,分散到了整个敏捷开发软件过程中

    看到敏捷开发中分散化的架构设计,想起公司财务中的"马克威茨资产组合理论",用马克威茨这个诺贝尔大师的理论来解释敏捷开发中的分散架构形式,却也行得通。

    “马克威茨资产组合理论”中说道:可以通过分散投资使收益率不变而方差(风险)减少。通俗一点讲也就是不要把鸡蛋放在一个篮子里。资产组合分散化后,可以做到收益率不变的情况下,风险减少。

    这里的风险指的是波动,也就是方差。这和软件工程中的风险有异曲同工之意,即软件工程中的风险指:需求的波动,数学化后就是需求的方差。然后可以按照统计定理推论出,把架构设计组合化,并分散化,有益于收益率不变的情况下,减少软件风险。(中间的推导过程省略,有兴趣的朋友参考相应文献)。

    如果按照资产组合理论,下面这些就是软件架构设计中的组合,把一次性软件过程前期30%(甚至更多)的架构设计,换成如下的软件架构组合:

    (1)引入新需求后的架构。每个Iteration中,新需求引入前,都可以进行构思和架构。

    (2)重构产生架构。先让软件运行,再重构其代码。那么软件的架构随着重构自然而然的在软件过程中产生

    (3)开发过程中的设计:以前是设计完后开发,现在是边设计边开发。

    (4)其他

    所以敏捷开发不是轻架构设计,而是依然注重架构设计。只不过架构的方式变化了,变得更加有效且风险更小。

    2. 敏捷开发中架构设计的内容

    传统的架构设计,包括架构和设计两个方面、其中设计可以包含详细设计,如详细的UML图(详细的类图,顺序图等),详细的API设计以及接口描述,存储层数据库表字段设计等等。

    出于下面两个方面的考虑,敏捷开发不适合这种架构设计内容:

    (1)在当今的快速变化的社会中,业务需求和技术也都快速变化着,在软件过程前期花费30%(甚至更多)的时间进行架构设计,要么开发出来的软件不符合市场需求,要么就是一旦需求变动,造成较大的改动成本。如,作者了解的一个电子商务产品,当前所做的功能都是两年前规划设计的,而且如有新需求发生,需要下个版本才会采纳,导致整个产品脱离市场和客户的需求。

    (2)架构设计包含两个方面,一是:架构,二是:设计。其中设计中的详细设计需要大量的时间,包含详细的流程,API,数据结构等设计。但软件开发阶段的Code编码阶段,同样蕴含了很多详细设计的内容,所以二者之间存在着Repeat Yourself的情况。换句话说,现在敏捷开发提倡Code is design,而以前是Design is code。但问题是,软件开发人员维护一套Design,外加一套Code,不堪重负,效率低。所以,现在是Code is Design盛行,敏捷盛行。

    基于这两种原因,敏捷中将传统的架构设计分成:架构 + 设计

    (1)敏捷开发的架构保留架构部分

    (2)转移设计到Code编码阶段、重构阶段、Unit Test阶段等。

    分离后,敏捷开发中的架构就轻装上阵,内容可以包括:

    (1)软件的架构层次,层次化是软件产品架构中很重要的一部分。

    (2)产品和技术选型

    (3)各个组件的结构,以及的关系

    (4)重要模块,和重要类的说明。但无需设计全部的类,和类的方法。

    而详细设计阶段,则在Code编码和UT单元测试阶段进行。这个阶段重构很重要,重构使你的软件架构和组件结构自然呈现

    所以在敏捷开发中架构设计的内容发生了变化:敏捷开发中止于架构,轻详细设计。但详细设计不是消失不见了,而是转移到了开发阶段,也即是:Code is design。这样既能拥抱变化,又规避风险,又Don't Repeat Yourself。

    3. 敏捷开发中架构设计的人员

    敏捷开发后,软件过程变化了,架构形式变化了,随之相应的人员的责任和需要素质也会变化。

    这里不说整个软件过程中的人员角色,以及职责和能力,如组长,经理,测试人员,开发人员等。这不是说这些的地方。可以另外的文章再继续。

    这里强调的是,敏捷开发架构设计变化后,对开发人员提出了更高的要求,要超越Code is Code阶段,达到Code is Design的要求。如上面我们分析,敏捷开发中架构设计内容变化后,一部分的设计职责转移到了开发人员身上。所以开发人员不仅需要是技术专家,不仅能够写很好的程序,还需要有架构设计思想和能力,能够在开发过程中不断重构出Design。

    浅谈敏捷开发中的架构设计!(干货)

     

    总结

    架构描述的是软件本身的结构,敏捷开发描述的是制造这个软件的过程,他们二者是软件科学的两条脉络,互相影响。不管敏捷与否,架构设计依然软件中最重要之一,是软件开发人员的进阶目标。

    展开全文
  • iOS开发那些事-移动平台架构设计

    万次阅读 2013-04-24 09:11:29
    低耦合企业级系统架构设计我们往往称JavaEE或.Net 开发的产品为“系统”,而移动平台(主要是:Android、iOS和Window Phone)开发的产品为“应用”。“系统”比较复杂,需要架构设计,而“应用”相对比较简单,这...
  • 数据交换平台的架构设计

    千次阅读 2014-10-29 12:53:13
    说到架构设计,不敢妄自牛逼。只能默默地向Linux致敬,没有强大的linux系统,我们做的架构设计,做的程序一天说不定挂几次。
  • 大数据架构、大数据开发数据分析的区别 大数据产业 顾名思义大数据是一个以数据为核心的产业。大数据产业生成流程从数据的生命周期的传导和演变上可分为这几个部分:数据收集、数据储存、数据建模、数据分析、...
  • 字节跳动测试开发工程师-产品研发和工程架构部职位面试被虐面向对象语言的封装、继承和多态浅拷贝和深拷贝类和对象OSI七层模型、作用和每一层对应的协议当python读入文件的时候发生了什么?手撕代码 面向对象语言的...
  • 从需求分析师到数据仓库架构师、ETL工程师、数据分析工程师、报表开发工程师、数据挖掘工程师等,都可以称为BI工程师。 ETL工程师:从事系统编程、数据库编程和设计,掌握各种常用编程语言的专业技术人员。也称为...
  • 什么是一个好的应用架构?怎么才能搭建大型的应用架构?其实每个人在工作几年之后都会有这个疑问,都在寻求好点的框架,那么小编我总结一下我的经验给大家。  其实对于客户端,一个好的应用架构,复杂度不亚于...
  •  软件开发方法包括:软件生命周期、软件开发模型、软件重用技术、逆向工程及形式化开发方法 一、软件生命周期  软件产品从形成概念开始,经过开发、使用和维护,直到最后退役的全过程成为软件生存周期。  ...
  • 数据密集型系统架构设计

    万次阅读 2016-05-19 20:07:30
    大数据技术对商业效果的提升已经在越来越多的行业中被证明,未来的...因此,未来越来越多的系统的主要瓶颈会从计算、IO转移到数据量上,内存密集型系统会变得越来越重要,相信其架构在未来几年也会有很多新的方式出现。
  • 一个图形数据维护工具架构设计

    千次阅读 多人点赞 2012-09-20 14:10:17
    一个图形数据维护工具架构设计   1、背景  近期负责一个GIS矢量化项目,工程中涉及图形数据、GIS业务数据的关联存储和管理。为弥补图形矢量化软件在附属属性管理方面的局限性,采用两套数据库系统进行图-数...
  • Django项目开发流程&项目架构

    千次阅读 2018-06-01 20:49:12
    项目开发流程&项目架构 1. 软件开发的一般流程   1. 需求分析及确认: 由需求分析工程师与客户确认甚至挖掘需求。...详细设计中描述实现具体模块所涉及到的主要算法、数据结构、类的层次结...
  • Unity 3D 引擎对于开发者来说,...但凡只要懂一门编程语言的人都能使用 Unity 3D 引擎开发,另外 Unity 3D 的内部架构设计非常好,采用的是组件开发,开发者能快速通过组件堆积出一个游戏。既然使用 Unity 3D 引擎
  • Architectures(主流架构) EmptyGO Simple GameManager Manager of Managers MVCS(StrageloC) MVVM(uFrame) ………. EmptyGO 问题:消耗资源;不易于管理 Simple GameManager 问题:GameManager文件过于庞大...
  • 一、软件架构设计 软件或计算机系统的软件架构是该系统的一个(或多个)结构,而结构由软件元素、元素的外部可见属性及它们之间的关系组成。 软件系统架构是关于软件系统的 结构、行为和属性 的高级抽象。指定了软件...
  • 1、hadoop 工作原理(最常见的问题):  a.首先 概括里面的角色(HDFS 、Mapreduce) ... 分布式文件系统,用于海量数据存储。  架构:   master/slave 架构 :1个Namenode和多个Ddatanode。  
  • 但凡只要懂一门编程语言的人都能使用 Unity 3D 引擎开发,另外 Unity 3D 的内部架构设计非常好,采用的是组件开发,开发者能快速通过组件堆积出一个游戏。既然使用 Unity 3D 引擎开发游戏这么简单,那它有没有坑呢?...
  • 结构设计的层次是否越多越好? 多人都会说,凡事不能走极端,走了极端就...我做(开发架构的几个原则,根据优先次序高低排列:1. (逻辑)拆分越细越好 2. 依赖关细越少越好 3. 交互越少越好 ... 相互矛盾时,如
  • 架构设计(1)-谈谈架构

    万次阅读 多人点赞 2017-10-17 11:18:15
    1、什么是架构架构本质 在软件行业,对于什么是架构,都有很多的争论,每个人都有自己的理解。 此君说的架构和彼君理解的架构未必是一回事。因此我们在讨论架构之前,我们先讨论架构的概念定义,概念是人认识这...
  • 浅谈棋牌游戏开发框架之架构

    千次阅读 2018-11-06 15:50:05
    浅谈棋牌游戏开发框架之架构 关键字: 棋牌游戏 架构 框架 开发...二、架构设定解耦,复用性,拓展性多自由度、可分拆多项目开发,符合敏捷需求品质保证体系高效开发支撑公司大部分业务三、模块设计概要减少客户端对Coco...
  • Android开发软件架构思考以及经验总结

    万次阅读 多人点赞 2016-12-25 16:31:54
    本文目的有三,一是整理这段时间的架构学习和思考以及总结这一年的开发经验教训,二是希望能够与各位朋友探讨移动端App的架构设计,三是希望我们每一个应用开发者能够拥有架构的意识。个人的水平有限,文中如果不当...
  • 上文中对功能和产品进行了区分。...介绍系统架构之前,先简单介绍下ADAS/AD ECU常见的硬件架构。不展开描述,后续有专门章节深入探讨。目前主流的ADAS/AD ECU的硬件架构,一般有多个芯片(Core)构成;芯...
  • Android开发——微信Android架构历史

    千次阅读 2017-08-13 20:31:54
    微信Android诞生之初,用的是常见的分层结构设计。这种架构简单、清晰并一直沿袭至今。这是微信架构的v1.x时代。图1-架构演进到了微信架构的v2.x时代,随着业务的快速发展,消息通知不及时和Android 2.3版本之前...
  • 在各个网站和论坛,一说到数据仓库,基本都想到了"ETL※DW※OLAP",一说到数据仓库设计,就是按照行业规范和客户需求调研,设计主题,然后设计对应的­事实表、维表。但是,这就是真正的数据仓库总体设计么? 关于...
  • 软件架构设计之七:软件架构设计

    千次阅读 2013-08-27 20:28:13
    一、本章要点 ...2)系统架构设计案例分析。包括软件架构技术、XML技术、基于架构的软件开发过程、架构模型(风格)、特定领域软件架构、基于架构的软件开发方法、架构评估、软件产品线、系统演化、设计
  • 棋牌游戏开发框架Theway 架构

    万次阅读 2017-02-09 16:41:10
    说在前面的话:棋牌游戏市场,大部分都是品质低劣,生命周期短暂,绝大部分原因是因为棋牌游戏开发成本低,对开发人员的要求也低。大部分团队只需要快速出成品,只要有东西快速赚钱就可以了。16年的私人房模式,再次...
  • 2006年6月24日 成都User Group活动-J2EE应用架构设计开发主 题:J2EE应用架构设计开发时 间:2006年6月24日 下午1点-5点半地 点: 绿洲大酒店(公交车路线-341、3、18、45、23、73路可以到达)联 系 人: 喻...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 258,090
精华内容 103,236
关键字:

数据开发工程开发架构设计