从单体架构到微服务架构的演化历程

因用户量、访问量、数据量等不同,系统架构被分为了多个发展阶段,为了解决不同阶段业务所带来的不同的技术问题,就有了以下系统架构演化历程。

从单体到微服务,文字过于苍白,上图对比

1初始阶段

业务发展初期,为了更快速满足客户需求,将所有业务功能模块都放在一个系统中来实现。

优点就是快速响应,优先抢占市场份额。

在单体阶段一般会使用到的网站架构模式是:分层模式

1.1分层模式

定义:将系统在横向维度上切分成几个部分,每部分的职责单一,上层对下层的依赖和调用组成一个完整的系统。

栗子:7层的网络通信协议;计算机硬件、操作系统和应用系统;MVC三层架构等

原因(为什么要分层):分层结构对网站支持高并发和向分布式方向发展至关重要

约束:层次之间禁止  跨层次调用,逆向调用。

建议:在网站规模还很小的时候应该采用分层的架构。

一般单体的分层架构:

 分层如分工,为的就是各施其职,但如何落地到开发层面呢?

通过按业务功能模块进行分包分层开发

 这样做的目的是能更好的应对架构的演化过程,降低升级改造难度、风险、成本等。后续只需要对不同的业务模块进行抽离,即可实现业务拆分。

1.2部署方式

通常服务器操作系统使用linux,前端使用nginx部署、业务端使用tomcat部署、数据存储为MySQL数据库、文件存储(如:FastDFS)。

这时网站架构如图:

 随着业务的发展,越来越多的用户访问导致性能越来越差,越来越多的数据导致存储空间不足,当单台服务器无法满足业务发展所需时,此时就要做业务的垂直拆分了??为时尚早!垂直拆分将在后续讲到。这时应该按层进行分离,前端、应用和数据做分离,也称为横向拆分,这也是为什么一开始要做分层的原因。

2横向拆分阶段

按层进行分离,也成为横向拆分。拆分后需要分别部署到四台服务器,但这四台服务器对硬件资源的要求各不相同,前置和应用服务器需要处理大量的业务逻辑,因此需要更快功能强大的CPU资源;数据库服务器需要快速磁盘检索和数据缓存,因此需要更快的硬盘和更大的内存;文件服务器需要存储大量用户上传的文件,因此需要更大的硬盘。

这时网站架构如图:

 不同特性的服务器独立使用一台服务器,使得网站的并发处理能力和数据存储空间得到了很大的改善,支持网站业务进一步发展。但是随着用户逐渐增多,网站又一次面临挑战:数据库压力太大导致访问延迟,进而影响整个网站的性能,用户体验受到影响。这时需要对网站架构进一步优化。

3缓存改善网站性能阶段

加入本地缓存EhCache和Redis缓存服务器用于提升数据访问速度,降低数据库服务器的访问压力。

3.1缓存模式

定义:将数据存放在距离计算最近的位置以加快处理速度。

目的:提高系统性能

使用前提:

1. 数据访问热点不均衡,频繁访问的数据应该放在缓存
2. 数据在某个时间段内有效,短时间内不会过期的数据应该放在缓存
3. 一定时间内允许数据不一致,最终一致即可
4. 一定程度上允许数据不一致,也即是说部分数据丢失也不影响业务

每一层都有属于自己的缓存,常用的几种缓存:CDN缓存、nginx缓存、进程内缓存(Mybatis缓存,Spring MVC页面缓存,EhCache数据缓存)、进程外缓存(Redis 分布式缓存)、数据库缓存等等。

该阶段引入缓存主要用于提高数据的访问速度,降低数据访问压力。但单一的web服务器和业务服务器能够处理的请求连接有限,在高并发场景成为整个系统的瓶颈。

4应用服务器集群阶段

图文结合更生动,先上图

本阶段和之前的阶段唯一的区别在于:web服务器和应用服务器都采用集群模式,而集群必然就带上了负载均衡

该阶段我们主要是分析集群模式和负载均衡。

4.1集群模式

定义:多台服务器部署相同应用构成一组相互独立的计算机群。

作用:提高并发、提高可用性、提高扩展性

条件:无状态服务

状态化服务:服务器端一般都要保存请求的相关信息,每个请求可以默认地使用以前的请求信息。

无状态服务:服务器端所能够处理的过程必须全部来自于请求所携带的信息,以及其他服务器端自身所保存的、并且可以被所有请求所使用的公共信息。

