MyException - 我的异常网
当前位置:我的异常网» 互联网 » 互联网络项目架构

互联网络项目架构

www.MyException.Cn  网友分享于:2013-09-19  浏览:0次
互联网项目架构

互联网项目架构

 

 

什么是架构设计

 

      通俗的说,架构设计就像是小学考试中解答应用题的过程,但是解决的问题更复杂,构思设计的过程更庞大,解题的工作量更大。

 

 

 

 

项目的质量指标

 

      软件开发的最终目标是使用代码去实现抽象的业务逻辑,然后根据下面的指标评价项目的好坏:

 

  • 功能:功能目标是应用的基本要求,如果不能实现既定的功能逻辑,应用就失去了存在的意义,因此实现产品需求是应用的基本的目标。
  • 可用性:这也是软件需求的一个基本标准,服务器挂了,数据库挂了,系统还能否继续用,就是单点问题,简单的做法就是做集群,虽然回增加维护量,但这是解决单点的最有效方法。
  • 性能:在基本的功能之上,会有一些性能的要求,但是很少有产品经理或者用户能提前提出这样的要求,因此架构师要有丰富的经验去发现和解决(或者为未来提升性能做准备)性能问题。性能的主要衡量有:单次请求的相应时间,单实例请求并发数,服务最大并发量等。
  • 扩展性:目前互联网应用的开发模式:快速响应,迭代开发;提出需求,快速相应,尽快上线,是骡子是马拉出来溜溜。所以这就要求系统的架构设计要更好的响应新的需求和需求变更。

 

 

 

 

架构设计的主要过程

 

  • 确定问题域
  • 数据建模
  • 模块划分
  • 关键流程描述
  • 技术选型
  • 代码实现
  • 验收测试

 

 

 

确定问题域

 

       记得小学考试后拿到老师改过的卷子,对着一个个的大红叉都会懊恼:”哎,又看错题目了“。错误的方向危害大于错误的方法,没有找对方向,项目就会南辕北辙,远远偏离目标。来自产品经理或者用户的需求描述就是我们的问题域,但是来自于产品经理的需求描述会比较全面,内容也很多,来自用户比较简单,相对比较模糊。比如电商项目的需求文档会非常大,拿到一个几十上百页的需求文档(有程序员拍砖说,我家的产品只一段话”像XXX网站的功能copy一下吧”,哈哈)时,往往不知道从何处下手,所以我们要从繁杂的问题域中找到关键问题。

 

例子1:

 

    1. 用户可以在我们的app给其他人转钱

     

    从 1 出发,又延伸出几个问题

 

    2. 用户访问:用户注册、登陆

 

    3. 用户信息:用户可以查看自己信息,还有绑定基本信息

 

    4. 用户交易:给别人转钱,钱是怎么转过去的,一般通过第三方机构的API实现

 

    从 3 出发,又往下延伸

 

    3.1. 补全用户信息:在注册时,尽量简单,等用户需要交易或其他操作时,让用户不全信息,如:email 、mobileNo 、 银行卡。

 

    3.2. email 和 mobileNo 绑定:这里的绑定,需要发送验证,然后激活。

 

    3.3. 银行卡绑定:需要依赖第三方平台的API

 

    从 4 出发,又往下延伸

 

    4.1. 收钱的人是不是app用户

 

    4.2. 收钱的人是不是我的朋友,如果是直接交易,如果不是那是否允许交易,如果允许交易,交易后是否成为朋友

 

    4.3. 交易完成后,应该显示用户的交易记录,成功的怎样显示,失败的怎样显示

 

 

例子2:

 

    1. 我是app用户,想添加某人成为朋友

 

    从 1 出发,延伸出下面问题

 

    2. 我想加的人,是不是app用户

 

    3. 加朋友前和加朋友后,看到的这个用户信息有无变化

 

    4. 加朋友的申请流程

 

    从 2 出发,往下延伸

 

    2.1. 根据别人的email 、mobileNo,在app中查看是否存在,如果存在,就可以申请加好友;如果不存在,就邀请他成为用户

 

    2.2. 从我的通讯录中,现有的email、mobileNo,查看这些是否存在已经是app用户的,如果有,可以申请加好友

 

    从 3 出发,往下延伸

 

    3.1. 加好友前,可以看到别人的姓名、电话等基础信息

 

    3.2. 加好友后,除了可以看到基础信息外,还可以看到别人的一些公开的交易记录

 

    3.3. 用户可以设置自己的交易记录是否公开,公开的话,可以让他的共同朋友看到,如果不公开的话就看不到

 

    从 4 出发,往下延伸

 

    4.1. 能不能重复申请添加好友

 

    4.2. 添加好友申请,是否有有效期

 

    4.3. 申请添加好友后,是不是要推送消息,还有app的图标上是否加上一个1标记

 

    

       不断的展开问题域,就可以把整个流程转起来。当然实际应用的时候我们不会把所有的问题域都总结出来,确定了关键问题就可以开始数据建模了。

 

 

 

