【软件测试】学习笔记-网站伸缩性架构设计

这篇文章探讨网站的伸缩性架构设计是什么,以及在设计测试用例时需要注意哪些点。

可伸缩性和可扩展性的概念区别

可伸缩性翻译自Scalability,指的是通过简单地增加硬件配置而使服务处理能力呈线性增长的能力。最简单直观的例子,就是通过在应用服务器集群中增加更多的节点,来提高整个集群的处理能力。

可扩展性翻译自Extensibility,指的是网站的架构设计能够快速适应需求的变化,当需要增加新的功能实现时,对原有架构不需要做修改或者做很少的修改就能够快速满足新的业务需求。

分层的可伸缩性架构

网站的可伸缩性架构设计主要包含两个层面的含义:

  • 一个是指,根据功能进行物理分离来实现伸缩;
  • 另一个是指,物理分离后的单一功能通过增加或者减少硬件来实现伸缩。

在根据功能本身进行物理分离来实现伸缩的过程中,还有两种不同的实现方式:

  • 一种是功能的“横切”,比如一个电商网站的购物功能从上至下就可以分为界面UI层、业务逻辑处理层、公共服务层和数据库层,如果我们将这些层区分开来,每个层就可以独立实现可伸缩;

图1 功能“横切”示意图

  • 另一种是功能的“纵切”,比如一个电商网站可以根据经营的业务范围(比如书店、生鲜、家电和日化用品等)进行功能模块的划分,划分后的每个业务模块都可以独立地根据业务流量和压力来实现最适合自己规模的伸缩性设计。

图2 功能“纵切”示意图

同样地,对于单一功能可以通过增加或者减少硬件来实现的可伸缩性,也有两种不同的实现方式:

  • 一种是纵向的可伸缩性,指的是通过增加单一服务器上的硬件资源来提高处理能力。比如,在现有服务器上增加CPU、内存,或者在现有的RAID/SAN存储中增加硬盘等。- 传统软件企业使用的“宠物”模式,就是通过这个思路来实现有限的可伸缩性,我们往往把这种方式的伸缩性称为单节点的可伸缩性。显然,在如今海量互联网流量的情况下,想仅仅依赖于某一台服务器来处理各种请求显然是不可能的。
  • 另一种是横向的可伸缩性,指的是通过使用服务器集群来实现单一功能的可扩展性。当一台机器不足以处理大量用户并发请求的时候,我们就采用多台机器组成集群来共同负担并发压力。- 这种方式是基于集群的可伸缩性实现的,也是目前最主流的网站可伸缩性方法,也就是我之前提到过的“牲口”模式。很多时候当我们谈及网站的可伸缩性设计时,如果没有特定的上下文或者特指的场景,往往指的都是基于集群的可伸缩性。

图3 单一功能通过增加或者减少硬件来实现的可伸缩性

基于集群的可伸缩性设计,是和网站本身的分层架构设计相对应的:

  • 在应用服务器层面有应用服务器集群的可伸缩性架构设计;
  • 在缓存服务器层面有缓存服务器的可伸缩性架构设计;
  • 在数据库层面有数据库服务器的可伸缩性架构设计。

虽然都是可伸缩性设计,但是由于应用服务器、缓存服务器和数据库服务器本身的架构在设计上就有所区别,加之它们的使用场景不同,使得它们的可伸缩性架构设计就有着巨大的差异。

接下来,我就先简单解释一下这三个层面的可伸缩性设计指的是什么,以及从测试人员的角度来看我们需要关注哪些点。

应用服务器的可伸缩性设计

应用服务器的可伸缩性设计是最直观,也是最容易理解的。当一台应用服务器不足以支撑业务流量的时候,我们就可以用多台服务器来分担业务流量。

但是,为了保证这批服务器对外暴露的是一个统一的节点,我们就需要一个负载均衡器作为统一的窗口来对外提供服务,同时负载均衡器会把实际的业务请求转发给集群中的机器去具体执行。

这里需要特别注意的是,负载均衡器并不是按照你在字面上理解的“均衡”那样,把业务负载平均分配到集群中的各个节点,而是通过负载均衡算法(比如轮询算法、基于加权的轮询算法、最小链接算法等)将用户流量分配到集群机器。从这个意义上说,将负载均衡器称为任务分配器才更合适。

图4 通过负载均衡器实现的应用服务器集群示意图

