【软件测试】学习笔记-网站可扩展性架构设计
可扩展性,指的是网站的架构设计能够快速适应需求的变化,当需要增加新的功能实现时,对原有架构不需要做修改或者做很少的修改就能够快速实现新的业务需求。
从这个定义中,我们很容易就可以得出衡量网站可扩展性设计优秀与否的主要标准,就是增加新功能的时候对原有系统的影响是否足够小。
当今的商业环境决定了网站新功能开发与上线的时间周期必须非常短,如果每次添加新功能,都需要对原有系统进行大量修改,从而还会牵连出更多测试工作的话,那么你的竞争力就会被大打折扣,用一个不太恰当的比喻就是直接“输在了起跑线上”。
其实,添加新功能时必须要对系统进行大幅度修改的原因是,系统架构设计上的耦合性。那么,有什么“好的”架构设计方案可以使得我们添加新功能的时候,只需对原有系统做少量修改,甚至完全不需要修改吗?
咋一听起来,这就像“又要马儿跑,又要马儿不吃草”。但,其实不是的。我们往往可以通过架构上的设计优化来达到事半功倍的效果。
为了帮助你理解可扩展性,先看一个案例。
网站可扩展性架构设计的案例
假设你现在为了实时监控服务器的健康状态,需要为网站添加一个实时收集服务器端监控指标的功能,此时最直接的方案就是用代码去实现对每一个监控指标的收集,然后将所有的这些代码集成在一起形成一个可执行程序运行在服务器端后台。
这样的设计固然简单直接,而且也能实现所有的功能需求(收集各种监控指标),但是当你需要收集一个新的监控指标时,就不得不更新整个可执行程序了。如果你需要经常添加新的监控指标的话,那么这样的设计就不能满足可扩展性的要求了。
我们希望的是,当增加新的监控指标的时候,原有的系统不需要做任何修改,甚至可以做到实时添加全新的监控指标。为了达到这个目的,现有的其他方案都不能满足或者不容易满足这个要求,所以我们就必须要在架构设计上做些文章了。
我们可以把对每一个监控指标的代码实现,直接打包成一个个的可执行监控子程序,比如收集CPU使用率的程序A、收集内存使用率的程序B等,然后运行在服务器后台的监控主程序通过调用这些子程序,比如程序A和B,来实现所有的监控需求。
这时,再增加新的监控指标时,原有系统就不需要做任何改动,只需要独立实现新的监控子程序,然后以配置文件的形式“告诉”主程序新添加的监控子程序的路径即可。这也就实现了系统的可扩展性。
接下来,我们再一起回到网站的可扩展性设计上来。其实,提升网站可扩展性性的核心,就是降低系统各个模块和组件之间的耦合。耦合程度越低,各个模块和组件的复用可能性就越大,系统的可扩展性也会越好。
从现在来看,实现网站可扩展性架构的主要技术手段包括事件驱动架构和微服务架构。
微服务架构从根本上改变了网站的架构形式,带来可扩展性便利的同时,还带来了很多其他优秀的特性。在微服务架构下,一个大型复杂软件系统不再由一个单体组成,而是由一系列的微服务组成。其中每个微服务可被独立开发和部署,各个微服务之间是松耦合的。每个微服务仅专注于完成一件任务,并要很好地完成该任务。
在微服务架构下,当网站需要增加新功能时,我们除了可以添加新的业务逻辑外,还可以利用原本已经存在的微服务来构建新的功能。由于服务和服务之间是相互隔离的,并且单个服务还可以被其他多个服务复用,所以系统的可扩展性会比较好。
事件驱动架构与消息队列
事件驱动架构设计的出发点源于这样一个事实:如果系统的各个模块之间的协作不是通过直接的调用关系来实现的,那么系统的可扩展性就一定会更好。问题是,系统的各个模块间的协作如何才能不基于调用关系呢?
答案就是事件消息。系统各个模块之间只是通过消息队列来传输事件消息,而各模块之间并没有直接的调用关系、保持松散的耦合关系。
事件驱动架构最典型的一个应用就是操作系统中常见的生产者和消费者模式,将其应用到网站设计中就是分布式消息队列。
分布式消息队列同样采用了生产者和消费者模式:
- 消息的发送者负责将消息发布到消息队列中,也就是“生产者”;
- 另外,系统中会有一个或者多个消息接收者订阅消息,订阅目的是为了获取消息并进行处理,这里的消息订阅者其实就是“消费者”。消息接收者发现消息队列中有新的消息后,就会立马对其进行处理。
可以看到,在这种模式下,消息的发送者和接收者之间并没有任何直接的联系,是松耦合的。它们的协作是通过消息队列这个“中间人”进行的。消息的发送者将消息发送至消息队列后,就结束了对消息的处理,而消息的接收者只是从消息队列中获取消息进行后续的处理,并不需要知道这些消息从哪里来,因此可以很方便地实现高可扩展性。
所以,采用这种模式的话,当网站需要增加新功能的时候,只要增加对应的新模块,再由对此模块感兴趣的“消费者”进行订阅,就可以实现对原有系统功能的扩展了,而对原本的系统模块本身并没有影响。
此时,消息队列的架构如图1所示。
图1 消息队列的原理图
引入了消息队列后,我们不仅可以提高系统的可扩展性,还可以再一定程度上改善网站架构的高性能、高可用性和可伸缩性。
- 从性能方面来看,消息发送者不需要等接收者实际处理完成后才返回,也就是从原本的同步处理变成了异步处理,所以用户会感知到网站性能的提升。
- 从高可用方面来看,假如消息的接收者模块发生了短时间的故障,此时并不会影响消息发送者向消息队列中发送消息,等到消息接收者模块恢复后可以继续后续的处理,只要这段时间内消息队列本身没有被塞满而出现消息丢失的情况。从整体角度看,系统并不会感知到消息接收者模块曾经发生过短暂故障,也就相当于保证了系统的高可用。
- 从可伸缩性方面来看,消息队列的核心其实就是一个无状态的存储。所以,当系统需要能够保留更多的消息时,我们通过简单地增加存储空间就可以实现。尤其是,大规模的电商网站来更会将消息队列扩展成为分布式消息队列集群,来实现消息队列的可伸缩性。
引入消息队列后,测试人员需要额外关注的点
现在,你应该已经掌握了消息队列的基本原理,以及在网站架构中的用法。接下来,我们再一起看看消息队列对测试的影响,以及我们在测试时需要特别关注哪些点。
这里,我把测试人员需要额外关注的点,归纳为了以下几点:
- 从构建测试数据的角度来看,为了以解耦的方式测试系统的各个模块,我们就需要在消息队列中构造测试数据。这也是为什么很多互联网的自动化测试框架中都会集成有消息队列写入工具的主要原因。
- 从测试验证的角度来看,我们不仅需要验证模块的行为,还要验证模块在消息队列中的输出是否符合预期。为此,互联网的自动化测试框架中也都会集成消息队列的读取工具。
- 从测试设计的角度来看,我们需要考虑消息队列满、消息队列扩容等情况下系统功能是否符合设计预期。
- 除此之外,我们还需要考虑,某台消息队列服务器宕机的情况下,丢失消息的可恢复性以及新的消息不会继续发往宕机的服务器等等。
总结
在这篇文章中,分享了网站架构知识中的可扩展性。
可扩展性指的是网站的架构设计能够快速适应需求的变化,当需要增加新功能时,我们只要对原有架构进行少量修改,甚至不用修改就能快速实现新的业务需求。
从技术实现上来看,消息队列是实现可扩展性的重要技术手段之一。其基本核心原理是各模块之间不存在直接的调用关系,而是使用消息队列,通过生产者和消费者模式来实现模块间的协作,从而保持模块与模块间的松耦合关系。
引入消息队列后,测试数据的创建和测试结果的验证工作,都需要通过读写消息队列来完成。同时,我们还要考虑到消息队列满、消息队列扩容,以及消息队列服务器宕机情况下的系统功能验证。这几个点,就是测试人员需要额外关注的点了。
相关文章:

