OpenResty 的过去、现在和未来(中)

题图是 OpenResty 大会第二天的小规模圆桌会议。

这是春哥在去年 OpenResty 大会上的分享实录。满满的干货,我搭配 PPT 整理为三部分,分期发出来给大家。如果是有什么错漏,是我整理的问题。


在设计整个 OpenResty 的过程中,我们还是有几个比较清晰的目标。第一个目标首先是简单,simple。这也是我为什么不喜欢很多 java 框架的原因,就是一定要简单,不需要的东西一定不能存在。

然后要小巧,这点我也是很执着的一个事情,我算是半个ops,运维人员的背景出身,所以我希望我在机器上面跑的程序能够小巧,以至于能够完全控制整个代码机,在出问题的时候,可以自己去分析,自己去追踪,乃至自己去修复,而不管出问题的组件处于软件系统的哪个位置,所以这个有点偏执,但是这样可以让我晚上睡个好觉,因为我不再惧怕任何诡异问题,因为本来也就没有什么诡异问题。

个就是要快,这是我在yahoo和淘宝工作的最直接的感触。后来到了cloudflare也是类似的情况,其实现在的互联网环境变得如此的拥挤,就是看上去很不起眼的东西,往往就能吸引到很多流量,有很高的性能要求,而给我们的机器,通常不尽如人意,yahoo当时爬虫淘汰下来的机器是一个极端例子,但也能说明问题,所以要快。如果一个程序跑的还不如我收工干活来的要快,那么为什么还要写程序呢?

最后一个目标是一定要灵活。这也是我非常看重脚本语言的一个方面,静态语言有很多优点,但是我希望在做业务的时候,我的手是足够灵活的,可以做任何我想做的事情,而不会受到很多不必要的束缚。这一点,在座的脚本程序员都会深有体会。有时候,我并不希望实现语言给我太多的限制。

那么,很重要的一点,就是要实用主义。我们并不追求很花哨的学院派的概念,虽然作为业务爱好还是很有裨益的,但是对于工程的实践来说,实用主义应该是放在第一位的。首先要把活干了,也得得到一个足够高效、足够健壮、足够优美的一个系统。优美是最高境界。那么 OpenResty 就是实用主义的产物。我希望我们继续贯彻这个方针,保持实用主义者的称号。

还有一个很重要的,就是开源工作者很看重的:有趣

我们假设开源是一个编译器,它有优化选项,-Ofun,我们是针对乐趣进行优化。这一点看上去是和实用主义原则冲突,其实不然。因为对于一个工程师来说,最有意思的莫过于自己的技术,自己搭建的系统,自己设计的方案,能够在线上跑的非常好,能够服务越来越多的用户,这是非常大的一个乐趣。

对开源工作者来讲,他也希望自己的代码能够跑在尽可能多的公司的服务器上,能够收到尽可能多的用户的感谢信。这个你想,在一天干活最痛苦的时候,突然收到一封来自世界另一个角落的用户的感谢信,字里行间洋溢着一种感激,一种欣喜,那你这一天立马就会变得非常美好。

所以,要让乐趣变成我们工作的主旋律,而不要让工作变成一种负担。这也是我在做 OpenResty 的时候,希望我自己,以及每一位参与开发或者普通使用的用户,都能去做到的一件事情。

我们会看到在一些社区里面,很容易产生一种愤怒,比如说有某个用户问了一个很小白的问题,或者出言不逊,诸如此类的,很容易让人变得毛躁起来。我希望这种消极情绪能够尽量的消极乃至没有,因为我还是希望世界能多一些美好,多一些正面的积极的情绪,对我们每个人也会更好一些。

那么我们有一个正在不断成长的社区,我每天花费你们没法想象的时间,去处理用户的邮件和补丁,有新特性,有bugfix。会用各种语言去写,有时候会忘了正在用什么语言,可能前半截用的中文,后半截用的英文,有时候也会出现混乱的情况。

360的几位哥们儿,温铭、院生、艾菲他们也自己开了一个qq群,我不在那个群里面,因为我很久不用qq了。然后github上面也会有很多issue和pull request,当然一般的讨论还是希望能够在邮件列表里面,这样可以方便通过搜索引擎进行检索。那么现在我们还有了会议,让原本只知道web ID的朋友,能够看到真人,很多朋友只认识他们的github ID,或者email里面的nick,而不知道他们长什么样子。其实很多人和我想像多年的样子完全不一样,都是很正常的,还好没有性别和我想像的不一样。

我很希望去写一本书,那么360的温铭他们的团队已经开始写一本叫做《OpenResty最佳实践》的书,我自己脑袋里面也会有一些想法,我们可能会合作去合著一本书,这都是可以去讨论的。我脑袋里面那本书叫《programming OpenResty》,希望能够把我这么多年来,做 OpenResty 的一些感悟和心得,能够写下来。这样也省的我在邮件里面,翻来覆去的重复一些很基本的东西,也能让更多的人受益。

包管理一直是社区里面呼声很高的一个功能。我也希望 OpenResty 官方提供包管理这样的东西,我们可以很方便的上传、分享、安装自己或者他人的 Lua resty模块, Lua 库,或者基于 OpenResty 的应用程序和工具,都可以通过这个统一的工具链。大家熟悉的比如说,nodejs的NPM, Perl 的CPAN,ptyhon的PIP, Ruby的gems,有很多现有包管理工具,我们可以去参考。我们设计还没有定型,我只是给大家看下我脑海里面很粗糙的想法。这个名字不太好起,我跟温铭,跟院生他们商量,我觉得目前最好的名字是iresty,但还是稍微有点儿长,像PIP、NPM都是三个字母。iresty.org这个网站,我们可以检索所有 Lua resty的库,或者driver,比如需要ZooKeeper、MongoDB这样的客户端库的时候,就可以先在这个网站上进行搜索。没有的话,或者没有合适的话,你可以去着手开发,这样可以避免重复劳动,也可以鼓励大家的协同。