为了实现线性可伸缩性,我们希望应用本身是无状态的。此时,任何请求都可以在集群中任意节点上来执行,也就是说集群的处理能力将随着节点数量的增多呈现线性增长的态势。

但是,如果应用本身是有状态的,那么就会要求基于一次会话(session)的多次请求都被分配到集群中某一台固定的服务器上去执行。

理解了上述应用服务器集群的可伸缩性架构原理后,我们再从测试人员的角度来想想,应该考虑哪些相关的测试场景。为此,我总结了以下几点供你参考:

  • 需要通过压力测试来得出单一节点的负载承受能力;
  • 验证系统整体的负载承受能力,是否能够随着集群中的节点数量呈现线性增长;
  • 集群中节点的数量是否有上限;
  • 新加入的节点是否可以提供和原来节点无差异的服务;
  • 对于有状态的应用,是否能够实现一次会话(session)的多次请求都被分配到集群中某一台固定的服务器上;
  • 验证负载均衡算法的准确性。

缓存集群的可伸缩性设计

缓存集群的可伸缩性设计,相比应用服务器集群要复杂得多。

传统的缓存服务器集群是无法通过简单地加入新的节点来实现扩容的,其中的根本原因,就要从缓存的核心原理开始讲起了。

假定,一个缓存集群中有3台机器,那么我们在将需要缓存的内容存入缓存集群的过程,包括了这三步:

  • 首先,将需要缓存的内容的Key值做Hash运算;
  • 然后,将得到的Hash值对3取余数;
  • 最后,将缓存内容写入余数所代表的那台服务器。

而此时,如果我们在缓存集群中加入了一台新的机器,也就是说缓存集群中机器的数量变成了4。这时Key的Hash值就应该对4取余,你会发现这么一来,原本已经缓存的绝大多数内容就都失效了,必须重构整个缓存集群。而这,显然不能被接受。

为了解决上述这个问题,使得缓存集群也可以做到按需、高效地伸缩,那就必须采用更为先进的Hash一致性算法。这个算法可以很巧妙地解决缓存集群的扩容问题,保证了新增机器节点的时候大部分的缓存不会失效。

如果你想了解Hash一致性算法更详细的细节,请自行百度。

同样地,知道了缓存集群扩容的实现细节后,我们再从测试人员的角度出发,看看需要额外关注哪些点。这里,我总结了以下几点供你参考:

  • 针对缓存集群中新增节点的测试,验证其对原有缓存的影响是否足够小;
  • 验证系统冷启动完成后,缓存中还没有任何数据的时候,如果此时网站负载较大,数据库是否可以承受这样的压力;
  • 需要验证各种情况下,缓存数据和数据库数据的一致性;
  • 验证是否已经对潜在的缓存穿透攻击进行了处理,因为如果有人刻意利用这个漏洞来发起海量请求的话,就有可能会拖垮数据库。

数据库的可伸缩性设计

从实际应用的角度来看,数据库的可伸缩性设计主要有四种方式:

第一种方式是目前最常用的业务分库,也就是从业务上将一个庞大的数据库拆分成多个不同的数据库。比如,对于电商网站来说,它们可以考虑将用户相关的表放在一个数据库中,而商品相关的表放在另一个数据库中。

这种方式本身也符合模块设计分而治之的思想,但最大的问题是跨数据库数据的join操作只能通过代码在内存中完成,实现代价和成本都比较高。这种方式目前在一些中大型电商有不同程度的应用。

第二种方式是读写分离的数据库设计,其中主库用于所有的写操作,从库用于所有的读操作,然后主从库会自动进行数据同步操作。这样一来,主库就可以根据写操作来优化性能,而从库就可以根据读操作来优化性能。

但是,这个架构最大的问题在于可能出现数据不一致的情况。比如,写入的数据没能及时同步到从库,就可能会出现数据不一致。另外,这种读写分离的设计对数据库可伸缩性的贡献来讲,比较有限,很难从根本上解决问题。

这种方式主要应用在中小型规模的网站中,同时读写分离的设计也通常会和业务分库的设计一起采用,来提高业务分库后的数据库性能。

为了进一步提高数据库的可伸缩性,于是就出现了第三种数据库的可伸缩性设计:分布式数据库。分布式数据库同样存在数据不一致的问题,并且,这个方法通常只在单个数据表异常庞大的时候才会被采用,否则我还是更推荐业务分库的方法。这种数据库设计可以说是比较主流的应对大规模高并发应用的数据库方案。

