<audio id="audio" title="48 | 优秀的测试工程师为什么要懂大型网站的架构设计？" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/7f/81/7f0515c5e496f2fcaf6b6cf391402281.mp3"></audio>

你好，我是茹炳晟。今天我和你分享的主题是：优秀的测试工程师为什么要懂大型网站的架构设计？

上周我准备了两期答疑文章，希望可以帮助你解决在阅读前11篇文章时的一些疑问。今天，我们一起回到正题上来，讨论一下互联网的架构设计这个话题。

在这个话题里，我会和你分享测试工程师为什么要具备架构知识、怎么学架构知识，以及学到什么程度就可以了。同时，我会针对网站架构设计中最关键的四个主题：高性能架构设计、高可用架构设计、伸缩性架构设计，以及可扩展性架构设计，和你分享一些案例，让你切实体会到懂得架构知识在测试范围确定和用例设计等方面的重要性。

## 为什么要懂得网站的架构设计？

其实，如果你是工作在传统软件企业的工程师的话，网站的架构设计知识对你来说可能没那么重要。因为，你的测试对象是传统软件，此时你需要对你的被测软件的架构有比较深入的理解。

而现在如你所知，互联网企业已经占据软件产品的大半壁江山。如果你想跳出传统软件产品测试这个舒适区的话，那互联网企业将是一个最可能的去向。

而在互联网企业进行软件测试的话，很多时候需要针对互联网的架构来设计有针对性的测试，另外对于互联网的压力测试以及结果分析也需要对架构知识有比较清楚的认识。这时，不懂得网站架构设计知识，在开展测试时，就真的会有处处被掣肘的感觉了。更别提，这还会直接影响到你的能力提升和职业发展了。

在测试过程中，你可能会经常遇到诸如负载均衡器、缓存集群、数据库读写分离、消息队列、CDN、反向代理服务器和分布式数据库等概念，在测试执行中也经常会和这些系统打交道。但是，很多时候，你只是知道网站在架构设计上有这些组件，并不清楚这些组件真正的作用，在对应的测试设计时也很难做到“有的放矢”。

还有些时候，特别是性能测试，如果你不清楚详细的架构设计以及其中的技术细节，你可能根本无去解读和分析性能测试的报告。

我来举两个实际的例子吧。

### 基于消息队列的分布式系统测试设计的例子

在分布式系统的架构中，为了减少各个应用系统之间的直接耦合，往往会引入消息队列来实现解耦。

也就是说原本的功能实现是由系统A调用系统B来完成业务功能的，而引入了消息队列后，系统A不会再直接去调用系统B，而是将调用B所需要的数据放到了消息队列中，此时我们将系统A称为消息的生产者，然后系统B通过监听该消息队列，主动从消息队列中依次抓取数据进行系统B的处理，系统B在这种情况下称为消息的消费者。

通过这种方式，就完成了系统A和系统B之间的调用解耦。

那么，我们再来看测试的设计。测试用例的设计可以站在黑盒测试的视角，完全不需要知道消息队列的存在，而直接从业务功能的层面去设计用例。

但如果只这么做的话，你会发现虽然你的测试全部通过了，但是产品一旦到了线上，还可能会出现很多问题。

比如说，消息的生产者产生消息的速度远远大于消息消费者处理消息的速度时，很可能会造成消息队列满的情况，此时系统的行为是怎么样的？

显然仅仅通过黑盒测试很难完成系统性的、全面的测试。要做到系统性全面的测试设计，你就必须知道消息队列的基本原理，然后在此基础上去设计针对具体架构的测试用例和场景。

另外，既然我们的系统设计希望是解耦的，那么我们的测试设计也希望是解耦的。也就是说，对于一些更详细的测试，我们希望系统A和系统B可以被单独的进行测试。

那么，这个时候，如果是对系统A进行测试的话，你的测试验证就需要在消息队列中进行。同样的道理，如果你是对系统B进行测试的话，你就需要在消息队列中构造测试输入数据了。

由此可见，如果你不知道消息队列的存在以及其基本原理的话，你的测试将寸步难行。

### 缓存的例子

很多时候，在我们搭建完性能测试的基准环境，开始执行性能基准测试的时候，往往会发现系统刚开始运行时业务处理的响应时间都会相对比较长，只有当性能测试执行了一段时间后，系统的各项指标以及事务的响应时间才逐渐趋于正常。

为此，在做性能基准测试的时候，有经验的工程师通常都会先用性能场景对系统进行一下“预热”，然后再真正开始测试。你有想过这其中的原因吗？

另外，在做前端性能测试的时候，我们对于一个页面的打开时间通常会去统计两个指标，一个是首次打开时间，另一个是多次打开的时间。而且，通常来讲首次打开时间会远大于后面再次打开的时间。你有想过这其中的原因吗？

其实，造成上述两种情况的背后原因都是采用了缓存技术。