性能问题

 

        性能的问题域应该是针对关键路径确定的,比如用户交易,绑定银行卡,查看交易记录等。针对于这些关键路径问题,可以定义一些问题域,比如单实例支持1秒内完成1000条交易记录的查询,100单/秒的交易提交等。

 

 

扩展性问题

 

       扩展性是最难把握的,因为每个人经历不同,针对同样的项目会对未来需求有不同的预期,因此怎么把握当前的功能和未来的变化,如何平衡性能和扩展的关系,是架构师设计的关键。以我的的经验来看,扩展把我关键问题,优先满足关键问题的性能,确定最小功能集。确定最小功能集的优势可以快速实现,快速验证需求的准确性,每次需求开发都完成最小和最关键的需求。设计的时候要满足一些思想和原则,OOP(面向对象设计)原则:1、单一职责原则;2、开放闭合原则;3、里氏替换原则;4、依赖倒置原则;5、接口隔离原则;数据库设计三范式等等。扩展的问题域也可以参考友商或者与有经验的产品运营沟通,大致了解存在的扩展性。电商项目可能会有:投资,基金,买黄金等业务都是电商的一些扩展需求。

 

 

 

 

 

数据建模

 

       确定了问题域就可以开始答题了,确定数据模型。大部分的应用基本使用的仍然是关系型数据库,所以我们针对问题域先创建数据表,当然也存在一些项目使用NoSQL存储或者不持久化数据,这里确定的就是问题域的实体类。上面问题域中的每一个名称,都可以建一个表。如:用户、交易记录、申请加好友记录。

 

       我比较喜欢使用powerdesigner做数据库模型,可以直观的看到表结构,方便修改,可以生成大部分DB的DDL SQL。为上面找出的名词(实体结构)创建表结构,然后根据产品需求文档一条一条的阅读判断,当前表结构是否可以满足需求,如果不能满足,在表中添加列或者添加新的表来满足此需求,不断的去丰富表结构直到完全满足需求。当然在建模的过程中也会调整原来的表结构,毕竟不断的增加需求,会引起数据模型的变化,所以最初建立的肯定不完整,不断调整直到满足所有需求。

 

 

数据建模的建议

 

    1. 数据表包含自增id,创建时间createTime,更新时间updateTime和版本号version

 

  • 自增的id:主键,根据id查询或者更新时,速度毕竟快。
  • createTime和updateTime:记录创建时间和最后的更新时间,排查问题的关键点
  • version:编辑时version++,是一个很方便的乐观锁,能比较大的提升数据库的性能

 

    2. 不使用外键,这点有一些和数据库设计的规范相悖,但是这是来自真实经验总结,外键约束带来的数据完整性的优势远远小于更新逻辑实现的难度。从性能和扩展性来看不使用外键也是利大于弊,大数据高并发大流量的互联网应用提供性能的常用方法是:提高数据库的访问速度,缓存数据,数据库分库分表支撑高并发等,外键是对这些方法的一个制约。

 

 

    3. 不使用id作为表关联,虽然我们不创建外键约束,但是不代表表之间没有关联关系。所以表之间仍然会有外键,但是没有外键约束,设计这个外键的时候要考虑数据的增长型,数据没有确定的规模,那么参考增长的速度,我们可以设定一个未来3-5年的数据规模,如果单表不能满足,则数据存在分表的可能性,那么表间的关联使用全局的唯一id的方式一个更好的选择。全局唯一id的方式有很多算法,使用数据库(oracle的sequence和mysql的自增id,这里是为生成id的特殊表的自增)生成是一个比较好的方式,当然也可以使用组合方式添加数据类型,时间,地域等方式,也有使用uuid算法计算的方式,只要可以满足不重复的特点,选取那种方式可以参考一下产品的意见,因为这个字段用户可能感知。

 

 

    4. 表有没有多少列的标准?记得刚开始做设计的时候,经常怀疑自己是不是分的表太多或者太少,太大了是不是会影响性能,太少了是不是有点画蛇添足。应用最初的设计最符合设计原则和设计思想的,没有收到工期,团队分割,实现难度等非设计因素的影响,所以我们应该尽量的坚持最初的设计,克服其他因素的影响。

 

 

    5. 冗余字段是否有必要?我的做法是不使用,保持原有的设计,如果系统真的流量比较大,查询性能太低,可以通过把读服务从业务系统中分离(这里要注意不是数据库的读写分离)。从业务上把读写分开,做一些便于查询和提高性能的设计,通过一些数据抽取方式同步数据。这里会有人提出异议,这样做会导致用户的读延迟,其实展示性数据对数据的延迟是有很大的容忍度的,只有业务系统需要做到数据的一致,那么业务系统对数据的读取是针对性的,很少会出现需要很多关联数据的情况,所以最初设计系统时尽量少的使用冗余字段去提供查询的方便性和性能。

 

 

 

 

