互联网之总体架构设计篇

·  阅读 4461

著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

什么是架构

架构一直以来都被认为是高阶技术人员的代名词,但什么是架构,什么样的架构人员才称得上一个好的架构师,这是很难评判的。但是,要提高架构能力, 只寄希望于代码层级是远远不够的, 代码只能帮助我们解决执行力的问题,但架构的高度更多的是依赖战略(业务洞察力)以及战术问题(技术视野)来解决问题。

但架构的高度到底是在一个什么层面上呢?架构的高度(既架构战略和架构技术,也就是架构格局)。

在设计一个架构的时候,通常都需要完整的解决方案去解决实际问题,这些问题包括根据具体业务场景选择合适的系统架构形态;针对所选择的架构形态应该如何去设计实现;在这之中如果有困难如何去折中处理;系统的架构如果在线上运行中出现问题该如何解决...等等一系列问题都是在架构设计之初都需要考虑到的问题。这就很需要架构师的架构格局来做支撑。其实在架构的背后,更多的是思考,思考为什么这么设计,为什么其它方案不优雅不合适等等一系列的为什么。

所以如果要做好一个架构,需要有绝对的理论支撑,实际的项目架构落地实践。拒绝忽悠,拒绝空理论、空概念。

总结:

架构完整解决方案

  • 具体业务场景
  • 架构如何选型
  • 架构如何设计
  • 架构如何折中
  • 架构线上问题如何解决

架构背后哲学思考

  • 为什么要这样设计
  • 其它方案为什么不优雅

架构的实践

  • 拒绝空理论、空概念
  • 实际项目架构落地经验
  • 拒绝忽悠

互联网发展三阶段

在互联网的发展之路上,正在经历这3个阶段,过去的PC互联网,现在的移动互联网,未来的物联网。

在PC互联网时代,我们暂且称之为互动1.0时代。在这个阶段,以内容在线为主要核心,但资源之间的互动方式没有发生太多的变化,还是一个中心对多点的广播模式,比如过去的三大门户网站(百度,搜狐,网易)。

在PC互联网后期,移动互联网时代早期,也就是互动2.0时代。这个阶段以互动为核心,比较有代表性的产品有微博,Twitter。这些产品有了“关注”,因为“关注”产生了互动,产生了网络效应,说的人越多,看的人也越多,反之亦然。这让网络因为“关注”这个机制有了自成长的一个可能性,一个契机。

在移动互联网后期,暂称互动3.0时代,因为“关注”把一对一的关系变成了更广泛的多对多关系,形成了真正的交互网络形态,人和信息都在线了。网越织越密,才有了用更高效的方式实现原来很难实现的功能,网络文明再一次进步。

未来物联网将带来更广阔的天空,更不可思议的生活方式。

在这过程中,互联网发展的特点也越来越明显,比如:

  • 业务功能越来越多、越来越复杂
  • 万物互联数据量越来越大
  • 请求量越来越大,更高的用户体验要求
  • 业务快速迭代,持续交付的能力等

互联网架构演进之路

更具体的说明参考单体架构,SOA架构,微服务架构,分布式架构,集群架构

单体架构设计与实践

单一架构一般都是一个普通的java war文件,其内部的java代码目录层次结构单一。一个单体架构系统的架构图大致如图所示:

单体架构的优点

  • 开发简单
  • 测试简单
  • 部署简单
  • 规模结构简单

如果单体架构承载不了更高的压力怎么办?单体架构的扩张就是使用nginx做反向代理,基于不同负载均衡策略把请求压力发送到其它单体应用上。单体架构的应用是一个war包部署在Tomcat上,扩展只需要再搞一台机器使用Tomcat部署war包就可以了,如图所示:

单体架构适用场景

  • 业务场景简单、功能不复杂、研发人员较少的项目
  • 创业公司初期
  • 性能要求极其严苛

