一、架构
软件架构是系统的一个草图,阐述了各个组件之间的通信,层次划分,一旦系统开始详细设计,架构蓝图就很难甚至无法改变。
- 传统分层架构
- 前后端分离架构
- 微服务架构
分层架构
分层架构是一种设计软件架构的思想。
- 开放API层:可直接封装Service接口暴露成RPC接口;通过Web封装成http接口;网关控制层等。
- 终端显示层:各个端的模板渲染并执行显示的层。当前主要是Velocity 渲染,JS渲染,JSP渲染,移动端展示等。
- Web 层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
- Service 层:相对具体的业务逻辑服务层。
- Manager 层:通用业务处理层,它有如下特征:对第三方平台封装的层,预处理返回结果及转化异常信息,适配上层接口。对 Service 层通用能力的下沉,如缓存方案、中间件通用处理。 与 DAO 层交互,对多个 DAO 的组合复用。
- DAO 层:数据访问层,与底层 MySQL、Oracle、Hbase、OB 等进行数据交互。
- 第三方服务:包括其它部门 RPC 服务接口,基础平台,其它公司的 HTTP 接口,如淘宝开放平台、支付宝付款服务、高德地图服务等。
- 外部数据接口:外部(应用)数据存储服务提供的接口,多见于数据迁移场景中。
通常意义上的三层架构就是将整个业务应用划分为展现层(表示层)(User Interface Layer)、业务逻辑层(Buesiness Logic Layer)、数据访问层(Data Access Layer)。区分层次的目的是为了体现“高内聚,低耦合”的思想。
分层领域模型规约
- DO(Data Object),此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
- DTO(Data Transfer Object),数据传输对象,Service或Manager向外传输的对象。
- BO(Business Object),业务对象,可以由Service层输出的封装业务逻辑的对象。
- VO(View Object),显示层对象,通常是Web向模板渲染引擎层传输的对象。
- Query,数据查询对象,各层接收上层的查询请求。注意超过2个参数的查询封装,禁止使用Map类来传输。
二、微服务架构
Martin Fowler于2014年提出的Micro Service概念,谈论多年的SOA(Service-Oriented Architecture,面向服务的架构)终于有了新的解决方案,不再需要ESB(Enterprise Service Bus,企业服务总线),并随着Docker的普及,一个轻量级SOA架构MSA诞生。
单体应用架构
若干业务模块打包封装到一个war包。单块架构/单体应用架构
单体应用架构:尽管已经进行了模块化,但UI和若干业务都被打包在一个war包中,该war包包含了整个系统所有的业务功能。
缺点在于:
- 复杂性高。模块多、边界模糊、依赖不清晰、代码质量参差不齐。
- 技术债务。随着时间推移、需求变更、人员更迭,导致不坏不修,且代码难以被修改。
- 部署频率低。构建和部署时间增加,全量部署耗时长、风险高。
- 可靠性差。某个应用bug,如死循环、OOM等导致整个应用崩溃。
- 拓展能力受限。有些模块计算密集,有些IO密集,导致在cpu、内存等硬件选择上无法兼顾。
- 阻碍技术创新。
水平扩展(集群)
水平扩展是在单体应用架构基础上使用负载均衡(反向代理),可无限拓展。
缺点在于:
- 造成大量系统资源浪费,如Module A和Module B不需要水平拓展。
- 单块应用无法拆分,导致修改一个Module都需要整个部署。
- 技术选型单一。单块应用都是基于java开发,无法将某个Module通过其他开发语言实现。
垂直扩展(分布式)
所谓垂直拓展,是指将原来的一个应用拆成互不相干的几个应用,以提升效率。
也可进一步,抽取公共的功能作为服务层。
缺点在于,系统间耦合变高,调用关系错综复杂。
SOA架构(Service Oriented Architecture)
面向服务的架构较为复杂,有较重的ESB企业服务总线。
微服务架构
1、与SOA的区别
- 微服务在SOA上发展而来,是SOA的落地方案,且更轻量级。
- 内部通信协议RESTful接口(或RPC),替代ESB的SOAP。
- 通过服务实现组件化,可拆分,开发者不再需要协调其它服务部署对本服务的影响。
- 按业务能力来划分服务和开发团队,开发者可以自由选择开发技术,提供API服务。
- 基于Docker容器,取代虚拟机。基础设施自动化,可单独、自动部署,用于持续集成,持续部署。
2、微服务架构设计要求/设计原则:
- AKF拆分、服务无状态、通信无状态、前后端分离
- 根据业务模块划分服务种类(微小颗粒度、职责单一性)。
- 服务自治原则,每个服务可独立部署且相互隔离,运行在自己的进程里(运行隔离性)
- 轻量级通信机制,REST、RPC、AMQP、STOMP、MQTT等通信机制进行服务调用
- 可使用不同的语言和存储技术
- 服务需保证良好的高可用性(自动化部署)
- 支付编排,可弹性伸缩
3、几个挑战:
- 运维要求高(交付流程、开发规范)
- 分布式复杂性
- 部署依赖较强、接口调整成本高
- 通信成本较高
微服务技术选型
- SpringBoot作为微服务开发框架,嵌入式容器,可直接jar包发布。
- 使用Spring Cloud,集成Netflix的微服务技术栈。
- 发布微服务时连接ZooKeeper来实现服务注册。
- 通过Node.js将浏览器请求转发到Tomcat并调用服务,通过单线程模型和非阻塞异步式I/O来支撑高并发。
- 使用Jenkins搭建自动化部署服务。
- 通过Docker将服务容器化封装。
冰山模型
微服务是去中心化的,为啥还有八大中心?是不含业务意义的中心,通用的技术中心。
其他微服务方案:
- Dubbo的RPC
- JBoss的WildFly Swarm
- REST框架的Dropwizad
- JavaEE官方的KumuluzEE
架构师与技术专家
技术专家是深度优先,而架构师是广度优先。
架构师的职责:制定规范+指导落地。
架构师不光要解决架构上的问题,更重要的是围绕业务进行设计。
微服务架构师的职责:
- 分析业务需求并切分微服务边界
- 定义架构规范与文档标准
- 确保架构顺利落地
- 改善架构并提高开发效率
挑战:
- 架构需要适应不断变化的业务需求
- 架构具备稳定性、拓展性、安全性和容错性
- 使技术团队深刻理解微服务思想
- 展现微服务架构的价值
- 不要单纯为了追求技术,业务是否合适?人员能力是否具备?
三、全栈
- 系统的性能瓶颈定位
- 团队间的沟通障碍
- 业务的救火灭火
- 团队的资源紧张
- 有工匠精神
- 三个切面,技能、性能、效率
技能
- 操作系统,Linux选型、内核、文件系统、Shell
- 数据存储,关系型数据库、NoSQL、文件对象、文件系统
- 网络,七层协议模型、网络编程、网络类型、HTTP、TCP/IP、DNS
- 框架与库,Spring、客户端、前端框架、Tornado等
- 安全,数据安全、传输安全、代码安全、网络安全
- 微服务,服务、发现、通信、治理
- 云服务,基础云服务Iaas,平台级服务Paas,Saas
- 大数据,专业知识、数学算法、计算环境、Spark
性能
- 业务与代码,业务逻辑、代码规范、意图导向、单元测试
- 运行时调优,依赖与加载,JVM、Linux参数
- 数据访问,连接池、高可用、日志分析
- 缓存,页面缓存、应用缓存、Web代理、边缘缓存、数据库缓存、平台级缓存框架、应用级缓存
- 均衡,DNS负载、网络连接(4层)、HTTP负载(7层)、SSL、数据库负载
- 消息队列,ZeroMQ、ActiveMQ、RabbitMQ、Kafka
效率
- 环境,硬件平台、IDE、虚拟机、沟通工具、知识管理
- 语言,Java、Objc、Python、Javascript
- 敏捷,协同工具、持续集成/发布、Scrum流程、质量工具
- DevOps,产品管理、配置管理、环境管理、集成部署、质量反馈、自动化流程、协作流程、组织变革(云服务、容器、微服务)
四、方法论
可扩展架构
AKF扩展立方体(Scalability Cube),是《架构即未来》一书中提出的可扩展模型,这个立方体有三个轴线,每个轴线描述扩展性的一个维度。
- X轴,代表无差别的克隆服务和数据,工作可以很均匀的分散在不同的服务实例上;
- Y轴,关注应用中职责和功能的划分
- Z轴,按照服务和数据的优先级划分
轴线 | 特点 | 场景 | 应用分割 | 数据库分割 |
---|---|---|---|---|
X轴 | 简单,但单体应用过大时变慢 | 发展初期 | 克隆单体应用,负载均衡 | 克隆单库,读写分离,主从 |
Y轴 | 解决指令集和数据集的约束,成本高 | 业务复杂时期 | 基于功能或服务分割,如微服务 | 根据不同的信息类型,分库 |
Z轴 | 解决数据集的约束,有最大的扩展性,成本最高 | 用户指数级增长 | 根据产品SKU/用户hash到不同服务 | hash分片入库 |
分布式架构
在常见的分布式系统中,总会发生诸如机器宕机或网络异常等情况。基于此,产生了适应各种场景的一致性算法,解决如何在一个可能发生上述异常的分布式系统中,快速且正确地在集群内部对某个数据的值达成一致, 并且保证不论发生以上任何异常,都不会破坏整个系统的一致性。
拜占庭将军问题
它是由莱斯利·兰伯特提出的点对点通信中的基本问题,拜占庭位于如今的土耳其的伊斯坦布尔,是东罗马帝国的首都。由于当时拜占庭罗马帝国国土辽阔,为了达到防御目的,每个军队都分隔很远,将军与将军之间只能靠信差传消息。在战争的时候,拜占庭军队内所有将军和副官必须达成一致的共识,决定是否有赢的机会才去攻打敌人的阵营。但是,在军队内有可能存有叛徒和敌军的间谍,这个就是拜占庭容错问题。
- 如果叛将人数为 m,将军数 n >= 3m + 1,那么就可以解决拜占庭将军问题。
- 前提条件:叛将数 m 已知,需要进行 m + 1 轮的作战协商。
ACID 理论
CAP理论
2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提出CAP猜想。 2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP。
CAP理论:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和 分区容错性(Partition tolerance)这三项中的两项。
- 一致性,all nodes see the same data at the same time
- 可用性,Reads and writes always succeed
- 分区容错性,the system continues to operate despite arbitrary message loss or failure of part of the system
CAP权衡:
- CA,放弃分区容错性,加强一致性和可用性。
- AP,常用互联网场景,舍弃C,退而求其次保证最终一致性。
- CP,一般不使用,但是涉及到钱的行业,宁可停止服务,也需要保证一致性。
BASE理论
eBay的架构师Dan Pritchett源于对大规模分布式系统的实践总结,在ACM上发表文章提出BASE理论,BASE理论是对CAP理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)
- 基本可用(Basically Available),分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。如服务降级。
- 软状态( Soft State),是指允许系统存在中间状态。如允许mysql replication的异步复制。
- 最终一致性( Eventual Consistency),是弱一致性的一种特殊情况,区别于ACID的强一致性模型。
一致性协议
- 2PC(two phase commit),二阶段提交,即PreCommit和Commit。是一个强一致、中心化(1个coordinator和n个partcipant)的原子提交协议。
- 3PC(three phase commit),三阶段提交,即CanCommit、PreCommit和Commit。
八大分布式协议和算法
- Paxos算法,是Leslie Lamport提出解决分布式共识性的算法,即一个分布式系统中的各个进程如何就某个值通过共识达成一致。
- Raft算法,由Stanford提出的一种更易理解的一致性算法。
- ZAB协议,ZooKeeper实现的一种主从模式的系统架构来保持集群中各个副本之间的数据一致性的算法。
- 一致性Hash算法
- Gossip协议算法
- Quorum NWR算法
- FBFT算法
- POW算法