分布式架构的演进过程

架构的概念
一个软件系统随着功能越来越多,调用量急剧增长,整个系统逐渐碎片化,越来越无序,最终无法维护和扩展,所以系统在一段时间的野蛮生长后,也需要及时干预,避免越来越无序。架构的本质就是对系统进行有序化重构,使系统不断进化

架构是如何实现无序到有序的呢?
基本的手段就是分和合,先把系统打散,然后重新组合。

  • 分的过程是把系统拆分为各个子系统 / 模块 / 组件,拆的时候,首先要解决每个组件的定位问题,然后才能划分彼此的边界,实现合理的拆分。
  • 合就是根据最终要求,把各个分离的组件有机整合在一起,相对来说,第一步的拆分更难。拆分的结果使开发人员能够做到业务聚焦、技能聚焦,实现开发敏捷,合的结果是系统变得柔性,可以因需而变,实现业务敏捷

架构一般可分业务架构、应用架构、技术架构

  1. 业务架构从概念层面帮助开发人员更好的理解系统,比如业务流程、业务模块、输入输出、
    业务域
  2. 应用架构从逻辑层面帮助开发落地系统,如数据交互关系、应用形式、交互方式,是的整个系统逻辑上更容易理解,步入大家熟知的 SOA 就属于应用架构的范畴
  3. 技术架构主要解决技术平台选型、如操作系统、中间件、设备、多机房、水平扩展、高可用等问题

从计算机本身的角度来考虑的话,一个请求的访问到处理最终到返回,性能瓶颈只会是:CPU、文件 IO、网络 IO、内存、等因素

简单说一下各个资源的消耗原因
CPU/IO/内存:

  1. CPU 主要是上下文的切换,因为每个 CPU 核心在同一时刻只能执行一个线程,在CPU 切换执行其他线程的过程中,需要存储当前线程的执行状态并恢复要执行的线程状态,这个过程就是上下文切换。比如 IO、锁等待等场景下也会触发上下文切换,当上下文切换过多时会造成内核占用比较多的 CPU
  2. 文件 IO,比如频繁的日志写入,磁盘本身的处理速度较慢、都会造成 IO 性能问题
  3. 网络 IO,带宽不够
  4. 内存,包括内存溢出、内存泄漏、内存不足
    实际上不管是应用层的调优也好,还是硬件的升级也好。其实无非就是这几个因素的调整。

假如说这个时候应用服务器的压力变大了,根据对应用的检测结果,可以针对性的对性能压
力大的地方进行优化。我们这里考虑通过水平扩容来进行优化,把单机变为集群
在这里插入图片描述

分布式环境下的session共享问题
应用服务器从一台变为两台,这两个应用服务器之间没有直接的交互,他们都依赖数据库对外提供服务,那么这个时候会抛出两个问题

  1. 最终用户对应两个应用服务器访问的选择
    对于这个问题,可以采用 DNS 解决,也可以通过负载均衡设备来解决
  2. session 的问题?
    我们打开一个网页,基本上需要浏览器和 web 服务器进行多次交互,我们都知道 Http 协议
    本身是无状态的,实际上,我们很多的场景都需要带有状态的特性,因此我们引入了 session+cookie机制来记住每次请求的会话
    在会话开始时,给当前会话分配一个唯一的会话标识(sessionid),然后通过 cookie 把这个标识告诉浏览器,以后在每次请求的时候,浏览器都会带上这个会话标识来告诉 web 服务器请求属于哪个会话。在 web 服务器上,各个会话有独立的存储,保存不同会话的信息。如果遇到禁用 cookie 的情况,一般的做法就是把这个会话标识放到 URL 的参数中
分布式环境下的 session 共享

解决 session共享其实也有很多非常成熟的方案
(1)服务器实现的 session 复制或 session 共享
我们在 Web 服务器之间增加了会话数据的同步,通过同步就保证了不同 Web 服务器之间Session 数据的一致。一般应用容器都支持 Session Replication 方式,如下所示:
在这里插入图片描述
存在的问题:

  1. 同步 Session 数据造成了网络带宽的开销。只要 Session 数据有变化,就需要将数据同步
    到所有其他机器上,机器越多,同步带来的网络带宽开销就越大
  2. 每台 Web 服务器都要保存所有 Session 数据,如果整个集群的 Session 数据很多(很多人同时访问网站)的话,每台机器用于保存 Session 数据的内容占用会很严重。这个方案不适合集群机器数多的场景

(2)利用成熟的技术做 session 复制
12306 使用的 gemfire,或者常见的内存数据库如 Redis,其实就是将Session 数据不保存到本机而且存放到一个集中存储的地方,修改 Session 也是发生在集中存储的地方。Web 服务器使用 Session 从集中存储的地方读取。这样保证了不同 Web 服务器读取到的 Session 数据都是一样的。存储 Session 的具体方式可以是数据库
在这里插入图片描述
存在的问题:

  1. 读写 Session 数据引入了网络操作,这相对于本机的数据读取来说,问题就在于存在时延
    和不稳定性,不过我们的通讯基本都是发生在内网,问题不大。
  2. 如果集中存储 Session 的机器或者集群有问题,就会影响到我们的应用。相对于 Session Replication,当 Web 服务器数量比较大、Session 数比较多的时候,这个集中存储方案的优势是非常明显的

(3)将 session 维护在客户端
很容易想到就是利用 cookie,但是客户端存在风险,数据不安全,而且可以存放的数据量比较小,所以将 session 维护在客户端还要对 session 中的信息加密。

相对前面的集中存储方案,不会依赖外部的存储系统,也就不存在从外部系统获取、写入 Session数据的网络时延、不稳定性了