【软件测试】学习笔记-网站可扩展性架构设计
可扩展性,指的是网站的架构设计能够快速适应需求的变化,当需要增加新的功能实现时,对原有架构不需要做修改或者做很少的修改就能够快速实现新的业务需求。 从这个定义中,我们很容易就可以得出衡量网站可扩展性设计优秀与否的主要标…...

深度学习常用代码总结(k-means, NMS)
目录 一、k-means 算法 二、NMS 一、k-means 算法 k-means 是一种无监督聚类算法,常用的聚类算法还有 DBSCAN。k-means 由于其原理简单,可解释强,实现方便,收敛速度快,在数据挖掘、数据分析、异常检测、模式识别、金…...
数据结构·顺序表应用
本节应用是要用顺序表实现一个通讯录,收录联系人的姓名、性别、电话号码、住址、年龄 顺序表的实现在上一节中已经完成了,本节的任务其实就是应用上节写出来的代码的那些接口函数功能,做出来一个好看的,可…...

第一个 OpenGL 程序:旋转的立方体(VS2022 / MFC)
文章目录 OpenGL API开发环境在 MFC 中使用 OpenGL初始化 OpenGL绘制图形重置视口大小 创建 MFC 对话框项目添加 OpenGL 头文件和库文件初始化 OpenGL画一个正方形OpenGL 坐标系改变默认颜色 重置视口大小绘制立方体使用箭头按键旋转立方体深度测试添加纹理应用纹理换一个纹理 …...

剩余银饰的重量 - 华为OD统一考试
OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 有N块二手市场收集的银饰,每块银饰的重量都是正整数,收集到的银饰会被熔化用于打造新的饰品。 每一回合,从中选出三块 最重的…...

redis远程连接不上解决办法
问题描述: redis远程服务端运行在192.168.3.90计算机上,客户端计算机(ip:192.168.3.110)通过redsi-cli.exe客户端工具连接时,没有反应,连接不上。 如图所示: 解决步骤: 步骤一&…...