模块划分

 

       如果数据模型主要为满足功能目标的话,模块划分会比较多的兼顾性能和扩展性,常用的互联网应用的模块划分和部署结构有如下几种(这里讨论的划分和部署是互联网应用的服务器端),不考虑浏览器和APP等客户端,当然介绍的几种也是常用的结构。

 

 

单实例结构


           

 

  • 优势:结构简单,便于开发部署
  • 劣势:可能存在性能瓶颈,扩展性差,系统耦合性高

 

 

集群结构


   

 

    备注:db层作为整体描述,可能存在单DB,读写分离,分库分表或者数据cluster等技术

 

  • 优势:性能大大提供(理论上可以无上限)
  • 劣势:负载存在平衡的可能,仍然会存在性能瓶颈,扩展性差

 

 

分布式结构


    
 

       分布式系统是把不同的业务切分到不同的实例中,功能相关的聚合到同一个实例中,系统间使用网络协议通信的一种结构。

 

  • 优势:扩展性强,高内聚,低耦合
  • 劣势:结构复杂, 事务控制难度大,开发工作量大

 

 

混合结构

 


   
 

    混合结构是分布结构基础之上每个模块又实现集群结构,所以这个模式放大了分布式结构的优势和劣势。

 

  • 优势: 扩展性强,高内聚,低耦合,健壮性高
  • 劣势: 结构复杂, 事务控制难度大,开发工作量大

 

 

总结

 

       大部分的互联网应用的结构都可以用上面的4个结构描述,当然这里只是简单的描述,一些应用为了提高数据库访问会加上DB缓存,为了提高页面的访问速度做页面静态化和CDN,为了应对大数据的存储和检索使用NoSQL数据库等,但是我们设计的结构是不受影响的。

 

 

 

如何选择系统结构

 

      1. 系统是否能满足未来2-3年的增长,如果采用混合结构的系统工作量要远远大于单例结构的系统,对初创企业来说,上线才是最大的需求,所以拼速度的时候就要放弃优雅。如果公司有一定的规模,开发的应用是核心业务或者未来的核心业务,采用扩展性强的混合结构应对未来的快速发展的业务需求是一个更好的选择。

 

      2. 人力因素,混合结构要比单实例的结构工作量增加很多,并且对团队整体的技术水平有较高的要求,所以要”量力而行”。

 

      3. 时间因素,很多互联网公司的工期不是技术评估的,是由”市场”确定的,所以火烧眉毛的时候就别讲究性能和扩展了,上线再说。

 

      4. 架构不是一成不变的,不断增加的访问和不断变化的需求改变着系统的架构。快速响应,不断迭代才是互联网应用的方式。所以最初的架构,尽量的做到高内聚低耦合,这样不断的提高系统的短板,逐渐完善系统结构。

 

 

 

分布式结构电商模块描述

 



 

 

显示层

 

    前台:用户端界面显示层,依赖用户服务,商品服务,交易服务和支付服务。

 

    后台:运营端界面显示层,运营人员管理各种数据的界面。 依赖用户服务,商品服务,交易服务和支付服务。

 