存在的问题:
安全性。Session 数据本来都是服务端数据,而这个方案是让这些服务端数据到了外部网络及
客户端,因此存在安全性上的问题。我们可以对写入的 Cookie 的 Session 数据做加密,不过
对于安全来说,物理上不能接触才是安全的

数据库压力变大,读写分离吧

随着业务的继续增长,数据量和访问量持续增加。对于大型网站来说,有不少业务是读多写少,这个情况也会直接反馈到数据库上。那么对于这种情况来说,我们可以考虑采用读写分离的方式来优化数据库的压力
在这里插入图片描述

这个结构的变化会带来两个问题
1. 数据如何同步
数据库系统一般都提供了数据复制的功能,我们可以直接使用数据库系统自身的机制。不同的数据库系统有不同的支持,比如 Mysql 支持 Master+slave 的结构提供数据复制机制

2. 应用对数据源如何路由
对于应用来说,增加一个读库对结构变化产生了一定的影响,也就是我们的应用需要根据不同的情况来选择不同的数据库源

读写分离后,数据库又遇到瓶颈
随着业务的发展,我们的主库也会遇到瓶颈。我们的网站各个模块:交易、商品、用户数据都还是存储在一个数据库。尽管增加了缓存、读写分离的方式,但是数据库的压力仍然在持续增加,因此我们可以对数据垂直拆分和水平拆分来解决数据库压力问题

专库专用,数据垂直拆分
垂直拆分是把数据库中不同的业务数据拆分到不同的数据库中,例如:把用户、交易、商品的数据分开
在这里插入图片描述

需要考虑到如何处理原来单机跨业务的事务

  1. 使用分布式事务解决
  2. 去掉事务或者不追求强事务的支持
    对数据进行垂直拆分后,解决了把所有业务数据放在一个数据库中的压力问题,并且也可以根据不同业务的特点进行更多的优化

分布式事务的解决方案:

  • 基于可靠消息的最终一致性方案概述
  • TCC事务补偿型方案
  • 最大努力通知型

垂直拆分后,遇到瓶颈,数据水平拆分
与垂直拆分对应的还有数据水平拆分,数据水平拆分就是把同一个表的数据拆分到多个数据库表中,产生数据水平拆分的原因是某个业务的数据表的数据量或者更新量达到了单个数据库的瓶颈,这个时候就可以把表拆到两个或者多个数据库中

水平拆分带来的影响

  1. sql 路由问题,需要根据一个条件来决定当前请求发到那个数据库中
  2. 主键的处理,不能采用自增 id,需要全局 id
  3. 由于同一个业务的数据被拆分到不同的数据库,因此涉及到一些查询需要跨两个数据库获取,如果数据量太大并且需要分页,就比较难处理了
数据库问题解决后,应用面对的挑战

前面讲的读写分离、分布式存储、数据垂直拆分和水平拆分都是解决数据方面的问题,接下来我们要看看应用方面的变化。随着业务的发展,应用的功能会越来越多,应用也会越来越大,我们需要思考如何不让应用持续变大,这就需要把应用拆开,从一个应用变为两个甚至是多个

服务化的道路
我们把应用分为三层,处于最上端的是 web 系统,用于完成不同的业务功能(controller),处于中间的是一些服务中心(server),不同的服务中心提供不同的业务服务;处于最下层的则是业务的数据库
与之前相比有几个重要的变化:
(1)首先业务功能之间的访问不仅仅是单机内部的方法调用,还引入了远程的服务调用。
(2)其次,共享代码不再是散落在不同的应用中,这些实现被放在各个服务中心。
(3)最后,数据库的连接也发生了一些变化,我们把数据库的交互工作放到了服务中心,让前端的 web 应用更加注重与浏览器的交互工作,而不必过多关注业务逻辑的事情。链接数据库的任务交给响应的业务服务中心了,这样可以降低数据库的连接数。

服务化的方式会带来很多好处:
(1)服务中心不仅把一些可以共用的代码集中管理,而且还使得这些代码变得更好维护
(2)从结构上来看,系统架构更加清晰了,比原本的架构更加立体。
(3)从稳定性上来看,一些散落在多个应用系统中的代码变成了服务并且由专门的团队进行统一维护,一方面可以提高代码的质量,另一方面由于基础核心模块相对稳定,修改和发布的频次相对于业务系统来说会少很多,这也会提高整个架构的稳定性。
(4)更加底层的资源由服务层统一管理,结构更加清晰,对于团队开发效率来说有比较大的提高

什么是分布式架构

分布式架构的定义
简单来说,分布式系统是指位于网络计算机上的组件仅通过传递消息来通信和协调目标系统。这里面有两个重要因素:

  1. 组件是分布在网络计算机上
  2. 组件之间仅仅通过消息传递来通信并协调行动
    分布式系统其实也可以认为是一种去中心化的实现思路,对于用户来说是无感知的

为什么要用分布式系统呢?

  1. 升级单机处理能力的性价比越来越低
  2. 单机处理能力存在瓶颈
  3. 对于稳定性和可用性的要求

分布式架构下的高可用设计
1.避免单点故障
a)负载均衡技术(faliover/选址/硬件负载)
软件负载/去中心化的软件负载(gossip(redis-cluster))
b)热备(linux HA)
c)多机房(同城灾备、异地灾备)(运维)

2.应用的高可用性
a)故障监控(系统监控(cpu、内存)/链路监控/日志监控)(自动预警)
b)应用的容错设计、服务降级、限流(自我保护能力)
c)数据量(数据分片,读写分离)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值