利用Anaconda安装pytorch和paddle深度学习环境+pycharm安装后不能调用pytorch和paddlepaddle框架
问题现象: 之前安装后不能在添加pytorch和paddlepaddle框架 原因(疑似): 在终端中显示pytorch和paddle在C盘但是安装是安装在J盘 解决办法: 卸载、删除文件重新安装后可以看到文件位置在J盘中 但是选择时还是显示C…...

Eclipses安装教程
一、下载开发工具包 1、开发工具包JDK 下载地址链接:https://www.oracle.com/cn/java/technologies/downloads/ 下载教程: 1)点击链接,可以跳转到页面 2)下滑页面,找到开发工具包 3) 记住下载之…...
安装python版opencv的一些问题
安装python版opencv的一些问题 OpenCV是知名的开源计算机视觉算法库,提供了C\Python\Java版共享库。 在Python中使用OpenCV格外简单,一句命令就能安装,一行import就能引入,可谓是神器。然而,在实际使用中可能遇到一些…...

RabbitMQ入门实战
RabbitMQ 是一个开源的消息中间件,实现了高级消息队列协议(AMQP),用于在分布式系统中进行消息传递。它能够在应用之间传递消息,解耦应用组件,提高系统的可伸缩性和可维护性。RabbitMQ 使用高级消息队列协议…...

vue3-模版引用ref
1. 介绍 概念:通过 ref标识 获取真实的 dom对象或者组件实例对象 2. 基本使用 实现步骤: 调用ref函数生成一个ref对象 通过ref标识绑定ref对象到标签 代码如下: 父组件: <script setup> import { onMounted, ref } …...
C# 十大排序算法
以下是常见的十大排序算法(按照学习和实现的顺序排列): 冒泡排序(Bubble Sort)选择排序(Selection Sort)插入排序(Insertion Sort)希尔排序(Shell Sort&…...

面试之Glide如何绑定Activity的生命周期
Glide绑定Activity生命周期 Glide.with() 下面都是它的重载方法,Context,Activity,FragmentActivity, Fragment, android.app.Fragment fragment,View都可以作为他的参数,内容大同小异,都是先getRetriever࿰…...

从 fatal 错误到 sync.Map:Go中 Map 的并发策略
为什么 Go 语言在多个 goroutine 同时访问和修改同一个 map 时,会报出 fatal 错误而不是 panic?我们该如何应对 map 的数据竞争问题呢? 这篇文章将带你一步步了解背后的原理,并引出解决 map 并发问题的方案。 Map 数据竞争 首先…...
Simon算法详解
0.0 Intro 相关的算法: Deutsh-Jozsa算法: 第一个量子算法对经典算法取得指数级加速的算法 美中不足在于只能确定函数是平衡的还是非平衡的,无法确定函数具体的内容,即无法直接解出函数 Bernstein-Vazirani算法ÿ…...

jrebel IDEA 热部署
1 下载 2022.4.1 JRebel and XRebel - IntelliJ IDEs Plugin | Marketplace 2 选择下载好的zip 离线安装IDEA 插件 重启IDEA 3 打开 [Preference -> JRebel & XRebel] 菜单,输入 GUID address 为 https://jrebel.qekang.com/1e67ec1b-122f-4708-87d…...
pdf拆分成各个小pdf的方法
背景:由于某些缘故,一个大的pdf需要拆分成页数少的pdf,或者pdf需要去掉指定页,那么就有必要对pdf进行重新编辑,这里需要用到一个库,直接进行操作即可。 当使用Python时,可以使用PyMuPDF库来拆分PDF文件。以下是一个示例代码, import fitz # PyMuPDF def split_pdf(i…...

IntelliJ IDEA 常用快捷键一览表(通用型,提高编写速度,类结构、查找和查看源码,替换与关闭,调整格式)
文章目录 IntelliJ IDEA 常用快捷键一览表1-IDEA的日常快捷键第1组:通用型第2组:提高编写速度(上)第3组:提高编写速度(下)第4组:类结构、查找和查看源码第5组:查找、替换…...

MSVS C# Matlab的混合编程系列2 - 构建一个复杂(含多个M文件)的动态库:
前言: 本节我们尝试将一个有很多函数和文件的Matlab算法文件集成到C#的项目里面。 本文缩语: MT = Matlab 问题提出: 1 我们有一个比较复杂的Matlab文件: 这个MATLAB的算法,写了很多的算法函数在其他的M文件里面,这样,前面博客的方法就不够用了。会报错: 解决办法如下…...

上位机图像处理和嵌入式模块部署(qt图像处理)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 很多人一想到图像处理,本能的第一反应就是opencv,这也没有错。但是呢,这里面还是有一个问题的,不知…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

网页端 js 读取发票里的二维码信息(图片和PDF格式)
起因 为了实现在报销流程中,发票不能重用的限制,发票上传后,希望能读出发票号,并记录发票号已用,下次不再可用于报销。 基于上面的需求,研究了OCR 的方式和读PDF的方式,实际是可行的ÿ…...