有状态服务还是无状态服务,其判断依据:来自相同发起者的两个请求在服务器端是否具备上下文关系。

对于无状态服务:天生适合集群。

对于有状态服务:需要实现同一个用户负载到不同服务器的请求结果一致,这里就涉及到session管理问题。

4.1.1session管理

最佳方案:session 服务器

最有效的方案是:有状态服务=无状态服务+有状态的session服务,也即是将保存状态的模块抽离出来独立部署、共同访问。

一般情况可以使用redis 分布式缓存来实现共享session;

如果业务场景对session管理要求比较高,则利用独立的session服务器共享session,同时集成单点登录SSO、用户服务等功能。

  其他实现session管理的方案:

  1. 业务服务器之间做Session复制;

  2. 利用cookie记录session,每次请求都带有最新的session;

  3. session绑定在服务器,通过负载均衡算法确保同一个ip每次访问相同的服务器

4.2负载均衡

负载均衡顾名思义是:负载和均衡…………将用户的请求均衡的发送到不同的服务器来做业务处理。

服务员上菜:负载均衡分类和常见算法

 

  

 负载均衡还有很多使命,比如:

1. 自动剔除故障服务节点;
2. 自身设备高可用(如硬件负载F5,keepalive);
3. 逃生机制(如果所有节点不可用,可以重定向到其他可用站点);
4. 丰富的优化技术手段(如TCP优化,HTTP压缩,SSL/TLS卸载,连接复用,连接数限制,用户优先级等)

负载均衡是门大学问,有时间专门写一个关于负载均衡的系列文章。

5数据库读写分离阶段

网站在使用缓存后,使绝大部分数据读操作访问都落在缓存中,但是仍然有一部分读操作(缓存访问不命中、缓存过期)和全部写操作需要访问数据库,随着网站用户不断增长,业务并发访问增大,数据库负载压力也不断增大,最终成为网站的瓶颈。此时此刻就要对数据库动刀了。

  业务服务器在写数据时,访问主数据库,主数据库(master)通过主从复制机制将数据同步到从数据库(slave),这样当应用服务器读数据的时候,就可以通过从数据库来获取,从而实现数据库的读写分离,提高数据库的并发访问。此时需要引入数据访问模块来实现数据库读写分离对应用透明化。

6加速网站响应阶段

随着网站业务不断发展,用户规模越来越大,不同地区的用户访问网站时速度差别很大,此时需要加速网站响应。加速网站响应,是为了提供更好的用户体验,留住用户。主要解决方案有CDN和反向代理。细心的会发现,上个阶段已经加入了反向代理(负载web服务器集群),因此本阶段主要是加入CDN更进一步提升访问速度。

7全部服务分布式阶段

任何强大的单一服务器都满足不了大型网站持续增长的业务需求。数据库经过读写分离后,依然不能满足需求,这时需要使用分布式数据库。文件系统也是一样,需要使用分布式文件系统。

8提高数据检索阶段

随着网站业务越来越复杂,数据量越来越大,对数据检索需求也越来越复杂,网站需要采用非数据库查询技术来解决数据检索慢的问题。如elastic search搜索引擎。对于检索数据的访问落在高速搜索引擎服务器中,极大的提高数据检索响应速度。

9垂直拆分阶段

虽然经历了很多个阶段,但是业务仍然是单体服务,只是做了横向扩展,并没有对单体服务进行拆分。单体应用随着业务需求的迭代,功能的追加扩展,最终成为一个庞然大物。变得更加复杂,逻辑耦合严重,难以理解,团队开发 人员职责不清,部署困难,回归测试成本巨大,交付效率大大降低。

9.1总结单体应用缺点

  1. 代码难以理解,导致代码质量逐渐降低,复杂性逐渐增加,代码难以被修改和重构,简言之:屎山。

  2. "屎山"懂得都懂,代码量大耦合度高动一发乱全身,构建和部署耗时长,难以定位问题,大部分时间花费在解决代码冲突上,导致开发效率极低,

  3. 可靠性差,一个bug可能会引起整个应用崩溃。

  4. 伸缩性差,单体只能按整体横向扩展,无法分模块垂直扩展,无法分团队独立开发部署;IO密集型模块和CPU密集型模块无法独立升级和扩容。

  5. 高度耦合的单体工程使得逻辑边界模糊不清,新业务需求开发任务无法有效分配到人,团队人员职责不清晰,沟通成本增加。

  6. 技术栈受限于同一框架和语言,阻碍新技术的融入,也阻碍新鲜血液的流入,贫血的系统终将走向死亡。

