软件构架 – 无技术简篇

软件构架

所谓的软件构架,是有关软件整体结构与各组件的抽象描述,用于指导大型软件系统各个方面的设计。一个好的软件构架,会随着业务的不断深入发展而不断的演化;但一个不好的软件构架,却会阻碍业务发展,甚至会成为业务发展的瓶颈。在一个大型的系统,构架始终围绕着“高可用 高性能,易扩展,可伸缩,高安全”等等几方面展开。需要强调的一点是,构架是有业务驱动的,适合淘宝腾讯等大型的互联网成功的构架,并不一定适合自己的业务,所以不要为了构架而构架,为了技术而技术

对于大型互联网应用,具备非常显著的特点:

  • 高并发,大流量 — 并发的访问的用户数很大,流量很高         
  • 高可用 — 7 * 24小时不间断运行
  • 海量数据 — 存储和管理的都是海量级别数据
  • 用户分布广,网络情况复杂 — 用户全球分布,网络环境复杂和使用设备类比很多
  • 安全环境恶劣 — 互联网开发环境天生开放性,易受攻击
  • 需求变更频繁,发布布频繁 – 为了快速适应市场占有市场,需求变更很产品发布频率极高
  • 渐进式发展 – 没有从一开始就规划好功能需求和非功能需求,都是适应市场发展

在传统软件行业,往往听到很多需求不确定的抱怨,相对于互联网企业,需求本身可能就不确定,就算是确定需求而又可能变更频繁,所以大多都是渐进式发展,SO,少点抱怨,多点务实。大型互联网技术挑战来源: 庞大的用户,高并发,和海量数据处理。

软件构架发展

构架的发展和演化都是有业务推动的,面向服务的体系结构(SOA),已经被演化为大型企业的成熟构架。

  1. 发展最最初级阶段构架

    发展最最初级阶段构架
    这个阶段的特点是:应用服务器,文件,数据库都部署在同一台物理机器上面。用户少,访问量低。使用各类开源软件和廉价服务器即可开启发展之路。

  2. 应用服务和数据服务分离

    应用服务和数据服务分离
    一般而言,对于应用服务器,瓶颈是CPU,数据库服务器,瓶颈是IO,文件服务器,瓶颈是硬盘。随着用户的增加,访问量的增加,单一服务器很快的遇到性能瓶颈。自然而然,数据服务和文件服务独立出来,使用独立的服务器,进行独立部署。

  3. 使用缓存解决性能

    使用缓存解决性能
    当数据库压力增大,限制业务发展,对关键业务使用缓存。使用缓存,分本地缓存和远程缓存。使用缓存后,应用服务器对于关键业务,首先考虑的是访问本地缓存,如果不命中,再访问远程缓存和数据库。热点数据需要考虑怎么和数据库同步。

  4. 应用服务群集解决并发能力

    应用服务群集解决并发能力
    当应用服务成为性能瓶颈单台机器无法支撑业务的时候,使用应用服务群集,再在前面增加负载均衡调度服务器。这样要求应用服务做到会话无关,或者使用分布式缓存解决会话问题。这样应用服务器随时可伸缩,不在会成为瓶颈。

  5. 数据库读写分离

    数据库读写分离
    数据库压力增大,使用缓存之后,一般数据库访问会降低,但却存在部分读不命中,写操作访问数据库。数据库主从配置是数据安全和故障恢复的一个重要措施,也是提高数据性能的一种措施。数据库进行配置主从复制,主库负责写,备库负责读,实现读写分离。至此,可看到,应用服务器已经需要做很大的改动了。

  6. 反向代理和CDN加速

    反向代理和CDN加速
    这里主要是资源的加速,反向代理和CDN本质是缓存,解决复杂网络情况下的访问,负载均衡调度优先反向代理访问。

  7. 使用分布式文件服务器和数据库服务器

    使用分布式文件服务器和数据库服务器
    数据库主备读写分离不能满足业务增长需求,文件服务也一样,那么就需要进行拆分。分布式文件服务器和分布式数据库,带来更难的运维,只要非不得已,才使用。

  8. 使用nosql数据库和搜索引擎服务器

    使用nosql数据库和搜索引擎服务器
    业务复杂性增加,考虑使用nosql数据库解决复杂的数据存储和使用搜索引擎服务器解决检索需求。

  9. 业务拆分

    业务拆分
    业务拆分应对各种复杂的业务需求,形成不同的产品线。可能会涉及分库,分表等。

  10. 分布式服务

    分布式服务
    每个产品线都要有共同发数据访问需求,将这些需求独立起来分布式部署。

由以上可看到,随着业务的不断发展和深入,应用服务都随着构架的不断改变和不断进行演化,最终形成面向服务的体系结构。也可看到,构架的变化会给应用服务的时候越来越复杂,运维也是越来越复杂。对于一个少量用户而言,追求者复杂的构架可能适得其反。所以再次强调的是,不要一味追求大型构架技术,业务驱动构架,不是构架驱动业务。不要一味追随大公司的解决方案,不要为了技术而技术,不要企图解决所有问题(这是有血的教训的)。

可幸的是,对于靠谱的云计算平台,已经产品化各种需求,中小企业可能不在需要关心构架问题,按需付费即可使用。使用云计算,不再需要自己拼凑资源,使用现有的一切技术方案,即可完善自己的构架,开展自己的业务(当然,钱和出问题是业务的响应速度是一大问题)。

