软件架构之前后端分离架构服务器端高并发演进之路

软件架构之前后端分离架构&服务器端高并发演进之路

  • 前后端分离架构
      • 从业务角度
      • 从质量属性
      • 从性能角度
  • 服务器端关于不同并发量的演进之路
    • 1. 单体架构
    • 2. 第一次演进:应用服务器和数据库服务器分开部署
    • 3. 第二次演进:引入本地缓存和分部署缓存
    • 4. 第三次演进:引入反向代理和负载均衡
    • 5. 第四次演进:数据库读写分离
    • 6. 第五次演进:[分库] 数据库按业务分库
    • 7. 第六次演进:[分表] 把大表拆分成小表
    • 8. 第七次演进:使多个Nginx负载均衡
    • 9. 第八次演进:通过DNS轮询实现机房之间的负载均衡
    • 10. 第九次演进:引入NoSQL数据库和搜索引擎等技术
    • 11. 第十次演进:大应用拆分为小应用
    • 12. 第十一次演进:复用的功能抽离成微服务
    • 13. 第十二次演进:引入企业服务总线ESB屏蔽服务接口的访问差异
    • 14. 第十三次演进:引入容器化技术实现运行环境隔离与动态服务管理
    • 15. 第十四次演进:以云平台承载系统

首先,当一个项目刚起步的时候,不能预知后续的访问量和并发能达到多少,在初步开发的架构选型中,采用前后端分离的架构。关于前后端分离架构,其优势如下:

前后端分离架构

前后端分离是一种软件系统架构模式,它将应用程序的前端和后端分离开发和部署。在这种架构中,前端和后端是独立的系统,通过API(应用程序接口)进行通信。

从业务角度

前后端分离架构可退可进,目前是一个应用刚起步的最基本架构。将前后端分离开来,则前端只需要负责跟人机进行交互,关注业务流程。后端则只需要关注算法数据,运算逻辑等。

从质量属性

前端关注易用性,美观;后端注重扩展性、可用性和性能。

从性能角度

前端消耗内存和带宽;后端有效消耗CPU。前后端消耗计算机硬件分工不同。前端考虑怎么跟人进行有效交互,后端则把重心放在怎么跟计算机打交道更高效稳定。

这样的前后端分离架构,使得在消耗计算机硬件如高性能、高可用方面能够有效剥离出来,只用一心一意的考虑把后端代码达到性能更优 下面介绍服务器端的性能优化演进之路。

服务器端关于不同并发量的演进之路

1. 单体架构

当一个项目在初期起始阶段,应用数量与用户数量都比较少,此时的应用服务器(如Tomcat)和数据库服务器部署在同一台服务器上,以淘宝为例:浏览器往www.taobao.com发起请求时,首先经果DNS服务器(域名解析系统)把域名转换成实际IP地址10.102.4.1,浏览器转而访问该IP对应的
Tomcat。
在这里插入图片描述
但是随着用户数量的增加,Tomcat和数据库之间竞争资源,单机性能不足以支撑业务。

2. 第一次演进:应用服务器和数据库服务器分开部署

Tomcat和数据库分别独占服务器资源,通过增加服务器分担应用的方式,显著的提高了两者各自的性能。
在这里插入图片描述
但是随着用户数量的增长,并发读写数据库成为了性能的瓶颈。

3. 第二次演进:引入本地缓存和分部署缓存

在Tomcat同服务器或者同JVM、中增加本地缓存,并在外部增加分布式缓存,缓存热点数据的HTML页面等。通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库的压力。
在这里插入图片描述
缓存虽然抗住了大部分的访问请求,但是随着用户数量的增长,并发的压力还是主要落在了单机的Tomcat上,响应逐渐变慢。

4. 第三次演进:引入反向代理和负载均衡

在多台服务器上分别部署Tomcat,使用反向代理软件(Nginx)把请求均匀分发到每个Tomcat中。
在这里插入图片描述
虽然反向代理使用服务器可以支持的并发量大大增加,但是并发量的增加也意味着更多请求穿透到数据库,单机的数据库最终会成为性能瓶颈。

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

把数据库划分为读库和写库,读库可以有多个,通过同步机制把写库的数据同步到读库,对于需要查询最新写入数据的场景,可以在缓存中多写一份,通过缓存获得最新数据。
在这里插入图片描述
但是随着业务逐渐变多,不同业务之间的访问量差距较大,不同业务直接竞争数据库资源,相互影响性能。