庞大的东西要干嘛?拆!老城区阻碍城市的发展,拆!代表性文化老城区就不能拆了,所以拆的时候要注意点。

9.2概述

定义:垂直拆分阶段是将系统在纵向维度上以功能和服务的不同进行切分,再包装成高内聚、低耦合的模块单元。

栗子:按业务进行分割:购物、论坛、搜索、广告等。

垂直拆分分为两种情况:

  1. 一是只拆分业务功能,数据库不拆分;

  2. 二是业务功能和数据库同时拆分。

前者相对后者来说更简单,随着业务的增长数据库拆分也是迟早的事,但系统的复杂度也成倍增加。

9.3垂直拆分之业务拆分

小二上菜

按照功能模块进行拆分,每个模块独立集群部署,使用相同的数据库。

优点:快速增长时,以应用系统为中心共用数据库的架构模式,业务系统间无需互相调用,也就不需要引入服务间远程调用。

缺点:耦合度高(共用数据库),数据库会成为以后的瓶颈

在本阶段同时引入了消息队列,部分业务可以采用异步处理、数据挤压在消息队列中再慢慢消费等等。降低数据库的并发访问,在这个阶段也带来了很好的性能提升。

同时引入API网关,对请求做统一管理。API网关的基本功能包含了统一接入、协议适配、流量管理与容错、以及安全防护,这四大基本功能构成了网关的核心功能。网关首要的功能是负责统一接入,然后将请求的协议转换成内部的接口协议,在调用的过程中还要有限流、降级、熔断等容错的方式来保护网关的整体稳定,同时网关还要做到基本的安全防护(防刷控制),以及黑白名单(比如IP白名单)等基本安全措施。

9.4垂直拆分之业务和数据拆分

 在业务拆分的基础上加入数据库拆分。和业务拆分一样,数据库按照业务功能模块做相对应的进行拆分。当A业务想访问B数据库时,需要通过远程调用来访问B业务获取数据,又因为B业务是集群服务,所以需要通过访问LB来负载到B业务群。谈到远程服务调用,业务服务间通常采用RPC(TCP协议)或 Restful API(HTTP协议)来实现远程调用。服务间除了通过远程调用,还可以通过消息队列来完成异步的服务间调用。

目前流行的分布式服务治理技术方案有:Dubbo 和 Spring Cloud,分别是RPC 和 Restful 两种不同的解决方案。

10微服务阶段

垂直拆分业务和数据阶段是微服务的雏形,为微服务阶段奠定了基础。

所谓微服务架构风格是一种将单个应用程序开发为一组小型服务的方法,每个小服务运行在自己的进程中,并以轻量级的机制(通常是HTTP RESTful API)的方式进行通信,这些服务围绕着业务能力所建立的,并且可以由完全自动化的部署机构独立部署,这些服务的集中管理只有最低限度,可以用不同的编程语言编写并使用不同的数据库存储技术。

——詹姆斯.里维斯 & 马丁.弗勒

说白了微服务也是分布式系统,不同业务系统间通过服务接口相互对接形成一个大型分布式系统。比如我要对接第三方支付系统(如微信支付/支付宝支付),我先申请开通支付功能,再拿到他们提供的支付接口对接文档,按照文档来完成对接即可。分布式系统也不是什么高大上的东西,分布式系统是一组计算机系统一起工作,在终端用户看来,就像一台计算机在工作一样。只不过在这个过程中会因为产生很多新的问题,需要学习新的技术或思想来解决对应的问题罢了。不要在现在拥有海量学习资料的互联网中迷失了方向,最终还是基础最重要。

10.1微服务的优点

  1. 易于开发与维护

    微服务相对小,易于理解;启动时间短,开发效率高

  2. 独立部署

    一个微服务的修改不需要协调其它服务

  3. 伸缩性强

    每个服务都可以在横向和纵向上扩展;每个服务都可按硬件资源的需求进行独立扩容

  4. 与组织结构相匹配

    微服务架构可以更好将架构和组织相匹配;每个团队独立负责某些服务,获得更高的生产力,也更容易扩大开发团队

  5. 提高容错性

    一个服务的内存泄露并不会让整个系统瘫痪

  6. 技术异构性

    使用最适合该服务的技术;降低尝试新技术的成本

