微服务知识——微服务架构的演进过程

server/2025/2/5 19:28:41/

文章目录

    • 初始架构:单机架构
    • 第一次演进:Tomcat与数据库分开部署
    • 第二次演进:引入本地缓存和分布式缓存
    • 第三次演进:引入反向代理实现负载均衡
    • 第四次演进:数据库读写分离
    • 第五次演进:数据库按业务分库
    • 第六次演进:把大表拆分为小表
    • 第七次演进:使用LVS或F5来使多个Nginx负载均衡
    • 第八次演进:通过DNS轮询实现机房间的负载均衡
    • 第九次演进:引入NoSQL数据库和搜索引擎等技术
    • 第十次演进:大应用拆分为小应用
    • 第十一次演进:复用的功能抽离成微服务

好的架构不是设计出来的,而是演进出来的。
系统立项之初,就想着设计一个大而全的架构,期待着它能够解决各个阶段的各种问题,这是不可能的。因为在初期很难预估后期业务的变化,如果在初期就落地一个大而全的项目,那么人力成本和时间成本都会很高。同时,架构并不是千篇一律的,千万不能在不同的业务和系统中生搬硬套同一个架构。先快速落地,并关注业务的变化和系统的健壮程度,在不同阶段对当前架构所面临的问题进行复盘和处理,选择一个更适合自身的方向进行优化和改进,这才是常规的做法。 在每个阶段,找到对应该阶段网站架构所面临的问题,在不断解决这些问题的过程中,系统的架构在不断地朝着正确的方向演进。

这里我们以淘宝为例,分析淘宝网站从一百个并发到亿级并发情况下服务架构的演进过程。淘宝作为电商平台,其架构经历了多次演进,以支持其快速增长的业务和高并发的用户请求。早期的淘宝采用了单体架构,随着业务的发展,逐步演进到使用分布式缓存、负载均衡、服务化等技术,最终采用了微服务架构

初始架构:单机架构

在淘宝网站最初时,应用数量与用户数都较少,可以把Tomcat和数据库部署在同一台服务器上。

浏览器往www.taobao.com发起请求时,首先经过DNS服务器(域名系统)把域名转换为实际IP地址10.102.4.1,浏览器转而访问该IP对应的Tomcat。

如下图所示:
在这里插入图片描述
新的技术挑战: 随着用户数的增长,Tomcat和数据库之间竞争资源,单机性能不足以支撑业务,架构演进势在必行。

第一次演进:Tomcat与数据库分开部署

第一次演进没有什么特别的,将 Tomcat 和数据库分别独占服务器资源,显著提高两者各自性能。

如下图所示:
在这里插入图片描述
新的技术挑战: 随着用户数的增长,并发读写数据库成为瓶颈。

第二次演进:引入本地缓存和分布式缓存

第二次架构演进引入了缓存,在Tomcat服务器上增加本地缓存,并在外部增加分布式缓存,缓存热门商品信息或热门商品的html页面等。

通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库压力。其中涉及的技术包括:使用memcached作为本地缓存,使用Redis作为分布式缓存,还会涉及缓存一致性、缓存穿透/击穿、缓存雪崩、热点数据集中失效等问题。

演进之后,如下图所示:
在这里插入图片描述
新的技术挑战:缓存抗住了大部分的访问请求,随着用户数的增长,并发压力主要落在单机的Tomcat上,响应逐渐变慢

第三次演进:引入反向代理实现负载均衡

在多台服务器上分别部署Tomcat,使用反向代理软件(Nginx)把请求均匀分发到每个Tomcat中。此处假设Tomcat最多支持100个并发,Nginx最多支持50000个并发,那么理论上Nginx把请求分发到500个Tomcat上,就能抗住50000个并发。

其中涉及的技术包括:Nginx、HAProxy,两者都是工作在网络第七层的反向代理软件,主要支持http协议,还会涉及session共享、文件上传下载的问题。

一起来看看使用反向代理之后的架构图:
在这里插入图片描述
新的技术挑战: 反向代理使应用服务器可支持的并发量大大增加,但并发量的增长也意味着更多请求穿透到数据库,单机的数据库最终成为瓶颈

第四次演进:数据库读写分离

把数据库划分为读库和写库,读库可以有多个,通过同步机制把写库的数据同步到读库。对于需要查询最新写入数据场景,可通过在缓存中多写一份,通过缓存获得最新数据。

其中涉及的技术包括:Mycat,它是数据库中间件,可通过它来组织数据库的分离读写和分库分表,客户端通过它来访问下层数据库,还会涉及数据同步,数据一致性的问题。

读写分离之后的架构图:
在这里插入图片描述
新的技术挑战: 业务逐渐变多,不同业务之间的访问量差距较大,不同业务直接竞争数据库,相互影响性能