6. 第五次演进:[分库] 数据库按业务分库

把不同业务的数据保存到不同的数据库中,使业务之间的资源竞争降低。对于访问量大的业务,可以部署更多的服务器来支撑。
在这里插入图片描述
但是随着用户数量的增长,单机的写库会逐渐达到性能瓶颈。

7. 第六次演进:[分表] 把大表拆分成小表

比如针对评论数据,可以按照商品的ID进行Hash,路由到对应的表中存储;针对支付记录,可以按照支付的小时创建表,每个小时表继续拆分为小表,使用用户ID或记录编号来路由数据。只要实时操作的表数据量足够小,请求能够足够均匀地分发到多台服务器上的小表,那数据库就能通过水平扩展的方式来提升性能。
在这里插入图片描述
虽然数据库和Tomcat、都能够水平扩展,可以支撑的并发量大幅提升,但是随着用户量的增长,最终单机的Nginx会成为性能上的瓶颈。

8. 第七次演进:使多个Nginx负载均衡

由于性能瓶颈在Nginx,因此无法通过两层的Nginx来实现多个Nginx的负载均衡。LVS和F5是工作在网络第四层的负载均衡解决方案,其中LVS是软件,运行在操作系统内核态,可对TCP请求或更高层级的网络协议进行转发,因此支持的协议更丰富,并且性能也远高于Nginx,可假设单机的LVS可支持几十万个并发的请求转发;F5是一种负载均衡硬件,与LVS提供的能力类似,性能比LVS更高,但价格昂贵。由于LVS是单机版的软件,若LVS所在服务器宕机则会导致整个后端系统都无法访问,因此需要有备用节点。可使用keepalived软件模拟出虚拟IP,然后把虚拟IP绑定到多台LVS服务器上,浏览器访问虚拟IP时,会被路由器重定向到真实的LVS服务器,当主LVS服务器宕机时,keepalived软件会自动更新路由器中的路由表,把虚拟IP重定向到另外一台正常的LVS服务器,从而达到LVS服
务器高可用的效果。
在这里插入图片描述
由于LVS也是单机的,随着并发数量增长到几十万时,LVS服务器最终会达到性能瓶颈,此时用户数量达到千万甚至上亿级别,用户分布在不同的地区,与服务器机房距离不同,导致了访问的延迟会明显不同。

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

在DNS服务器中可配置一个域名对应多个IP地址,每个IP地址对应到不同的机房里的虚拟IP。当用户访问www.taobao.com时,DNS服务器会使用轮询策略或其他策略,来选择某个IP供用户访问。此方式能实现机房间的负载均衡,至此,系统可做到机房级别的水平扩展,千万级到亿级的并发量都可通过增加机房来解决,系统入口处的请求并发量不再是问题。
在这里插入图片描述
但是随着数据的丰富程度和业务的发展,检索、分析等需求越来越丰富,单单依靠数据库无法解决如此丰富的需求。

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

当数据库中的数据多到一定规模的时候,数据库就不适用于复杂查询了,往往只能满足普通查询的场景。对于统计报表的场景,在数据量大时不一定能跑出结果,而且在跑复杂查询时会导致其他查询变慢。
在这里插入图片描述
引入更多组件解决了丰富的需求,业务维度能够极大扩充,但随之而来的是一个应用包含了太多的业务代码,业务的升级迭代变得困难。

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

按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。
在这里插入图片描述
但是不同的应用之间可能存在共用的模块,由应用单独管理会导致相同的代码存在多份,导致公共功能在升级时全部应用代码要跟着升级。

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

如用户管理、订单、支付、鉴权等功能在多个应用中都存在,那么可以把这些功能的代码单独抽取出来形成一个单独的服务来管理,这样的服务就是所谓的微服务,应用和服务之间通过HTTP、TCP或RPC请求等多种方式来访问公共服务,每个单独的服务都可以由单独的团队来管理。
在这里插入图片描述
但是由于不同服务的接口访问方式不同,应用代码需要适配多种访问方式才能使用服务。此外,应用访问服务,服务之间也可能互相访问,调用链将会变得非常复杂,逻辑变得混乱。

13. 第十二次演进:引入企业服务总线ESB屏蔽服务接口的访问差异