10.2微服务的缺点

  1. 团队沟通的过载

    微服务架构降低了团队管理的难度,但是却不能降低团队沟通的需求。研发人员需要确保一个服务中的更新不会破坏其它功能。我们在单体应用中也会发现类似问题,但是微服务架构的应用这个问题会更加明显。

  2. 正式文档的过载

    每一个独立的运行部件需要持续维护其规格和接口文档,这些文档是其它团队使用这些部件的必要条件。

  3. 不一致性的应用

    我们可以为每一个组件选择不同的技术栈。这导致了不一致的应用设计和架构,而这会在更长期的运维期间增加系统维护成本。提炼代码脚手架统一的快速开发环境,运维起来更容易,但并不是银弹。

  4. 数据的复杂度

    与单用户系统相比,连接到分布式系统的数据库是相当复杂和难以处理的,并且还有很多其他的数据源

  5. DevOps的复杂度

    我们需要拥有一支成熟的DevOps团队去处理微服务架构的应用的复杂性。由于多个应用存在多个活动部件,这种复杂度需要有高水平的经验。

  6. 增加了资源使用

    运行这些微服务架构的应用的初始投资会比较大,因为所有微服务应都需要拥有他们自己的运行容器,这也需要更多的CPU和内存。另外采用了中间件也会带来一个比较大的资源投入。

  7. 增加了网络通信开销

    分布式系统的产生的网络开销比单机应用多很多,不能简单把内部调用简单改为分布式调用,吃亏很大。微服务架构下,独立运行的组件都需要通过网络进行互相通信。这样系统需要有更加可靠和快速的网络连接。

  8. 网络安全

    通过网络进行通信的系统更容易产生安全缺陷。

  9. 测试难度

    测试微服务架构的应用绝对比单体应用难很多,深有体会,集成测试过程是一场噩梦。

  10. 产品监控

    监控微服务架构应用的成本会更高,很难获得合适的工具,自研的成本也很高。

  11. 其它:另外例如方案设计,研发管理,问题排查确实都有不少挑战。

微服务好处是很多,但缺点也很多,每个阶段都需要我们去解决新架构带来的新问题。微服务的系统复杂度、技术难度、人员成本、服务器成本都非常高。技术服务于业务,能简单就简单,这也是架构演化历程的意义所在。在此附上相对简单的微服务物理架构图:

 在上个阶段的基础上加入了服务注册与发现和任务调度集群。

本阶段为微服务阶段,物理架构图也是相对简单的,完善的微服务架构体系还有着很多技术需要引入,比如:多因子统一认证登录,配置中心,分布式锁,分布式事务,分布式幂等性,服务监控预警,链路追踪,服务自愈,日志分析,提炼代码脚手架,服务自动化部署,无感部署双AZ切换等等,在此附上微服务系统架构图:

11总结

演化到此基本上大多数的技术问题都得以解决。但演化并未结束,随着自身的不断发展,可以开放服务接口对接第三方系统(如微信/支付宝第三方支付)。当微服务发展到非常庞大的微服务群体时进阶到服务网格等等,个人水平有限继续进化会到什么程度就不清楚了,但始终围绕着高内聚低耦合、高可用、高性能、易扩展,易伸缩和安全性去进化架构

目前上云已成热门词语,各种技术方案也非常成熟,许多网站已经不需要再经历大型网站所经历过的架构演化之路。建立在云平台所需要的一切技术资源,都可以按需购买,线性伸缩,不需要自己一点点地拼凑各种资源,综合使用各种技术方案逐步完善自己的网站架构。

不要企图通过技术来解决所有业务问题,而是根据业务具体分析,使用不同的技术架构、不同的业务处理模式来解决业务问题。

但也正因为这样,网站架构技术演化过程也很难重现,以致于出现了很多为了使用技术而使用技术,而不是为了业务,本以为这样搭建起来的网站就很高大上,其实都是徒劳。所以网站架构师更应该对这个过程深刻了解,在技术选型和架构决策时才能有的放矢,直击要害。

主要参考文献:(PDF也为您安排好了)

《大型网站技术架构:核心原理与案例分析》--获取码:135804

《系统架构》--获取码:135802

《微服务设计》--获取码:135806

演化架构图原图路径:https://www.processon.com/view/6138293d63768906a2285e9e

微服务架构图原图路径:https://www.processon.com/view/61399bb0e401fd1fb6b5a651

来源于微信公众号:Java全栈布道师

 

posted @ 2021-09-26 18:32  渊渟岳  阅读(1554)  评论(0编辑  收藏  举报