第五次演进:数据库按业务分库

数据库按业务分库,把不同业务的数据保存到不同的数据库中,使业务之间的资源竞争降低,对于访问量大的业务,可以部署更多的服务器来支撑。这样同时会导致跨业务的表无法直接做关联分析,需要通过其他途径来解决。

分库之后的架构图如下所示:
在这里插入图片描述
新的技术挑战: 随着用户数的增长,单机的写库会逐渐达到性能瓶颈

第六次演进:把大表拆分为小表

比如针对评论数据,可按照商品ID进行hash,路由到对应的表中存储。

针对支付记录,可按照小时创建表,每个小时表继续拆分为小表,使用用户ID或记录编号来路由数据。

只要实时操作的表数据量足够小,请求能够足够均匀的分发到多台服务器上的小表,那数据库就能通过水平扩展的方式来提高性能。其中前面提到的Mycat也支持在大表拆分为小表情况下的访问控制。

这种做法显著地增加了数据库运维的难度,对DBA的要求较高。数据库设计到这种结构时,已经可以称为分布式数据库。

我们来看拆分小表之后的架构图:
在这里插入图片描述
新的技术挑战: 数据库和Tomcat都能够水平扩展,可支撑的并发大幅提高。然而随着用户数的增长,最终单机的Nginx会成为瓶颈

第七次演进:使用LVS或F5来使多个Nginx负载均衡

由于瓶颈在Nginx,因此无法通过两层的Nginx来实现多个Nginx的负载均衡。LVS和F5是工作在网络第四层的负载均衡解决方案,其中LVS是软件,运行在操作系统内核态,可对TCP请求或更高层级的网络协议进行转发,因此支持的协议更丰富,并且性能也远高于Nginx,可假设单机的LVS可支持几十万个并发的请求转发。

F5是一种负载均衡硬件,与LVS提供的能力类似,性能比LVS更高,但价格昂贵。

由于LVS是单机版的软件,若LVS所在服务器宕机则会导致整个后端系统都无法访问,因此需要有备用节点。

架构图如下:
在这里插入图片描述
新的技术挑战:由于LVS也是单机的,随着并发数增长到几十万时,LVS服务器最终会达到瓶颈。此时用户数达到千万甚至上亿级别,用户分布在不同的地区,与服务器机房距离不同,导致了访问的延迟会明显不同

第八次演进:通过DNS轮询实现机房间的负载均衡

在DNS服务器中可配置一个域名对应多个IP地址,每个IP地址对应到不同的机房里的虚拟IP。

当用户访问www.taobao.com时,DNS服务器会使用轮询策略或其他策略,来选择某个IP供用户访问。此方式能实现机房间的负载均衡

至此,系统可做到机房级别的水平扩展,千万级到亿级的并发量都可通过增加机房来解决,系统入口处的请求并发量不再是问题。

演进之后的架构图如下:
在这里插入图片描述
新的技术挑战: 随着数据的丰富程度和业务的发展,检索、分析等需求越来越丰富,单单依靠数据库无法解决如此丰富的需求

第九次演进:引入NoSQL数据库和搜索引擎等技术

当数据库中的数据多到一定规模时,数据库就不适用于复杂的查询了,往往只能满足普通查询的场景。

对于统计报表场景,在数据量大时不一定能跑出结果,而且在跑复杂查询时会导致其他查询变慢。

对于全文检索、可变数据结构等场景,数据库天生不适用。因此需要针对特定的场景,引入合适的解决方案。

如对于海量文件存储,可通过分布式文件系统HDFS解决,对于key value类型的数据,可通过Redis解决,对于全文检索场景,可通过搜索引擎如ElasticSearch解决,对于多维分析场景,可通过Kylin或Druid等方案解决。

当然,引入更多组件同时会提高系统的复杂度,不同的组件保存的数据需要同步,需要考虑一致性的问题,需要有更多的运维手段来管理这些组件等。

引入NoSQL和搜索引擎的架构图:
在这里插入图片描述
新的技术挑战: 引入更多组件解决了丰富的需求,业务维度能够极大扩充,随之而来的是一个应用中包含了太多的业务代码,业务的升级迭代变得困难。

第十次演进:大应用拆分为小应用

为了应对日益复杂的业务场景,通过使用分而治之的手段将整个网站业务拆分成不同的产品线,通过分布式服务来协同工作。

按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。这时候应用之间可能会涉及到一些公共配置,可以通过分布式配置中心Zookeeper来解决。

架构图如下:
在这里插入图片描述
新的技术挑战: 不同应用之间存在共用的模块,由应用单独管理会导致相同代码存在多份,导致公共功能升级时全部应用代码都要跟着升级。

第十一次演进:复用的功能抽离成微服务