说完了单体架构的一些优点,其实单体架构也存在一些缺点:

  • 系统耦合度高
  • 技术选型单一
  • 开发效率越来越低下

随着系统的使用越来越久,公司发展成长越来越迅速。系统的数据量及访问量也越来越大,针对这种状况如果应对解决呢?

  • 针对数据库,可以有垂直拆分(分库)和水平拆分(分表)解决方案
  • 针对系统也有垂直拆分(业务维度)和水平拆分(功能维度)的概念

水平分层架构设计与实践

水平分层架构是把系统向水平方向物理分成多个进程来运行,每层都有自己的逻辑,实现逻辑解耦。比如:网关层、业务逻辑层、数据访问层、数据存储层。下图是一个水平分层的系统架构图:

水平分层架构拆分的设计原则

  • 单独的页面展示服务
  • 单独的网关服务
  • 单独的业务逻辑服务
  • 单独的数据服务
  • 根据系统职能单独划分服务(类似公司职能部门划分一个道理)

在根据水平分层架构设计的时候,也会遇到一些技术选项的问题,下图展示一个网关层技术选项对比维度图,其它的技术选项对比维度图也类似如此:

业务逻辑层应该具备的基本功能

  • 业务逻辑判断
  • 根据不同逻辑判断实现不同功能

数据访问层应该具备的基本功能

  • CRUD 业务增删改查接口
  • ORM 框架
  • Sharding 支持分库分表
  • 屏蔽底层存储库的差异性(redis/mysql/mongodb)
  • 针对以上功能的聚合可以使用NewSql替代

水平分层架构虽然解决了一些问题,但其终究还是同步架构的一种,为了让水平架构的处理能力更上一个台阶,可以将其改造成一个异步架构的水平分层架构,如下图所示:

通过引入MQ消息中间件实现分层的异步处理,提升系统吞吐量。

水平分层架构的设计事项

设计过多

  • 请求路径变长
  • 平均响应延迟变高
  • 定位问题变的复杂化
  • 运维成本增加

设计过少

  • 和单体架构基本类似

设计合理适中

  • 同步架构(四层)
    • 网关层
    • 业务逻辑层
    • 数据访问层
    • 数据存储层
  • 异步架构(五层)
    • 网关层
    • 异步消息队列层
    • 业务逻辑层
    • 数据访问层
    • 数据存储层

即便使用了水平分层架构,也还是存在缺点的,这样的分层方式还是粒度过粗,我们看看最后水平分层架构的全貌图

App客户端先访问DNS域名解析服务器获得服务器IP;然后通过静态资源服务器获取CSS、JS等静态资源;最后调用服务器动态接口获取数据展示。

面向服务架构设计与实践

参考 SOA(Service-Oriented Architecture)面向服务的分布式架构详解

微服务架构设计与实践

参考 微服务架构设计

微服务架构有利也有弊,不好的设计会出现一些问题。因为微服务中业务关注服务局“通信”,业务迭代需要多方业务支持,导致业务迭代速度慢;基础设施组件升级困难,影响交付能力和交付速度;多语言通信之间的问题,业务服务每种语言一套基础设施、成本大。

下图是关于上述问题的图示:

服务网格架构设计与实践

参考 服务网格 Pattern: Service Mesh

应用程序A部署在一台机器上,同样的sidecarA也同样部署在这样机器上,sidecarA是基础设施组件,其实现了服务发现,配置管理,熔断限流,各种服务治理的功能,这使得应用程序不用再关注服务治理的相关编码实现,只需要注重业务编码的实现,关注点拆分(而在微服务架构中是需要同时兼顾考虑的)。打个比方需要修重试策略,修改注册中心,修改服务调用路由规则,这些在微服务架构中需要修改应用编码重新部署才能生效,而在服务网格架构中只需要修改技术设施组件,在不影响业务功能代码的情况下进行修改发布升级。