造成第一个情况的原因，是服务器端会对“热点”数据进行缓存，而不是每次访问都直接从数据库中获取数据。那么，系统刚开始运行时，由于没有任何之前的访问记录，所有数据都需要访问数据库，所以前期的事务响应时间都会比较长。但是，随着缓存的建立，后续的访问就会比较快了。这个前期对系统的“预热”过程其实是在“预热”缓存。

对于第二种情况也是同样的道理。浏览器端也会缓存从服务器端拿到各种静态资源，在第一次访问时这些资源都需要从服务器端获取，而后面再访问时，这些静态资源已经在浏览器的缓存中了，所以访问速度会大大加快。

由此可见，如果不知道缓存的存在、不理解缓存的基本原理，你就不可能从根本上理解性能测试的方法设计以及测试结果数据。

其实，对于缓存还有很多需要考虑的测试点，但是需要解释这些测试点就需要深入理解缓存的原理以及缓存的架构设计，因为在互联网环境下，缓存本身也是分层的，浏览器端有本地缓存、网络端有CDN缓存、数据中心前端有反向代理的缓存、应用服务器端有本地缓存，对于大规模互联网应用更有大规模的专用缓存服务器集群。所以，要有针对性的设计缓存相关的测试场景，就需要理解这些缓存的架构。

那么，接下来我就和你聊聊作为测试工程师应该怎么学习架构知识。

## 测试工程师怎么学架构知识？

其实，对于测试工程师来说，学习软件架构和系统架构知识的确是个不小的挑战。因为很多架构知识都是基于开发框架和系统设计的，对开发工程师来说，已经是个不小的挑战，对测试工程师来说更是一个难以驾驭的领域。

不过好在，同样是对架构知识的学习和掌握，不同角色的工程技术人员都有不同的视角，需要了解和掌握的全局知识和细节程度也各不相同。以消息队列知识为例：

- 如果你是系统架构师，那么你就不仅要掌握各个不同消息队列实现的技术细节，还清楚不同方案的优势和劣势，最关键的是能够根据业务的应用场景和特点来选择最合适的消息队列方案。
- 如果你是软件开发人员，那么你就需要掌握消息队列的使用方法、消息push和pull的模式，以及在应用中如何以异步方式来对消息进行妥善处理，并且还要考虑到异常场景的处理。
- 而作为软件测试人员，你需要知道消息队列的基本原理以及在被测系统中的部署情况，同时应该知道如何访问消息队列或者队列中消息的情况。在需要模拟消息进行解耦测试的场合，你还需要知道如何添加测试消息以满足测试的目的。

可见，对于测试人员来讲，学习架构知识应该有自己独特的视角，基本只要做到清楚原理、了解在被测系统中的部署架构，从测试的角度能够调用必要的接口就可以了。

那么，我们到底应该怎么来学习架构知识呢？根据我的个人经验，我认为应该遵循“由广度到深度”和“自上而下”两个基本原则。

**“由广度到深度”中的“广度”是指在平时工作以外的时间中，应该多注重全领域架构知识的积累，此时那些系统性地介绍架构知识的书籍或者专栏就可以给你最大程度的帮助了。**

因为这类资料往往已经对纷繁复杂的架构知识做了系统性地梳理。这里，我个人非常推荐极客时间李运华老师的“从0开始学架构”专栏，以及李智慧老师所著的图书《大型网站技术架构：核心原理与案例分析》。它们都能帮你从广度上积累架构知识。

**“由广度到深度”的“深度”是指，对于架构中某一领域的特定知识在项目中要实际使用的时候，必须要刨根问底，通过实际的测试来加深对架构知识细节的理解。**

**“自上而下”是指，在实际测试项目中，当需要设计涉及架构的测试用例和场景的时候，千万不要直接基于“点”来设计测试，而是应该：首先通过全局阅读理解上层架构设计；然后，在理解了架构设计的初衷和希望达成目的的基础上，再向下设计测试场景和用例。**

这个过程，一方面可以帮你设计出有针对性的测试用例，另一方面可以帮助你理解架构在实际项目中是如何落地的。

随着你经历的项目越来越多，你的架构知识就会逐渐充实丰满起来。这就好比你在走一个旋转楼梯，一直感觉自己在原地打转，但是不知不觉走了一段时间后你回头往下看的时候，就会发现已经站在了比原来更高的点上。

最后，我再特别提一下，对于架构知识的学习没有任何捷径可走，你必须一步一个脚印，才能达到下一个高峰。

## 总结

今天我通过消息队列和缓存两个实例给你讲解了测试工程师学习架构知识的重要性，并且从我个人的经验出发，提出了“由广度到深度”和“自上而下”的架构学习思路，最后指出了学习架构没有捷径，你必须一步一个脚印夯实自己的知识结构。

## 思考题

对于架构知识的学习，我只是给出了我的一些方法和意见，你对此还有什么其他的想法或者学习方法吗？

感谢你的收听，欢迎你给我留言。