软件构架模式

所谓的模式是指,在我们周围不断的重复发生的问题和已有的解决方案,如此,就可以使用该方案来解决问题,而非做重复的工作(GoF的设计模式,指的是开发层面的,这里是构架层面)。

常见的软件构架模式:

  1. 分层 这是最常见的构架模式。将系统横向分为几个部分,每部分负责单一的功能,通过上层对下层的调用,形成一个完整的系统。如,TCP/IP协议栈,这就是典型的分层系统。通常系统的划分,分为,应用层–负责展示,服务层–负责服务支持,数据层–负责数据服务。通过系统的分层,可将一个庞大的系统整体上切分为不同的部分,便于不同部门的开发和维护,同时也便于独立演化和发展。系统分层,概念上看很容易理解,然而在实践上,却又很容易违背其基本原则。系统分层挑战:合理划分层次和边界接口,严格遵循分层构架的约束,禁止跨层调用。分层构架对支持高并发发展和分布式发展非常重要,需在最开始的时候考虑。进行部署的时候,可以分别部署到不同的物理机器。

  2. 分割 系统分割属于纵向分割,指业务分割,根据业务和需求将服务分割为不同的独立单元。业务划分为不同的独立单元,一方面方便开发和维护,同时也是方便分布式部署。

  3. 分布式 系统的分层和系统分割都是为了方便分布式部署。分布式有较强的伸缩性,可以利用多台廉价机器提高性能。分布式带来的问题:网络调用导致性能降低,宕机概率增加,分布式事务难保证,开发管理维护困难。常见分布式方案:分布式应用和服务,分布式静态资源,分布式数据和存储,分布式计算等。

  4. 集群 对于集中访问的资源,通过多台服务器构成一个集群,通过负载均衡设备共同对外提供服务,这样更多用户时,增加机器,用户少时,减少机器,具备较强的伸缩性和性能。

  5. 缓存 使用缓存是解决性能问题的第一手段。缓存方式:CDN,反向代理,本地缓存,分布式缓存。缓存使用条件:热点数据访问不均衡,某些数据被频繁的访问,数据在一断时间内有效,不会很快过期。

  6. 异步 本质上是将业务分成多个阶段,每个阶段之间通过共享数据的方式进行协作。单一服务可通过共享队列的方式时间,分布式中多个服务器可使用分布式消息队列实现,分布式队列可视为内存队列的分布式部署。异步消息队列的特性:提高系统的可用性,加快网站响应速度,消除并发访问高峰。

  7. 冗余 为了避免服务宕机导致服务不可用等问题,需要进行冗余部署和数据冗余备份。定期保存,冷备,数据进行主备分离,实时同步实现热备。

  8. 自动化 发布过程自动换,自动化代码管理,自动化测试,自动运维等。

  9. 安全 密码,验证码,通讯,XSS攻击,SQL注入等。

好的模式不是模仿,而是对问题深刻理解之上的创造与创新。由上构架的模式要素,系统分层和分割是基础。

构架要素

构架始终围绕着“高性能,高可用,易扩展,可伸缩,高安全”这几个要素来的。

  1. 高性能 性能指标:响应时间,并发数,吞吐量(TPS–每秒事务, HPS–每秒http请求, QPS每秒查询),性能计数器(内存,CPU,磁盘,网络IO等,使用nmon等工具计算) 测试方法:性能测试,压力测试,稳定性测试 测试报告如:
    测试报告

前端性能优化: 减少http请求(多个JS,css合成一个),使用浏览器缓存(Cache-control,expired等头部属性,启用压缩,CSS在head里面,js在body里面(减少加载时显示空白页面),减少cookie传输。使用CDN加速,使用反向代理缓存(nginx,apache等都可以缓存)

应用服务器的优化: 使用分布式缓存,恰当使用缓存,频繁修改的数据,没热点访问的数据,数据不一致与脏读,缓存可用性超时等, 异步操作, 使用集群

存储性能优化: 固态硬盘,RAID, HDFS

  1. 高可用性 高可用性, 一个显著的特点是应用的无状态性。 高可用服务:分级管理(核心服务使用更好的硬件),超时设置,异步调用,服务降级(关掉不重要服务等, 等幂设计(服务失败后,将请求负载到其他可用服务)。 失效转移:失效确认(通过心跳,失败报告),访问迁移,数据恢复。

  2. 伸缩性 不同功能进行物理分离,单一功能通过群集实现。 应用服务群集:http重定向负载均衡(302重定向),DNS域名解析负载均衡(域名解析配置多个A记录),反向代理负载均衡,IP负载均衡,数据链路层负载均衡(通过修改目的MAC地址实现,LVS,使用广泛)。 负载均衡算法:轮询,加权轮询,随机,最少链接,源地址散列 关系数据库的伸缩性,非关系数据库的伸缩性

  3. 可扩展性 使用消息队列降低耦合性,使用分布是服务打造可复用平台

  4. 安全性 XSS攻击(站点脚本攻击),注入攻击 ,CSRF(跨域脚本攻击)等

最后

所谓的构架师不应该是当一个人,所有的参与的人都是构架师,一群优秀的人做一件他们热爱的事情,一定能成功。事情成就了人。

最后的最后,还是啰嗦下,不要企图去设计一个大型的网站(系统),大型系统不是设计出来的,而是演化发展而来。

完。