下图是一个服务网格架构图:

  • 请求:应用程序A将req发送到SidecarA,SidecarA将req发送到SidecarB,SidecarB将req发送到应用程序B
  • 响应:应用程序B将resp发送到SidecarB,SidecarB将resp发送到SidecarA,SidecarA将resp发送到应用程序A

官方服务网格架构图
Service Mesh的优点

  • Service Mesh独立进程、独立升级
  • 业务团队专注于业务逻辑本身
  • 一套基础设施支持多语言开发
  • 业务团队和基础设施团队物理解耦

Service Mesh的技术框架

框架 开发语言 开发公司
Linkerd Scala Buoyant
Conduit Rust Buoyant
Envoy C++ Lyft
Nginmesh Go Nginx
Istio Go/C++ Goole,IBM,Lyft

由于Istio是集大成这于一身,所以这里介绍一下Istio,更多详细的内容可以参考 Istio官方文档

Istio

总体架构

  • Istio服务网格逻辑上分为数据面板(执行者)和控制面板(指挥者)
  • 数据面板由一组智能代理(Envoy)组成,代理部署sidecar,调解和控制微服务之间所有的网络通信
  • 控制面板负责管理和配置代理来路由流量,以及在运行时执行策略

数据面板Envoy

  • 动态服务发现,负载均衡,TLS连接终止,HTTP/2 & gRPC代理
  • 熔断器,健康检查
  • 基于百分比流量灰度,故障注入和丰富指标
  • Envoy被部署为sidecar,和对应服务在同一个kubernetes pod 中

Mixer

  • 负责在服务网格上执行访问控制和使用策略,并从Envoy代理和其它服务收集metric信息
  • Central component

Pilot

  • pilot特为sidecars提供服务发现
  • 智能路由的流量管理功能(例如...A/B测试、canary部署等)
  • 弹性(超时、重试、断路器等)
  • 松耦合允许Istio在多个环境中运行(例如...Kubernetes(Consul/Nomad))同时维护相同的操作员界面进行通信管理

Citadel

  • 提供强大的服务间认证和终端用户认证,使用内置身份和证书管理
  • 它可以用于升级服务网格中的未加密流量,并未操作人员提供了基于服务标识而不是网络控制执行策略的能力
  • 从0.5版本开始,Istio支持基于角色的访问控制来控制谁可以访问你的服务

流量控制

  • 请求路由
    • Request Routing
    • 版本控制V1/V2
  • 服务发现与负载均衡
    • 三种负载均衡模式:轮询、随机和带权重的最少请求
    • 当为定实例的健康检查失败次数超过预定阀值时,它将从负载均衡池中弹出。当通过的健康检查数超过预定阀值时,该实例将被添加回负载均衡池

流量控制/处理故障

  • Envoy提供了一套开箱即用,选择加入的故障恢复功能,可以在应用程序中受益。功能包括:
    • 超时
    • 带超时预算有限重试以及重试之间的可变抖动
    • 并发连接数和上游服务请求数限制
    • 对负载均衡池的每个成员进行主动(定期)运行健康检查
    • 细粒度熔断器(被动健康检查),适用于负载均衡池中的每个实例

流量控制/错误注入

  • 错误配合的故障恢复策略(例如:跨服务调用的不兼容/限制性超时)可能导致应用程序中关键服务持续不可用,从而导致用户体验不佳
  • 可以注入两种类型的故障:延迟和中止
    • 延迟是计时故障,模拟增加的网络延迟或过载的上游服务
    • 中止是模拟上游服务的崩溃故障。中止通常以HTTP错误代或TCP连接失败的形式表现

千亿真实案例设计与实践

这个章节从真实案例入手讲解架构的演进之路,给予同学们更多的思考。

水平分层架构的案例一

“百度空间”维护的推送系统用于展现好友动态,且服务于百度众多的产品线(比如百度空间、知道、经验、旅游、ting、IM等等),80、90后应该对下面这张图比较熟悉,这就是那个时候的百度空间。