第四种方式则是完全颠覆了传统关系型数据数据库的NoSQL设计。NoSQL放弃了事务一致性,并且天生就是为了可伸缩性而设计的,所以在可伸缩性方面具有天然优势。因此,在互联网领域被广泛使用。

从测试的角度出发,无论是数据库架构哪种设计,我们一般都会从以下几个方面来考虑测试用例的设计:

  • 正确读取到刚写入数据的延迟时间;
  • 在数据库架构发生改变,或者同样的架构数据库参数发生了改变时,数据库基准性能是否会发生明显的变化;
  • 压力测试过程中,数据库服务器的各项监控指标是否符合预期;
  • 数据库在线扩容过程中对业务的影响程度;
  • 数据库集群中,某个节点由于硬件故障对业务的影响程度。

总结

可伸缩性翻译自Scalability,而可扩展性翻译自Extensibility,从英文单词的含义上我们就可以看出这两个概念间的差异了。

网站的可伸缩性架构设计主要包含两个层面的含义,一个是指根据功能进行物理分离来实现伸缩,另一个是指物理分离后的单一功能通过增加或者减少硬件来实现伸缩。

从整体架构的角度来看,应用服务器、缓存集群和数据库服务器各自都有适合自己的可伸缩性设计策略:应用服务器主要通过集群来实现可伸缩性,缓存集群主要通过Hash一致性算法来实现,数据库可以通过业务分库、读写分离、分布式数据库以及NoSQL来实现可伸缩性。

而相应的理解了网站的可伸缩性架构设计后,我们在开展测试时,就可以非常自信地设计出有针对性的测试用例了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows使用docker安装redis

windows环境搭建专栏🔗点击跳转 win系统环境搭建(十二)——Windows系统下使用docker安装redis 文章目录 win系统环境搭建(十二)——Windows系统下使用docker安装redis1.创建文件夹2.docker-compose.yaml配置文件3.red…

基于YOLOv8的学生课堂行为检测,引入BRA注意力和Shape IoU改进提升检测能力

💡💡💡本文摘要:介绍了学生课堂行为检测,并使用YOLOv8进行训练模型,以及引入BRA注意力和最新的Shape IoU提升检测能力 1.SCB介绍 摘要:利用深度学习方法自动检测学生的课堂行为是分析学生课堂表…

TCP/IP协议及配置、IP地址、子网掩码、网关地址、DNS与DHCP介绍

一、什么是服务器 能够为其他计算机提供服务的更高级的电脑 尺寸:Unit 1u1.75英寸44.45mm4.445cm IDC(机房) C/S结构 Client/Server客户端和服务端 二、TCP/IP协议 计算机与计算机之间通信的协议 三要素: IP地址 子网掩码 IP路由 I…

Mac book air 重新安装系统验证显示 untrusted_cert_title

环境: Mac Book Air macOS Sierra 问题描述: Mac book air 重新安装系统验证显示 untrusted_cert_title 解决方案: 1.终端输入命令行输入 date 会看到一个非常旧的日期 2.更改日期为当前时间 使用以下命令来设置日期和时间&#xff1a…

68. redis计数与限流中incr+expire的坑以及解决办法(Lua+TTL)

文章目录 一、简介二、代码演进第一版代码(存在bug隐患)第二版代码(几乎无隐患)第三版代码(完美无瑕) 一、简介 在日常工作中,经常会遇到对某种操作进行频次控制或者统计次数的需求,此时常用的…

安全基础~攻防特性3

文章目录 SSTI(模板注入)1. 简介2. 成因3. 常见框架存在注入4. 判断存在SSTI SSTI(模板注入) 1. 简介 (Server-Side Template Injection) 服务端模板注入 1、使用框架(MVC的模式),如python的flask,php的tp,java的sp…

Docker安装配置OnlyOffice

OnlyOffice 是一款强大的办公套件,你可以通过 Docker 轻松安装和部署它。本文将指导你完成安装过程。 步骤 1:拉取 OnlyOffice Docker 镜像 首先,使用以下命令从 Docker Hub 拉取 OnlyOffice Document Server 镜像: sudo docke…

Linux设备管理模型-02:sysfs