服务层

 

    用户服务:注册,登录,用户管理等

 

    商品服务:商品浏览,库存展示,商品管理,库存管理等

 

    交易服务:购物车服务,订单计算, 订单提交,订单列表等

 

    支付服务:生成支付链接,支付成功跳转,支付成功逻辑处理等

 

基础组件

 

    DB:数据存储

 

    Redis:使用redis实现用户状态session机制,便于将来集群部署;实现购物车功能,用户购物车服务端持久化,便于用户跨浏览器购物车管理。

 

    第三方支付组件:用于与第三方支付服务交互

 

 

 

 

关键流程描述

 

       关键流程描述是检查系统架构是否满足需求和指导开发的必要条件。关键流程描述是使用流程图解决关键问题的过程,它的使用者是团队其他成员和自己,所以格式不重要,其他人能明白就好。

 

 

要注意的地方:

 

      1. 有始有终,流程应该是从用户进入应用开始到离开应用的完整过程,比如交易的过程,应该从用户用户登陆到找到朋友到用户支付成功这一个过程。

 

      2. 流程图突出重点,比如上面举例的交易过程,应该突出交易相关的流程判断,不必描述用户注册,找回密码等过程。

 

      3. 简要说明,避免过于详细,比如交易的过程中需要更新库存,但是不需要描述更新库存前的库存校验这些是提交订单的内部实现。

 

流程图可以做成如下:



 

 

 

 

 

技术选型

 

    1. 如果非必要请使用常用的技术,框架等,常用技术和框架使用者多,所以会比较少的遇到非业务问题。曾经参与的一个项目,其中一个模块由一个比较熟悉python的同学负责,系统刚刚上线,因为一些原因要离职,没有人可以接下来,只好找其他的语言重新开发了一遍。

 

    2. 熟悉的优于强大的,尽量采取团队比较熟悉的技术或者使用团队中有人可以指导的技术。记得5年前为甲方公司做一个需求和Bug跟踪的工作流的系统,轻率的决定使用JBPM,因为团队中没有人研究过,所以花了大量的时间使用这个框架,最后也没有很好的使用,导致项目步履蹒跚。

 

 

 

 

 

代码实现

 

      代码首先是给人读的,其次才是给机器读,所以良好的代码结构是项目存活更长时间的良药。

 

代码分层

 

       功能单一原则,mvc是互联网应用的一种基础模式,从功能层次上划分为,v显示层,c控制层,m业务层。以Java实现业务分层如下:


    

 

    controller:页面控制层,用于页面出参入参转换和页面跳转

 

    vo:贫血实体对象,用于页面和业务层的数据传输

 

    bo:业务实现层

 

    dao:数据访问层,用于处理与数据库的交互

 

    service:业务逻辑层,主要负责业务逻辑和一些运算

 

 

命名规范

 

       代码中使用的类,方法,变量,参数等,采用统一风格命名,英文或者中文拼音,驼峰或者下划线分隔,尽量采用业界常用风格。类,变量和参数采用使用名词,方法使用动词等。

 

 

注释风格

 

       采用统一的注释风格,方法内一般采用行注释,其他地方采用段注释。

 

 

 

 

验收测试

 

       积极配合测试团队对项目的测试,他们是为项目健康上线保驾护航的人,不是挑刺的人。

 

 

 

文章评论

2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
代码女神横空出世
代码女神横空出世
程序员都该阅读的书
程序员都该阅读的书
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
如何成为一名黑客
如何成为一名黑客
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
一个程序员的时间管理
一个程序员的时间管理
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
旅行,写作,编程
旅行,写作,编程
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
编程语言是女人
编程语言是女人
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
为什么程序员都是夜猫子
为什么程序员都是夜猫子
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序员和编码员之间的区别
程序员和编码员之间的区别
Java程序员必看电影
Java程序员必看电影
我是如何打败拖延症的
我是如何打败拖延症的
那些争议最大的编程观点
那些争议最大的编程观点
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
老程序员的下场
老程序员的下场
中美印日四国程序员比较
中美印日四国程序员比较
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
程序员应该关注的一些事儿
程序员应该关注的一些事儿
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员必看的十大电影
程序员必看的十大电影
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
 程序员的样子
程序员的样子
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
鲜为人知的编程真相
鲜为人知的编程真相
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
10个调试和排错的小建议
10个调试和排错的小建议
程序员的鄙视链
程序员的鄙视链
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
漫画:程序员的工作
漫画:程序员的工作
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有