我们假设它的系统性能吞吐量为100000 QPS, 平均响应延迟:100ms

如果要设计这样的系统,它的设计难点会是什么?

  • 消息内容是使用Push还是Pull方式
  • 架构模式选择同步还是异步方式呢

下面简单的看一张总体架构图:

该架构选取了Pull方式减轻系统压力与异步方式提升系统处理能力。在这个场景下,消息内容并不需要所有关注者都及时看到最新消息,可以在用户上线后再去拉去被关注者新发布的内容,以此来减轻瞬时大数据量发送的问题,微博就类似如此。

如果很多人都在同时发布内容,服务器处理需要时间,但为了让用户避免过长等待,可以先把内容保存至消息队列中,之后将内容缓存在用户客户端上告知处理成功。在这中间下游业务服务器会从消息队列中取出内容继续处理,如果处理失败可以通知客户端失败,成功则不作通知用户的操作。以此来提升用户体验与系统处理能力。

水平分层架构的案例二

换个例子,比如58同城中的IM聊天功能,用于满足用户与商户沟通,获取信息,系统如图所示:

我们假设该系统包含模块30+个,使用了多种开发语言,比如Java/Go。日请求在10亿(IM)30亿(非IM),同时在线用户数突破100w+

如果要设计这样的系统,它的设计难点会是什么?

  • 如何解决百万千万同时在线问题
  • 架构模式上选用同步还是异步

下面简单的看一张总体架构图:

因为IM设计为异步过于复杂,考虑IM聊天实时性,采用同步水平分层架构;那如何保持百万/千万连接数,后面的内容会继续介绍。

微服务架构的案例三

这是一个买卖双方交易平台 在网站早期时候,系统设计方面只有:

  • 网关一个
  • 业务逻辑层一个(业务代码聚合在一个工程)
  • 数据访问层多个
  • DB/cache多个

下面简单的看一张总体架构图:

对于上图的架构,还是存在着一些问题,比如:

  • 业余逻辑层的粒度粗,所有业务逻辑耦合在一个物理进程内部
  • 后期开发迭代效率低下

那么对于这些问题可以如何解决呢?可以考虑使用垂直拆分(业务维度)来进行进一步的系统结构优化。看案例四

微服务架构的案例四

结合上述微服务架构的案例三,把业务逻辑层按照垂直拆分的概念拆分出来了多个独立维度的业务逻辑层服务,各自使用不同的物理进程,如图所示:

但对于该架构还是存在某些问题,比如:

  • 公共逻辑层之间关系耦合,每个业务都会有其它服务类似的代码

那么对于这些问题可以如何解决呢?可以采用组件化依赖jar包方式,对业务逻辑层再深度优化,抽取公共部分下沉为独立服务,提供兼容接口,使用水平拆分(功能维度)策略。

微服务架构 & Service Mesh 的案例五

最后可以看到拆分出来的公共逻辑层也形成了一个服务进程,下沉在业务逻辑层和数据访问层之间,这样既可以减少业务逻辑层同级之间互相调用循环依赖的问题,也可以更好的抽离冗余代码。最后再结合Service Mesh的架构设计理念,就将成为一个更强大更高效的软件系统架构。

下图是一张简单的总体架构图:

扩展知识

  1. HTTP/HTTPS
  2. TCP
  3. Protobuf学习
  4. 系统的高可靠性计算

作业思考

针对本文内容,思考自己公司所在的业务线如果优雅实施微服务架构,要求如下:

  1. 选取一个具体业务场景,给出微服务的具体拆分方案;
  2. 在拆分的基础上给出合理的系统架构设计;
  3. 给出每个微服务的功能流程图,并给出具体的接口详细设计;
  4. 给出每个微服务选用的框架;
  5. 给出每个微服务至少达到4个9的高可用方案;
  6. 给出微服务的服务治理方案和快速部署方案;

分类:
阅读
标签:
收藏成功!
已添加到「」, 点击更改