文章目录 sysfs1 使用sysfs控制GPIO2 sysfs编程2.1 完善sysfs属性文件的读写操作 上一篇文: 设备管理模型中的基础数据结构 sysfs sysfs是用于导出内核对象的文件系统,它是一个基于ram的文件系统,最初基于ramfs。 sysfs通常挂载在/sys目录下。它提供了一…

Linux中的共享内存

定义: 共享内存允许两个或者多个进程共享物理内存的同一块区域(通常被称为段)。由于一个共享内存段会称为一个进程用户空间的一部分,因此这种 IPC 机制无需内核介入。所有需要做的就是让一个进程将数 据复制进共享内存中&#xff…

web漏洞总结大全(基础)

前言 本文章是和cike_y师傅一起写的,cike_y博客:https://blog.csdn.net/weixin_53912233?typeblog 也欢迎大家对本文章进行补充和指正,共同维护这个项目,本文的github项目地址: https://github.com/baimao-box/Sum…

Golang 搭建 WebSocket 应用(八) - 完整代码

本文应该是本系列文章最后一篇了,前面留下的一些坑可能后面会再补充一下,但不在本系列文章中了。 整体架构 再来回顾一下我们的整体架构: 在我们的 demo 中,包含了以下几种角色: 客户端:一般是浏览器&am…

java枚举详细解释

枚举的基本认识 我们一般直接定义一个单独的枚举类 public enum 枚举类名{枚举项1,枚举项2,枚举项3 } 可以通过 枚举类名.枚举项 来访问该枚举项的 - 可以理解为 枚举项就是我们自己定义的一个数据类型,是独一无二的 接下来我们直接用一个例子来完全理解 加深理解 这里…

Linux-nginx(安装配置nginx、配置反向代理、Nginx配置负载均衡、动静分离)

关于代理 正向代理: 客户明确知道自己访问的网站是什么 隐藏客户端的信息 目录 关于代理 一、Nginx的安装与配置 1、安装依赖 2、安装nginx (1)上传压缩包到目录 /usr/nginx里面 (2)解压文件 (3&#xff09…

String在VS与Linux下的区别

目录 一、string的成员 1.VS 2.Linux 二、string的扩容机制 1. VS 2.Linux 一、string的成员 string是C标准库中的一个类模板,用于表示和操作字符串 string在 Windows 与 Linux 中的成员不是相同的 1.VS 4个成员:_str , _size , _capacity 和…

【一文详解】Java多线程和并发知识点详细总结【万字总结】

Java并发编程 并发编程的三个特性 原子性 一次操作或者多次操作,要么所有的操作全部都得到执行并且不会受到任何因素的干扰而中断,要么都不执行。 在 Java 中,可以借助synchronized、各种 Lock 以及各种原子类实现原子性。 synchronized…

MySQL(五)——多表查询

上期文章 MySQL(四)——约束 文章目录 上期文章多表关系一对多(多对一)多对多多表外键关系可视化一对一 多表查询概述笛卡尔积多表查询分类连接查询 内连接隐式内连接显式内连接 外连接左外连接右外连接 自连接联合查询 union&am…

python-基础篇-变量

文章目录 变量的基本使用目标01. 变量定义1) 变量演练1 —— iPython2) 变量演练 2 —— PyCharm3) 变量演练 3 —— 超市买苹果思考题 02. 变量的类型2.1 变量类型的演练 —— 个人信息2.2 变量的类型2.3 不同类型变量之间的计算1) **数字型变量** 之间可以直接计算2) **字符串…

Python基础第四篇(Python函数)

文章目录 一、函数介绍二、函数的定义三、函数的参数与返回值四、函数说明文档五、函数的嵌套六、变量域七、函数案例1.源代码2.读出结果 在程序设计领域,函数成为一个不可或缺的角色,它们为我们提供了精练、高效和易于管理的编程方式。本篇博客将带您深…

CentOS 7安装Java并配置环境

一、安装Java环境 1、检查系统是否安装Java [rootlocalhost ~]# java -version 2、更新系统软件包 [rootlocalhost ~]# yum update #遇到[y/n],选择y并回车,耐心等待下载完毕,之后系统会自动检验更新的软件包遇到 /var/run/yum.pid 已被锁定 /var/…

【动态规划】【数学】【C++算法】805 数组的均值分割

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 动态规划 数学 805 数组的均值分割 给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 数组 或者 B 数组中,使得 A 数组和 B 数组不为空,并且 average(A) average(B)…