编者注:本文为 CSDN 博主 smooth-z 的原创文章。
原文链接:
https://blog.csdn.net/smooth00/article/details/123863730
目前 JMeter 在接口测试和性能测试的市场占用率很高,最大的原因是其开源性、易扩展和轻量级(这是 LoadRunner 所不具备的),同时 JMeter 还可以满足多种协议的接口和性能测试(这是其他开源工具不具备的)。
而 MeterSphere 是一款基于 JMeter 引擎技术的软件测试平台,不考虑轻量级因素,基本上是可以替代 JMeter 的,并且更易于线上测试工作的开展(包括在线管理用例、在线编辑脚本和调试脚本,在线压测和在线分析报告等)。
MeterSphere 的分布式架构优势
JMeter 虽然灵活轻巧,但是基于其线下工具的特点,无法进行系统化和平台化的管理和运行。同时,JMeter 的单机模式在一般的压力机配置下,会受限于 JMeter 自身的机制和硬件配置,最多可以支持几百至一千左右的模拟请求线程。而开展大量的分布式 Slave 部署,会带来运维管理方面的困难。同时,JMeter 的主从(Master-Slave)模式,还会给主节点带来很大的交互压力,没人能做到部署大规模的分布式集群压测。
■ JMeter 的分布式结构分析
我们分析这个结构图会得出以下的结论:
从主节点调度和传输数据,依赖于稳定的端口,其中 server.rmi.localport 和 client.rmi.localport 端口默认是随机的(也可以设置成如上图固定的),server_port 端口一般固定为 1099,只要防火墙没有放行(如果是随机端口就要求关闭防火墙),Master-Slave 主从分布式模式就会调度失败;
主节点发送给从节点的数据相对较少,因为除了主从调度和数据同步外,每个从节点作为独立的压力机,自行负责自己那部分请求发送和接收。但是,从节点发送给主节点的测试结果数据一般会比较大,遇到大量的从节点时,对主节点(主控机)的压力就会很大,容易出现瓶颈;
每启动一个从节点(Agent),基本上 Server_Port 端口就被占用了,而且只能进行单任务压测,就算一个任务结束了,进程还在端口就不会释放,属于资源独占型;
主从方案部署繁琐,除了考虑端口因素,还要考虑版本一致性,插件依赖包一致性。其中一个节点崩溃,就可能导致整个压测任务失败(因为要保证调度和主从数据的一致性);
如果 JMeter 压测的 CSV 需要每个节点(Agent 压测机)读取的数据不一样,则需要人为提前进行切分、裁剪和放置,因为主从控制没有文件远程传输和同步机制;
如果从节点硬件性能差别过大,也没法控制不同节点的压力分配来减轻某些节点的压力。因为节点机 Agent 只有发压功能,没有差异控制功能,线程设置为多大,每个节点就都复用一样的配置;
另外,JMeter 在 GUI 模式下通过第三方插件可以查看实时压测报告(性能较差,一般不采用),No-GUI 模式下只能生成结果报告。目前一种常见的方式是,通过后端监听器向 InfluxDB 发送结果数据,采用 Grafana 进行实时展示,但这种方式在大规模压测下 InfluxDB 也会崩溃,除非是 InfluxDB 集群(集群版的未开源);
JMeter 默认是不支持性能监控的,只能是在 GUI 模式下,通过扩展监听器插件(例如 PerfMon Metrics Collector)来实现,但也只能监听到 CPU、内存、网络这样的基础指标,可扩展性有限。另外从性能上考虑,也非常不合理,本来 Master 节点压力就大,再加上监控数据的汇集,性能就更差了,所以除了采用独立部署的性能监控平台,没有别的办法。
■ MeterSphere 的分布式架构分析
我们分析以上架构图会得出结论:
MeterSphere 基于 Docker 技术,易于分布式集群的部署,如果配合 Kubernetes 就更易于扩展部署节点(进阶版),也易于云部署;
MeterSphere 没有采用传统的 JMeter Slave(Agent 分压器)方式去扩展节点,而是每个节点都是独立的 JMeter Master。这种模式的好处是,不需要通过 Server_Port 端口来构建主从连接,每个节点就是个 Docker 版的 JMeter 进程,由 NodeController 控制,用完即停(通过 Docker 启动和注销);
测试结果和报告再也不用通过 Slave 向 Master 汇集,而是各压测节点通过 JMeter-Kafka 监听类组件向 Kafka 回传测试结果数据,避免了主从模式下的 Master 汇集压力。而且,Kafka 还可以考虑集群化部署,这在性能上就可以满足大数据量的吞吐压力;
MeterSphere 将传给 Kafka 的结果数据采用 DataStreaming 进行收集和计算,并写入 MySQL 数据库,这确保了在生成实时报告及汇总报告上的性能。我们都知道 JMeter 生成报告的性能一直比较差,特别是长时间压测写入了大量结果数据到文件中,想顺利转换成 HTML 报告几乎不可能;
MeterSphere 基于界面化的设置性能压测参数(并发、时间、梯度、压测资源池、文件切分等),并通过资源池管理节点资源,根据资源池分发压测脚本和文件到指定的节点,自动启动 Docker JMeter 完成压测;
测试用例(接口)、测试场景(脚本)全都入库保存和管理,测试数据、测试结果和报告也是入库保存和管理,方便后续分析、分享和比对;
性能监控上支持扩展 Prometheus,如配置了相关的 Prometheus 监控,MeterSphere 在压测的同时会自动收集被压测端系统的性能监控数据。
MeterSphere 的 Web 平台化优势
JMeter 虽然受到很多人推崇,但作为一款测试小工具,无法进行测试脚本管理、无法在线规划测试场景、无法多人实时查看测试过程和测试结果。总之,不方便基于团队的方式开展接口测试和性能测试工作,更别提是基于项目的迭代实时进行持续测试了。
另外,长期做过性能测试的都知道,接口测试和性能测试是有一定相关性的,比如性能测试的混合测试场景就是一些接口的组合,完全可以把测试通过的接口直接引用过来,就不需要重新定义和编辑了。同样,性能测试的场景规划也完全可以前移到接口测试阶段进行,而不至于到性能测试执行阶段了才开始准备测试脚本。这些事对于 Web 平台系统来说再平常不过了,但对于 JMeter 来说就不具备这样的管理方便性。
MeterSphere 可以说解决了我们上面所提到问题,即完全在线运行和管理,相当于将 JMeter 由线下搬到了线上。
当然,这样一定会有人问,能在线编辑和调试测试脚本吗?毕竟很多基于 JMeter 的开源测试平台,在线压测一般都没问题,但是要在线编辑脚本就有点困难。因为要在 Web 端做一套和 JMeter 一样灵活的脚本编辑工具可没那么容易。这一点 MeterSphere 做得挺不错,并且相信未来还会从 JMeter 身上吸收更多的优点。
我们先来看看 MeterSphere 基于 Web 界面的接口定义和编辑开发能力:
① 创建接口
目前支持创建接口包括 HTTP、TCP、SQL、DUBBO,类型上还是偏少,比如还没支持 WebSocket(接口配置没有该功能,但性能测试可以通过上传 JMX 脚本和 WebSocket 相关依赖 Jar 包来实现)。
对于接触过 JMeter 或 Postman 的人来说,在上面创建接口操作起来相对容易,因为很多要素是一样的。更让人惊喜的是可以同步创建 Mock 服务,只要在 Mock 设置中配置上期望请求条件和期望响应内容,Mock 服务就生效了,易用性上没的说了。
另外我们创建的接口除了能 Mock 化,还能文档化(相当于 Swagger 化),这点也挺棒。
② 导入外部接口
支持导入多种格式的接口文件,目前 HTTP 协议支持 Postman、Swagger、JMeter,所支持的接口工具相较其他接口测试平台涵盖更为广泛。
以 JMeter 的脚本为例,导进来后,基本要素和 JMeter 一样,就是前置处理器、后置处理器、断言等都没了。不过没关系,可以进入 Case 或是在自动化接口场景模式上追加。例如,在后置处理操作中添加正则表达式提取 Cookie 参数。
然后可以执行调试。来看我们提取的效果:
可以看到,这个正则表达式(如果响应体是 JSON 格式,除了正则,推荐用 JSONPath 提取,那样更方便精准,我这里提取的是响应头的 Cookie,所以用正则)提取的是三个值的数组。我们只要取第二个值,作为我们的 Cookie 参数,那么直接引用变量 ${cookie_2}就可以了。是不是和 JMeter 上的操作类似?所以我就说会使用 JMeter 的,接受 MeterSphere 是很容易的(本来就是一套玩法)。把这个 Cookie 引用到后面接口的请求头即可。
注明:其实导入外部接口的功能还有另外一种现实意义。就是我们可以用其他工具,比如 Postman、JMeter 代理录制、Chrome 录制插件等工具去录制接口脚本,然后导入 MeterSphere。这为性能测试场景的构建提供了辅助手段,能给喜欢录制的小伙伴带来很大帮助。
为什么很多人愿意使用 JMeter 来做接口测试?除了它支持的协议多以外,最主要是容易进行场景化的编排。比如我登录后,获取 Token 再传给查询接口,然后在查询接口进行查询,查询到结果,传给操作接口进行修改或删除操作。这样的场景化就是业务特性,要求接口按先后顺序编排,彼此还要参数关联。而这样的场景化接口编排后,是可以很方便地直接引用到后期的性能测试场景的。所以接口场景化很重要,这一点 MeterSphere 也做得不错(毕竟是基于 JMeter 的技术)。
对于 JMeter 技术理解比较深的话,了解和使用 MeterSphere 是有帮助的。特别是接口自动化场景和性能测试场景,基本上属于技术同源。
X1~X5:是负载模拟的一个过程,使用这些组件来完成负载的模拟;
X1:选择协议,模拟用户请求,检查服务响应是否正确,并收集结果信息,属于 API 定义部分;
X2:完善测试脚本部分,包括参数化,关联等,属于 Case 定义部分;
X3:控制测试脚本业务逻辑,属于业务场景定义部分;
X4:集合点,模拟用户并发,这属于性能测试涉及的内容;
X5:用户数,一个线程代表一个用户,调试接口一般单线程,性能测试就会用多线程;
Y1:可以理解为选择协议,包含负载模拟部分,负责模拟用户请求;
Y2:可以理解为检查点,结果验证部分,负责验证结果正确性,属于接口 Case 定义部分;
Z:可以理解为监控器,负责结果的收集,对于 JMeter 来说监听器不仅可以放在线程组之内,也可以放在线程组之外;
对于 MeterSphere 平台来说,无论接口测试,还是性能测试,都离不开以上要素结构。只是像监听器已经做到了高度集成,在平台里已融合到报告或监控中了,所以没有直观体现。
① 创建场景
我们可以创建个场景,然后从上面定义好的接口,直接复制添加(从接口列表导入)过来。
除了导入过来的接口,我们也可以在场景下直接添加新的接口。同样也可像 JMeter 一样,添加事务控制器、循环控制器、条件控制器、自定义脚本(BeanShell、Python 等),如以下添加随机生成身份证号码的脚本:
可以说这个接口自动化场景编辑的功能还是很强大的,对于我一个擅长 JMeter 的测试人员来说,可以无缝接受。
② 导入脚本场景
我尝试把 JMeter 脚本导入后,发现连线程组、事务和各 JMeter 元件都一起导入了,具体如下:
很多元件目前是界面上不支持展现,但会以 XML 形式展现,可以编辑 XML,比如 Cookie 管理器。
说到 Cookie 管理,可以用 JMeter 自带的 HTTP Cookie 管理器(MeterSphere 界面目前没有提供这个元件,导入的显示为 XML),也可以用我上面提到的正则表达式提取的方式,然后添加到其他接口请求头中(类似于 Token 处理方式)。
当然,MeterSphere 也有自己的方式,就是 Cookie 共享。勾选了这个选项,其实就相当于是用了 JMeter 中的 Cookie 管理器的 Cookie 保存。
无论是新建场景,还是导入场景,其实 MeterSphere 做得已经很出色了,基本上吸收了 JMeter 的很多特性。同时,从扩展性上看,MeterSphere 还可以继续扩展 JMeter 的一些元件。从开源的二次开发角度来说,我觉得难度应该不大。
③ 变量和参数化
关于参数化,主要有上面提到的关联提取方式。目前支持正则、JSONPath、XPath 这些表达式,基本上也够用了。
至于全局变量可以在项目环境配置中去配置。配置方式很灵活,可以直接添加变量,也可以在全局前置脚本中添加脚本产生变量。
从文件中导入变量,跟 JMeter 中的 CSV 数据文件设置类似,在场景编辑页面上方有场景变量链接,设置界面如下:
④ 定时任务
接口自动化场景,肯定要有自动执行的功能,所以 MeterSphere 也提供了定时任务和任务通知的功能,可以满足定时执行接口场景的需要。
这个定时任务用的是 Cron 表达式。说实在的很多人不知道怎么配置,建议加个 Cron 配置器功能,比如下图这样的(当然这只是辅助功能,还是需要自己了解清晰什么是 Cron):
对于任务通知,功能也是非常简单,简单到可能很多人也不知道怎么用了,具体如下:
这里的任务通知,一般就是邮件或钉钉通知用得多。可能很多人不知道 WebHook,其实就是触发事件后向对方(第三方)的 URL 接口发送一条消息,比如钉钉我们可以这样获取 WebHook:
在钉钉群聊中,通过 “群设置”→“智能群助手”→“添加机器人 ”→选择 “自定义” 机器人。为机器人设置一个头像和名称,点击 “添加” 按钮后可以获得一个 WebHook 地址,点击 “完成” 按钮即可完成钉钉机器人的添加。
说到定时任务,我们不得不提一下持续构建。一般接口测试在执行持续构建场景中会用到定时测试任务,或是触发测试任务,比如提交和发布一版新包后,就要立即开始接口回归测试。
其实在这一块 MeterSphere 是有 Jenkins 插件提供的(https://github.com/metersphere/jenkins-plugin ),我们可以把插件安装到 Jenkins,就可以调度 MeterSphere 的接口任务。这都算是隐蔽的功能,很多人可能不知道,可以自行上网搜索了解一下。
MeterSphere 相较于 JMeter 的最大优势就是性能测试过程完全通过 Web 界面操作,包括脚本的上传和管理、参数化及资源文件的上传管理、压测在线配置、压测过程实时查看、压力机的性能监控、性能测试结果及报告管理,这些都是单机化的 JMeter 所不具备的。
① 测试资源
MeterSphere 比较好的地方,就是通过资源池来管理测试资源。而且一个资源池可以创建多个压测节点,这里的每个节点不是 JMeter 传统理解的 Slave(比如端口绑定 1099 的代理节点),而是关联一个新的 JMeter Master 进程。这个进程就是通过 Docker 镜像在压测时动态创建容器,压测完后就自动消亡释放压测资源。
以下是一个资源池创建两个节点的示例:
每个节点控制器 NodeController 负责创建和消亡 JMeter Master 容器。NodeController 也是个容器,所对应的默认端口为 8082,docker ps | grep node-controller 结果如下:
ONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d8cbeab1861 registry.cn-qingdao.aliyuncs.com/metersphere/ms-node-controller:v1.19.0 "/deployments/run-ja…" 4 days ago Up 4 days (healthy) 0.0.0.0:8082->8082/tcp, 0.0.0.0:9100->9100/tcp ms-node-controller
② 性能监控
MeterSphere 的节点部署模式(安装时 install.conf 配置 MS_INSTALL_MODE=node-controller),启动后会看到三个相关容器。其中,JMeter Master 容器是动态的(压测完就消亡)。另外两个固定的,一个是上面提到 NodeController,一个是 Node Exporter。
很多人不知道 Node Exporter 的作用,其实它是个性能监控采集器,相当于 Prometheus 监控平台中的 Node Exporter。有了它我们压测完后,在报告中是能看到采集到的压力节点性能监控数据。
上面的监控采集数据,基本上和 Prometheus 是一样的。可以肯定的是,MeterSphere 对其做了一些集成,既然通过 Node Exporter 能支持 Linux 性能指标的采集,那么我们除了监控压力节点机,我们还可以监控被测服务器。通过 “性能测试”→“测试”→“高级配置”→“监控”,添加我们需要监控的服务器:
上面的方式可以按 Prometheus 的 PromQL 语法自定义监控指标。那么毫无疑问,我们还可以按一般 Prometheus 的方式去扩展其他服务的监控,比如 MySQL、PostgreSQL 的监控等。只需要在被监控机器上部署相应的采集器,比如 MySQL Exporter、Postgres_Exporter、JMX Exporter 等。真正懂性能测试和性能监控的人应该都不难理解这方面的扩展需求,监控关系示意图如下:
③ 加载测试脚本
主要包括两种方式,一种是 JMX 文件(包括新上传的脚本或引用平台上已有的脚本),一种是引用上面提到的接口自动化场景(这也是平台化管理的优势)。
从本质上来说,上面提到的接口自动化过程,就是一个 JMeter 脚本化的过程。最终压测调用的是 JMX 文件(会分发到各个节点),所以性能测试加载脚本和接口场景配置就是一个相通相关的过程。
④ 压力配置
基于界面的压力配置,比 JMeter 要简单直观。目前支持两种线程组发压模式,一种是 ThreadGroup 线性递增发压,一种是 ConcurrencyThreadGroup 阶梯递增发压。
从配置上来说,支持选择资源池(每个资源池可能对应多个压测节点),支持多场景(同时或顺序执行多脚本),除了常规的并发配置项,还包括 RPS(容量限制)配置。
压测可以自定义分配不同节点的压力配比(不同机器性能不一样,有时候要区别对待)。
对于参数化文件,还支持 CSVDataSet 拆分(在高级配置中),可以按照分节点分隔压测数据。这是 JMeter 默认不具备的功能,但是在业务场景中经常需要的功能。配置页面如下:
对于我来说,目前 MeterSphere 不支持动态调整 TPS/RPS,这点挺不方便的。因为有时候长时间压测,需要继续加压时,我们是不希望中断测试的,希望能够动态加压。
⑤ 测试报告
MeterSphere 的测试报告算中规中举,但是相对于 JMeter 来说,优势明显。首先是可以实时直观地查看压测情况,最关注的 TPS、RT 指标、请求统计、错误记录都清晰明了。
JMeter 如果没有引入第三方插件的话,是不能直观地查看压力变化情况的。当然 JMeter 测试结束后,导出的 HTML 报告也很详细。这点来说,MeterSphere 有点不足,不过不影响我们的测试活动,毕竟最关注的指标也就这些,如果需要更多的报告视图,完全可以基于开源扩展开发。
MeterSphere 的测试报告示例如下:
另外 MeterSphere 还有一个亮点,就是报告对比功能。我们可以把多轮测试的报告进行对比,比如比较 TPS 的提升情况,能清楚地说明性能的提升。
MeterSphere 的扩展性优势
JMeter 的最大优势是开源性,MeterSphere 的最大优势也是其开源性。MeterSphere 的另一个优势就是它是基于 JMeter 技术的。
JMeter 最大的优势是支持多种协议的测试。这方面除了 LoadRunner 应该找不到第三款测试工具了吧?互联网大厂自己的工具不算,毕竟外人也不能免费享用。
所以,MeterSphere 的最大优势是基于 JMeter 去扩展各种协议接口的测试,比如 WebSocket 的测试。默认 JMeter 是不支持 WebSocket 的,但是可以扩展第三方的插件获得支持。对于 MeterSphere 来说,我们也是同样的思路,我们可以把 WebSocket 第三方插件依赖 Jar 包全部上传,这样就能支持 WebSocket 协议脚本的压测了。
上面的依赖包一次上传后,就可以直接在同一个项目中引用了,调测的效果如下:
所以 MeterSphere 基本上可以做到支持 JMeter 所支持的所有协议和接口,就看个人怎么去配置和使用了。另外,MeterSphere 也是基于 Java 的开源平台,我们可以通过二次开发去获得更多的扩展。
① 监控方面可以扩展 Prometheus,而 Prometheus 是开源的系统监控平台,相关的说明上面也有提到,具体的应用大家可以自己去 Prometheus 官网获得支持。MeterSphere 的系统设置中有相关的外接配置:
在 UI 测试方面,估计不久也会有相应的扩展,比如扩展 Selenium 的支持和应用。
② MeterSphere 与目前流行的缺陷管理平台也做了相应的连接和集成,比如我们使用禅道比较多,就可以考虑这方面的集成应用,这就是开源扩展的优势。
MeterSphere 目前的不足
对于我个人来说,目前 MeterSphere 的最大不足,是不支持动态 TPS/RPS/线程数的控制。在实际工作中,我们希望在每次压测执行时能够随时调节吞吐量或者动态改变压力的上限值。
场景一:执行线上的一个持续容量测试,如果在某个压力下服务容量没有问题,我们就希望在不停止压测的情况下,再加大一些容量;或者发现压力在某个时间段过大,需要临时降低吞吐量。这时候如果不能动态改变 TPS/RPS,那我们只能停止任务重新开始了;
场景二:在我们无法估算系统的最大 TPS 情况下,会通过不断加大压力(用户数/线程数),来关注 TPS 曲线的变化情况(要求线程数连续不中断的梯度递增,保持同比例关系:TPS*RT=线程数)。如果压力数(用户数)增长,TPS 却不再增长了,可能就是出现性能瓶颈了。但如果这个趋势一直没出现,而压力工具已经压到最大用户数/线程数,那么我们就需要动态改大用户数/线程数,否则测试可能要中断。
以上的两种情况,在一般的测试情况下影响不大,大不了重新开始执行测试。但是如果是在生产环境下测试,或者需要大量前置工作的情况下(准备大量测试数据或复杂的环境初始化工作),任何测试的中断,都意味着工作量的增大,所以压测过程中动态改变压力是很有必要的。
在 JMeter 中动态改变压力,是通过 BeanShellClient 和 BeanShellServer 来实现动态改变参数变量,例如在节点 jmeter.properties 设置 beanshell.server.port 为 9000,通过命令动态改变参数:
java -jar <jmeter_path>/lib/bshclient.jar localhost 9000 update.bsh <参数>
目前基于 MeterSphere 进行这方面的改造有困难,一方面是开启 beanshell.server.port 就打破了原有 JMeter-Master 无需端口调用的优势(前面说到的优点);另外 JMeter 只支持 DynamicThread 动态线程技术的 ConcurrencyThreadGroup、ArrivalsThreadGroup 线程组和 Constant Throughput Timer 吞吐量定时器等进行动态改变参数变量,适用性上有限。但是,还是希望 MeterSphere 的工程师们能找到最佳的方案解决这个问题,哪怕是折中的方式通过外部手动配置也行。
关于 JMeter 动态压力的相关技术可以关注我的另一篇文章《JMeter 动态吞吐量实现》:https://blog.csdn.net/smooth00/article/details/121655220?spm=1001.2014.3001.5501
当然以上的想法不适合所有人,有很多人可能用不到这个功能,盲目做到产品化的 MeterSphere 当中,可能会导致易用性和部署维护上变得糟糕。不过,作为云压测系统重要的一个功能还是尽早考虑考虑。
MeterSphere 组件及资源
■ Frontend:MeterSphere 的前端工程,基于 Vue.js 进行开发;
■ Backend:MeterSphere 的后端工程, 基于 Sprint Boot 进行开发,为 MeterSphere 的功能主体。目前 Frontend 和 Backend 合为一套源码:https://github.com/metersphere/metersphere;
■ Node Controller:为性能测试提供独立节点类型的测试资源池,接收来自系统的性能测试任务,动态地启动 JMeter 容器完成性能测试。源码地址:https://github.com/metersphere/node-controller;
■ MySQL:MeterSphere 项目的主要数据均存储在 MySQL;
■ Kafka:接收 JMeter 产生的性能测试结果数据。JMeter 中用到了 Kafka 监听器插件,源码地址:https://github.com/metersphere/jmeter-backend-listener-kafka;
■ Data Streaming:从 Kafka 中获取性能测试结果数据进行处理后存入 MySQL 数据库。源码地址:https://github.com/metersphere/data-streaming;
■ Docker Engine:为 Node Controller 提供 JMeter Master 容器运行环境。镜像构建文件:https://github.com/metersphere/jmeter-image;
■ Chrome Plugin:浏览器插件,录制 Web 访问请求生成 JMeter 脚本,并导入到 MeterSphere 中用于接口测试及性能测试。源码地址:https://github.com/metersphere/chrome-extensions;
■ Jenkins Plugin:配套的 Jenkins 插件,在 Jenkins 任务中触发指定的 MeterSphere 平台上的测试任务执行。源码地址:https://github.com/metersphere/jenkins-plugin;
■ helm-chart:用于部署 MeterSphere Kubernetes 环境的 Helm Chart,源文件:https://github.com/metersphere/helm-chart;
■ 其他组件:可以到 MeterSphere 仓库中找,地址为:https://github.com/orgs/metersphere/repositories;
■ MeterSphere 的 Docker 镜像地址:https://hub.docker.com/u/metersphere。
写到这,发现自己写的很多了,就不再多说了。其实对于测试或技术工作来说,最重要的要素是人,其次才是工具。毕竟工具是死的,人是活的,再好的工具也得有懂它的人才能发挥价值,也只有人才能促进工具往好的方向演进。
MeterSphere 开源代码地址:https://github.com/metersphere/
————————————————
版权声明:本文为 CSDN 博主「smooth-z」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/smooth00/article/details/123863730