如用户管理、订单、支付、鉴权等功能在多个应用中都存在,那么可以把这些功能的代码单独抽取出来形成一个单独的服务来管理,这样的服务就是所谓的微服务。应用通过HTTP、TCP或RPC请求等多种方式来访问服务,每个单独的服务都可以由单独的团队来管理。

此外,可以通过Dubbo、SpringCloud等框架实现服务治理、限流、熔断、降级等功能,提高服务的稳定性和可用性。
在这里插入图片描述
微服务架构并不是神话故事中的孙悟空,某一天忽然从石头缝里蹦出来了。微服务架构并不神秘,在“微服务架构”这个概念“火”起来之前,微服务架构叫什么?或者换一个说法:“微服务架构的雏形是什么?”其实,前文中网站架构演进的过程已经给出了答案。微服务架构这个概念变得流行之前,技术架构也在不断优化和演进。

微服务架构这个概念“火”起来之前,人们会用“分布式服务”或“服务化”来概括这种将大系统拆分为小系统的架构模式,与微服务架构的方式很像,也是对巨无霸的单体应用进行拆分,并结合RPC协议进行服务通信和调用。常见技术有Dubbo、DubboX、CXF、gRPC、HSF、Motan等。随着微服务概念的流行、微服务生态的完善和微服务架构落地规则的细化,现在业内人士都默认将这种架构方式称为微服务架构了。

有人肯定会有疑问,难道只能往微服务架构的方向上演进吗?答案肯定不是,在前面的架构演进图中,演进方向是一条笔直的线。而现实情况中肯定是有不同分支的,系统架构的演进并不是一条笔直的线,根据业务大小和业务侧重点的不同,系统架构在演进时也会朝着不同的方向发展,微服务架构只是众多技术架构中的一个,适合自身业务系统和技术团队的才是最好的架构。而且近些年又出现了Service Mesh、DDD领域驱动、云原生等比较流行的技术方案,今后还会有更加优秀的技术架构和落地方案出现。


http://www.ppmy.cn/server/165210.html

相关文章

Docker入门篇(Docker基础概念与Linux安装教程)

目录 一、什么是Docker、有什么作用 二、Docker与虚拟机(对比) 三、Docker基础概念 四、CentOS安装Docker 一、从零认识Docker、有什么作用 1.项目部署可能的问题: 大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题&#xff1…

PHP 常用函数2025.02

PHP implode() 函数 语法 implode(separator,array) 参数描述separator可选。规定数组元素之间放置的内容。默认是 ""(空字符串)。array必需。要组合为字符串的数组。 技术细节 返回值:返回一个由数组元素组合成的字符串。PHP 版…

DeepSeek:智能时代的AI利器及其应用前景

1.DeepSeek是什么? DeepSeek是一款基于人工智能技术的工具,旨在帮助用户高效处理和分析数据、生成内容、优化工作流程等。无论是数据分析、自然语言处理,还是自动化任务,DeepSeek都能提供强大的支持。其核心技术涵盖了机器学习、深…

ECharts 样式设置

ECharts 样式设置 引言 ECharts 是一款功能强大的可视化库,广泛用于数据可视化。样式设置是 ECharts 中的重要一环,它能够帮助开发者根据需求调整图表的视觉效果,使其更加美观和易于理解。本文将详细介绍 ECharts 的样式设置,包…

NLP深度学习 DAY5:Sequence-to-sequence 模型详解

Seq2Seq(Sequence-to-Sequence)模型是一种用于处理输入和输出均为序列任务的深度学习模型。它最初被设计用于机器翻译,但后来广泛应用于其他任务,如文本摘要、对话系统、语音识别、问答系统等。 核心思想 Seq2Seq 模型的目标是将…

Python3 OS模块中的文件/目录方法:os.path() 模块

一. 简介 前面文章简单学习了 Python3 中 OS模块中的文件/目录的部分函数。 本文继续学习 Python3 OS模块中的文件/目录方法:Python3 os.path() 模块,以及 path模块涉及的方法。 二. Python3 OS模块中的文件/目录方法:os.path() 模块 1. …

Vue3学习笔记-模板语法和属性绑定-2

一、文本插值 使用{ {val}}放入变量&#xff0c;在JS代码中可以设置变量的值 <template><p>{{msg}}</p> </template> <script> export default {data(){return {msg: 文本插值}} } </script> 文本值可以是字符串&#xff0c;可以是布尔…

pytorch实现门控循环单元 (GRU)

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 特性GRULSTM计算效率更快&#xff0c;参数更少相对较慢&#xff0c;参数更多结构复杂度只有两个门&#xff08;更新门和重置门&#xff09;三个门&#xff08;输入门、遗忘门、输出门&#xff09;处理长时依赖一般适…