通过ESB统一进行访问协议转换,应用统一通过ESB来访问后端服务,服务与服务之间也通过ESB来互相调用,以此降低系统的耦合程度。这种单个应用拆分为多个应用,公共服务单独抽出来管理,并使用企业总线来解除服务之间耦合问题的架构,就是所谓的SOA(面向服务)架构。
在这里插入图片描述
但是随着业务不断发展,应用和服务都会不断变多,应用和服务的部署变得复杂,同一台服务器上部署多个服务还要解决运行环境冲突的问题。此外,对于如大促这类需要动态扩缩容的场景,需要水平扩展服务的场景,就需要在新增的服务器上准备运行环境,部署服务等,运维将变得十分困难。

14. 第十三次演进:引入容器化技术实现运行环境隔离与动态服务管理

目前最流行的容器化技术是Docker,最流行的容器管理服务是Kubernetes(K8S),应用/服务可以打包为Docker镜像,通过K8S来动态分发和部署镜像。Docker镜像可理解为一个能运行你的应用/服务的最小的操作系统,里面放着应用/服务的运行代码,运行环境根据实际的需要设置好。把整个“操作系统”打包为一个镜像后,就可以分发到需要部署相关服务的机器上,直接启动Docker镜像就可以把服务起起来,使服务的部署和运维变得简单。
在这里插入图片描述

15. 第十四次演进:以云平台承载系统

TODO

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/77979.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dajngo06_Template模板

