详尽的文档和测试用例

没错,文档和测试是判断开源项目是否靠谱的关键指标,甚至是排在代码质量和性能之前的。
OpenResty 的文档非常详细,作者把每一个需要注意的点都写在了文档中。绝大部分时候,我们只需要仔细查看文档,就能解决遇到的问题,而不用谷歌搜索或者是跟踪到源码中。为了方便起见,OpenResty 还自带了一个命令行工具restydoc,专门用来帮助你通过 shell 查看文档,避免编码过程被打断。
不过,文档中只会有一两个通用的代码片段,并没有完整和复杂的示例,到哪里可以找到这样的例子呢?
对于 OpenResty 来说,自然是/t目录,它里面就是所有的测试案例。每一个测试案例都包含完整的 NGINX 配置和 Lua 代码,以及测试的输入数据和预期的输出数据。不过,OpenResty 使用的测试框架,与其他断言风格的测试框架完全不同,后面我会用专门章节来做介绍。

同步非阻塞

协程,是很多脚本语言为了提升性能,在近几年新增的特性。但它们实现得并不完美,有些是语法糖,有些还需要显式的关键字声明。
OpenResty 则没有历史包袱,在诞生之初就支持了协程,并基于此实现了同步非阻塞的编程模式。这一点是很重要的,毕竟,程序员也是人,代码应该更符合人的思维习惯。显式的回调和异步关键字会打断思路,也给调试带来了困难。
这里我解释一下,什么是同步非阻塞。先说同步,这个很简单,就是按照代码来顺序执行。比如下面这段伪码:

local res, err  = query-mysql(sql)
local value, err = query-redis(key)

在同一请求连接中,如果要等 MySQL 的查询结果返回后,才能继续去查询 Redis,那就是同步;如果不用等 MySQL 的返回,就能继续往下走,去查询 Redis,那就是异步。对于 OpenResty 来说,绝大部分都是同步操作,只有 ngx.timer 这种后台定时器相关的 API,才是异步操作。
再来说说非阻塞,这是一个很容易和“异步”混淆的概念。这里我们说的“阻塞”,特指阻塞操作系统线程。我们继续看上面的例子,假设查询 MySQL 需要 1s 的时间,如果在这 1s 内,操作系统的资源(CPU)是空闲着并傻傻地等待返回,那就是阻塞;如果 CPU 趁机去处理其他连接的请求,那就是非阻塞。非阻塞也是 C10K、C100K 这些高并发能够实现的关键。
同步非阻塞这个概念很重要,建议你仔细琢磨一下。我认为,这一概念最好不要通过类比来理解,因为不恰当的类比,很可能把你搞得更糊涂。
在 OpenResty 中,上面的伪码就可以直接实现同步非阻塞,而不用任何显式的关键字。这里也再次体现了,让开发者用起来更简单,是 OpenResty 的理念之一。

动态

OpenResty 有一个非常大的优势,并且还没有被充分挖掘,就是它的动态
传统的 Web 服务器,比如 NGINX,如果发生任何的变动,都需要你去修改磁盘上的配置文件,然后重新加载才能生效,这也是因为它们并没有提供 API,来控制运行时的行为。所以,在需要频繁变动的微服务领域,NGINX 虽然有多次尝试,但毫无建树。而异军突起的 Envoy, 正是凭着 xDS 这种动态控制的 API,大有对 NGINX 造成降维攻击的威胁。
和 NGINX 、 Envoy 不同的是,OpenResty 是由脚本语言 Lua 来控制逻辑的,而动态,便是 Lua 天生的优势。通过 OpenResty 中 lua-nginx-module 模块中提供的 Lua API,我们可以动态地控制路由、上游、SSL 证书、请求、响应等。甚至更进一步,你可以在不重启 OpenResty 的前提下,修改业务的处理逻辑,并不局限于 OpenResty 提供的 Lua API。
这里有一个很合适的类比,可以帮你理解上面关于动态的说明。你可以把 Web 服务器当做是一个正在高速公路上飞驰的汽车,NGINX 需要停车才能更换轮胎,更换车漆颜色;Envoy 可以一边跑一边换轮胎和颜色;而 OpenResty 除了具备前者能力外,还可以在不停车的情况下,直接把汽车从 SUV 变成跑车。
显然,掌握这种“逆天”的能力后,OpenResty 的能力圈和想象力就扩展到了其他领域,比如 Serverless 和边缘计算等。

出自

温铭 -OpenResty从入门到实战 专栏

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