命令行工具也会叫iresty,如果大家有更好的想法, 可以在邮件列表或者qq群,告诉我们。现在是一个雏形的想法。我们可以去 install 一个库,可以删除卸载这个模块。我比较坚持的一点是,模块名字前面要求加上github ID,这样可以避免其他社区包管理里面常见的一种抢坑的问题,就是我这个东西还没做出来,我先抢这个坑,别人就不能注册这个名字了。我希望像github一样,鼓励大家不在名字空间上面去争夺,像 Github 一样鼓励大家去fork,去自己定制,但是还是希望尽量去协作,但我不希望协作是强制的。也可以去search,这些基本功能是需要的。

我还希望有一个命令行的文档,可以看到标准模块和安装模块的格式化的文档。这样省的我们在网上搜索,那也挺费事的。在终端里面可以看到,这比较符合我们UNIX程序员的习惯。当然不仅能查看库的文档,模块的文档,还可以查看 NGINX Lua 或者 NGINX 里面某个配置指令的文档,我也希望能做到这一点,这样所有的文档查找都能通过一个命令行工具来进行,甚至你终端支持颜色的话,显示出来的文档是彩色的。

resty这个工具已经实现了有一段时间,可能有些同学还不知道。这是一个很简单的 OpenResty 命令行,你可以用-e选项去执行一行代码,你可以使用几乎所有的 OpenResty 里面暴露的标准API,你也可以指定一个文件,用 OpenResty 实现一些命令行的工具。我们注意到这个工具也可以用于一些在线的分析,比如说同一份业务代码,即可以作为服务跑在 NGINX 里面,同时也可以在命令行里面,供运维人员去快速检查一些当前生产数据的状态,所以这也会非常有用。还有同学会用这个工具做单元测试,因为本质上这个resty工具,自己启动了一个没有脑袋的 NGINX ,这个 NGINX 不会监听任何东西,只是一股脑的从头执行到尾,然后退出。

我们刚才说到irsety包管理工具,会同时支持 Lua 库和 OpenResty 应用,我希望有更多的 OpenResty 应用可以通过iresty install 就可以装上,就可以运行。

我们可能会对 Lua Rocks有限性的兼容支持,而且我个人对 Lua Rocks不是特别的喜欢。所以我希望 OpenResty 有自己的包管理系统。同时标准 Lua 世界的库,由于各种原因,没有考虑 OpenResty 的阻塞和非阻塞的问题,它没有使用 OpenResty 提供底层的原语接口,比如说socket接口,所以这些库通常会阻塞 NGINX 的事件循环,造成并发的严重下降。

还会有更多官方的二进制发布包。比如说我们现在正在做的windows的二进制发布包,里面有一个32位的windows版本,刚才360的同学们也讲到,他们维护了一个windows的分支。现在计划是把他们的优化工作,融合到官方的windows版本中来。我现在这个是非常简单的,并不适合做生产,只适合在windows上面做开发,有人有这样的需求,虽然他们最后的生产环境是Linux或者BSD。 我现在的windows版本是用MinGW GCC来编译的,我希望最终使用微软的工具链来编译,以获得最好的性能,和最少的依赖项。还会有主流的Linux发行版本的仓库,这样大家升级是apt-get update一下。这些工作都是近期会重点做的事情。我还希望iresty.org网站上传的 Lua 模块和应用,能自动生成二进制各个发行版的安装包,这也是个很cool的feature。

还有一个大家呼声很高的特性,就是让 NGINX 成为一个一般的TCP server,而不仅仅是http server,我们就可以去做更多的事情。那么 NGINX 最新提供的 stream 子系统就可以做到这一点。我们会有基于这个子系统的 Lua 模块和echo模块。echo模块已经完成开发,大家可以在github上面去查看, Lua 模块也正在开发过程当中,它会拥有和现有的 NGINX http modlue相同的 Lua API,所以你们的很多应用和库,可以不加修改的运行在一个新的子系统上面。

类似的,我们会有UDP server,其实我很想看到的一点,是基于 OpenResty 的DNS name server,我觉得这是一个很有意思的应用。

下一个,模板。上午 Aapo 老师介绍过他自己写的 lua-resty-template,我自己也有我的一些想法,就是 lua-resty-tt2(jemplate)。作为一个 Perl 程序员,我非常热爱 Perl 里面 tt2 这个模板语言。它其实跟 Perl 没有太多关系, Perl 社区的一个大神,他写了一个 jemplate 这个工具,可以把 tt2 生成为独立的、可以在客户端运行的JavaScript,这就意味着同一份模板,即可以跑在服务端,也可以跑在客户端,这是一个非常有趣的想法。

这得益于这个模板语言既不是 Perl ,也不是 Lua ,也不是JavaScript,而是它自己的一种小语言,足够简单但有足够强大。我曾经用一个脚本语言实现了一个比较完整的x86反汇编器,就是通过这个模板。所以这块也是我想去尝试的官方模板引擎库。当然,如果大家有兴趣,也可以去移植 Python 里面常见的模板语言到 OpenResty 的场景下,那么 Python 原有的应用可以更容易的迁移到 OpenResty ,模板文件至少不用动。

未完待续,下期更精彩。