Dajngo06_Template模板 6.1 Template模板概述 模板引擎是一种可以让开发者把服务端数据填充到html网页中完成渲染效果的技术 静态网页:页面上的数据都是写死的,万年不变 动态网页:页面上的数据是从后端动态获取的(后端获取数据库…

车载网络扫盲

目录 车载以太网发展技术 车载网络通信架构与拓扑 车载网络的车载网关 车载网络通信协议 二层确定性以太网协议 二层车载网络扩展协议 三层安全加密协议 四层应用通信协议 车载网络通信架构的网络安全 车载以太网发展技术 车载网络技术包括车载影音娱乐和车载导航需要的MOST&am…

粘包问题

一.粘包原因及解决办法 粘包(Packet Sticking)是指在网络通信中,发送的数据包在接收端被合并成一个大的数据块或多个数据包被拆分成较小的数据块,导致接收端无法正确解析和处理数据的现象。 粘包问题可能由以下几个原因引起&…

Java多线程篇(1)——深入分析synchronized

文章目录 synchronized原理概述锁升级 初始状态偏向锁偏向锁获取/重入偏向锁的撤销/重偏向和升级批量重偏向和批量偏向撤销偏向锁的释放 轻量级锁轻量级锁获取/重入轻量级锁膨胀轻量级锁释放 重量级锁重量级锁获取/重入重量级锁释放重量级锁的降级 其他锁粗化、锁消除调用hashc…

IDEA(2023)修改默认缓存目录

😇作者介绍:一个有梦想、有理想、有目标的,且渴望能够学有所成的追梦人。 🎆学习格言:不读书的人,思想就会停止。——狄德罗 ⛪️个人主页:进入博主主页 🗼专栏系列:无 &#x1f33c…

OSCP系列靶场-Esay-Vegeta1保姆级

OSCP系列靶场-Esay-Vegeta1保姆级 目录 OSCP系列靶场-Esay-Vegeta1保姆级总结准备工作信息收集-端口扫描目标开放端口收集目标端口对应服务探测 信息收集-端口测试22-SSH端口的信息收集22-SSH端口版本信息与MSF利用22-SSH协议支持的登录方式22-SSH手动登录尝试(无)22-SSH弱口令…

stu02-初识HTML

1.HTML概述 (1)HTML是Hyper Text Mark-up Language的首字母缩写。 (2)HTML是一种超文本标记语言。 (3) 超文本:指除了文字外,页面内还可以包含图片、链接、甚至音乐、视频等非文字元…

二叉树顺序存储结构

目录 1.二叉树顺序存储结构 2.堆的概念及结构 3.堆的相关接口实现 3.1 堆的插入及向上调整算法 3.1.1 向上调整算法 3.1.2 堆的插入 3.2 堆的删除及向下调整算法 3.2.1 向下调整算法 3.2.2 堆的删除 3.3 其它接口和代码实现 4.建堆或数组调堆的两种方式及复杂度分析…

React 组件实例的三大核心—props

0x00 前言 CTF 加解密合集CTF Web合集网络安全知识库溯源相关 文中工具皆可关注 皓月当空w 公众号 发送关键字 工具 获取 0x01 props 基础 1.props渲染 1.1 常规渲染 class Person extends React.Component{render(){const {name,age,sex} this.propsreturn (<ul>…

使用 Python 来创建一个基本的命令行密码管理器

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 密码管理器项目简介…

长亭雷池社区版本安装与使用

0x01 雷池介绍 一款足够简单、足够好用、足够强的免费 WAF。基于业界领先的语义引擎检测技术&#xff0c;作为反向代理接入&#xff0c;保护你的网站不受黑客攻击。核心检测能力由智能语义分析算法驱动&#xff0c;专为社区而生&#xff0c;不让黑客越雷池半步。 官方网址&…

11809 - Floating-Point Numbers (UVA)

题目链接如下&#xff1a; Online Judge 这道题目我想到了打表做&#xff0c;但是没想到用log来简化……写了一个比较复杂的版本&#xff0c;严重超时。后来看了别人的题解才做出来。UVa 11809 Floating-Point Numbers&#xff08;浮点数&#xff09;_ShannonNansen的博客-CS…

【Linux】多线程互斥与同步

文章目录 一、线程互斥1. 线程互斥的引出2. 互斥量3. 互斥锁的实现原理 二、可重入和线程安全三、线程和互斥锁的封装1. 线程封装1. 互斥锁封装 四、死锁1. 死锁的概念2. 死锁的四个必要条件3. 避免死锁 五、线程同步1. 线程同步的理解2. 条件变量 一、线程互斥 1. 线程互斥的…

SOLR分组聚合的相关技巧

0. 前言 使用SOLR的时候我是抗拒的&#xff0c;又应为项目只能用SOLR实现需要&#xff0c;没有办法只能硬着头皮来做&#xff0c;如果实现没办法可以看看下文。在做的过程中&#xff0c;SOLR这个技术栈可能用的少&#xff0c;国内的文字写的都是基本应用&#xff0c;facet que…

Mybatis注解开发---增删改查

目录 &#xff08;1&#xff09;insert测试方法 &#xff08;2&#xff09;delete测试方法 &#xff08;3&#xff09;update测试方法 &#xff08;4&#xff09;select测试方法 一定要记得注册映射 <mappers><package name"com.gq.mapper"/></m…

卷积网络:实现手写数字是识别50轮准确率97.3%

卷积网络&#xff1a;实现手写数字是识别50轮准确率 1 导入必备库2 torchvision内置了常用数据集和最常见的模型3 数据批量加载4 绘制样例5 创建模型7 设置是否使用GPU8 设置损失函数和优化器9 定义训练函数10 定义测试函数11 开始训练12 绘制损失曲线并保存13 绘制准确率曲线并…

机器人连续位姿同步插值轨迹规划—对数四元数、b样条曲线、c2连续位姿同步规划

简介&#xff1a;Smooth orientation planning is benefificial for the working performance and service life of industrial robots, keeping robots from violent impacts and shocks caused by discontinuous orientation planning. Nevertheless, the popular used quate…

学习记忆——方法篇——连锁拍照、情景故事和逻辑故事法

三大方法速记这些内容 1、连锁拍照法速记重要事件 2、情景故事速记速记购物信息 3、逻辑故事法速记客户档案 一、连锁拍照法速记重要事件 例&#xff1a;女朋友在出差之前嘱咐男朋友几件事 1、把房间收拾干净&#xff0c;最重要的是要把书架整理了&#xff0c;垃圾倒了 2、记…

Spring+MyBatis使用collection标签的两种使用方法

目录 项目场景&#xff1a; 实战操作&#xff1a; 1.创建菜单表 2.创建实体 3.创建Mapper 4.创建xml 属性描述&#xff1a; 效率比较&#xff1a; 项目场景&#xff1a; 本文说明了Spring BootMyBatis使用collection标签的两种使用方法 1. 方法一: 关联查询 2. 方法…

学习Bootstrap 5的第九天

目录 列表组 基础的列表组 实例 活动的列表项 实例 禁用的列表项 实例 链接列表项 实例 移除列表边框 实例 带编号的列表组 实例 水平列表组 实例 多种颜色列表项 实例 多种颜色的链接列表项 实例 带徽章的列表组 实例 列表组案例 实例一 实例二 列表组…