OpenResty: 介绍 (摘抄)

 

 

 

 

原文连接:http://www.javashuo.com/article/p-rsupxyac-bq.html    css

 

Nginx 是俄罗斯人发明的, Lua 是巴西几个教授发明的,中国人章亦春把 LuaJIT VM 嵌入到 Nginx 中,实现了 OpenResty 这个高性能服务端解决方案。html

经过 OpenResty,你能够把 nginx 的各类功能进行自由拼接, 更重要的是,开发门槛并不高,这一切都是用强大轻巧的 Lua 语言来操控。node

它主要的使用场景主要是:python

在 Lua 中揉和和处理各类不一样的 nginx 上游输出(Proxy,Postgres,Redis,Memcached 等)

在请求真正到达上游服务以前,Lua 能够为所欲为的作复杂的访问控制和安全检测

为所欲为的操控响应头里面的信息

从外部存储服务(好比 Redis,Memcached,MySQL,Postgres)中获取后端信息,并用这些信息来实时选择哪个后端来完成业务访问

在内容 handler 中随意编写复杂的 Web 应用,使用 同步但依然非阻塞 的方式,访问后端数据库和其余存储 在 rewrite 阶段,经过 Lua 完成很是复杂的 URL dispatch 用 Lua 能够为 nginx 子请求和任意 location,实现高级缓存机制

组织 OpenResty 技术大会以前,我一直认为本身是一个孤独的 OpenResty 使用者,以为本身在使用一个冷门的技术。nginx

虽然你们都据说过 OpenResty 或者 ngx_lua,但感受用在生产环境中使用的却少之又少,除了几个 CDN 公司外,好像没有据说过哪家知名互联网公司在使用。而 CDN 行业之因此使用,不少是受到 cloudflare 技术栈的影响,OpenResty 的做者也在国外这家 CDN 公司。git

但办完这个大会,我发现使用者真的挺多,奇虎360的全部服务端团队都在使用,京东、百度、魅族、知乎、优酷、新浪这些互联网公司都在使用。有用来写 WAF、有作 CDN 调度、有作广告系统、消息推送系统,还有像咱们部门同样,用做 API server 的。有些还用在很是关键的业务上,好比开涛在高可用架构分享的京东商品详情页,是我知道的 ngx_lua 最大规模的应用。程序员

  1. 奇虎企业安全服务端技术选型的标准

先说下 3 年多前作架构选型的时候,我为何会选择 OpenResty?github

其实架构如何设计并不重要,由于每家公司,每一个团队,他们的公司文化和技术背景各不相同,生搬硬套会拔苗助长。重要的是当初为何这么选择,中途为何调整。sql

咱们的产品要求单机上面,服务端提供高性能的 API 接口, QPS 至少过万,将来须要支撑到 10 万。咱们并无急于去使用 PHP 、 Python 或者其余的语言来实现功能,而是先勾勒出一个理想化的技术模型。docker

这个模型应该具有:

非阻塞的访问网络IO。在链接 MySQL 、Redis 和发起 HTTP 请求时,工做进程不能傻傻的等待网络IO的返回,而是须要支持事件驱动,用协程的方式让 CPU 资源更有效的去处理其余请求。不少语言并不具有这样的能力和周边库。

有完备的缓存机制。不只须要支持 Redis 、Memcached 等外部缓存,也应该在本身的进程内有缓存系统。咱们但愿大部分的请求都能在一个进程中获得数据并返回,这样是最高效的方法,一旦有了网络IO和进程间的交互,性能就会受到很大影响。

同步的写代码逻辑,不要让开发者感知到回调和异步。这个也很重要,程序员也是人,代码应该更符合人的思惟习惯,显式的回调和异步关键字,会打断思路,也给调试带来困难。

最好是站在巨人肩上,基于成熟的技术上搭建。采用一门全新诞生的语言和技术,须要经历语言自身发展期频繁调整的阵痛,还可能站错队。

不只支持 Linux 平台,还须要支持 Windows 平台,这个是咱们产品很特别的需求,不少中小企业用户仍是习惯 Windows 的操做,不具有 Linux 的维护能力。

基于以上几点的考虑,考察了当时的一些方案,选择了 OpenResty 。

首先,它最大的特色就是用同步的代码逻辑实现非阻塞的调用,其次它有单进程内的 LRU cache 和进程间的 share DICT cache,并且它是揉合 nginx 和 LuaJIT 而产生的。并且 nginx 有 Windows 版本,虽然有很是多的限制,但这些限制都是能够解决的, nginx 官方 Windows 版本中不支持的特性,咱们开源出来的版本都解决了。

第一次看到这样的方案,我以为它确定会颠覆高性能服务端的开发。为何呢?在我以前的公司里,天天会有近百亿次的查询请求,而服务器只用了十台。

咱们采用了 nginx C 模块 + 内置在 nginx 中的 K-V 数据库(本身开发的),来实现全部的业务逻辑,达到这个目标。听上去很简单,可是过程很是艰辛,两三个十几年工做经验的大牛作了一年多才稳定下来。绝大部分开发能力不足,只能可望不可即。并且后续的调试和维护,也会花费很多精力。

可是 OpenResty 的出现改变了这一切, OpenResty 很是的 pythonic ,适合人类的正常思惟。新手通过一两个月的学习,作出来的 API, 就能够达到 nginx C 模块的性能,并且代码量大大减小,也方便调试。

  1. 以奇虎和新浪为例,如何在项目中引入新技术

技术选型只是第一步,如何才能在一个产品或者项目中引入 OpenResty 这个新的技术呢?我拿奇虎企业安全和新浪移动这两家公司真实发生的案例给你们看看。我和新浪移动的周晶,都是在一个有成熟产品的部门,用一两我的的力量,把一个新技术,替换掉了原有的技术架构。但因为企业产品和我的产品的不一样,方法有很大的不同。

先说我所在奇虎企业安全。我在 2012 年初加入这个部门,当时产品主打免费,目标用户是小企业。因此架构设计上面,只考虑了几十点、几百点的终端请求,使用了很是强绑定的 Windows 平台技术,并且倾向于不用开源软件,本身新作一个更适合本身的框架。包括本身用 C++ 开发的 Web server,本身写的 PHP 路由和框架,数据存储在 sqlite 里面。

我帮忙修改了两个月 PHP 的 bug,看明白了技术架构的思路以后,就去新开的一个产品线了。这是一个实验性的产品,主要面对央企和专用网,一个网络中有上百万的终端。

刚开始没有什么人关注,我就直接采用了 Linux + OpenResty + Redis + Postgres 的开源组件,性能测试甩以前的N条街。后面这个实验性的产品,和以前的产品,合并为一个产品,技术上面就割裂为两套架构。老功能用老架构,新功能用新架构。

随着愈来愈多大用户的增长,原有的技术架构开始捉襟见肘,技术债务越积压越多。随着用户的抱怨,sqlite 被抛弃,全面换成 Postgres。但对于本身开发的框架仍是有些敝帚自珍。

期间经过对比测试、OpenResty 培训还有屡次用户性能问题排查,让开发同窗们都知道这门技术的优点。快被加班压垮的开发同窗,逐渐开始选择使用 OpenResty 而不是自研的框架,来进行新功能的开发,以及旧功能的迁移,来避免加班。

在产品重构的时候,以前自研的服务端框架被彻底抛弃,服务端开发的同窗从 8 、9 我的减小到 3 我的。在新技术的引入过程当中,咱们没有采用强制的举措,由于企业产品须要稳定,用户处部署的版本更新很慢。

而新浪移动周晶的实践,对你们更有参考意义。新浪移动最开始是基于 Apache,用 PHP 来处理用户请求。Apache 是同步多进程模型,在并发请求很少的状况下没有问题。

可是老是会有突发新闻,好比马航失联、文章×××等,突发的高流量把后台压垮了几回。并且能够预见世界杯的流量也会很大,因此周晶花几个月时间,用 nginx 替换了 Apache,使用 nginx 的 fast_cgi_cache,QPS 提高了一个数量级。

新浪移动后台的接口都是使用 PHP 来实现的,在高并发下有些力不从心。而 nginx 简单的缓存虽然能知足性能,但不能知足业务精细化和数据一致性的要求,须要找 PHP 以外的解决方案,前提是让 PHP 的开发可以温馨的使用。 node.js 的回调地狱、Go 的调试不方便,都是一个阻碍。

他们最后选择了 OpenResty,并且基于 OpenResty 开源了一个 Web 框架 Vanilla(香草),模仿了 Yaf 的使用习惯,让 PHP 的开发更容易接受和上手。 Vanilla 已经在新浪移动开始使用,一些核心业务,好比高清图和体育直播,正在向这个框架迁移中。

  1. 入门痛点,以及学习的正确方法

我和周晶的入门,都是本身摸着石头过河。当时除了 Python 社区「大妈」的那篇使用文章外,找不到其余的资料。

奇虎和新浪都用 OpenResty 成功替换了以前的技术,但问题仍是挺明显,就是你们都认为本身是孤独的使用者,同事中基本没有人认同。在关键和支撑业务上,使用 OpenResty 有些不放心,都会在边缘业务上先作尝试和验证。

虽然 OpenResty 的性能作的很棒,比肩或者超过其余全部的高性能解决方案,可是担忧没有学习资料、担忧招不到人、担忧没人交流,可能还担忧做者章亦春哪天撂挑子不干了,这个项目就黄了。

高可用架构群里的各位都是架构师,是技术决策者,在引入一门新技术的时候,确定会考虑到这些风险。好比小米科技马利超在高可用架构的分享,他们在抢购系统中曾经使用过 ngx_lua,虽然性能知足需求,可是团队里面熟悉的人少,最后仍是改为了 Go 语言实现。

如何解决这些担心? 社区是有过思考和讨论的,咱们放在分享最后讲。先从一个尝试使用这门技术的开发者的角度看,OpenResty 很多基础工做没有完善,友好程度不够:

只能从源码安装,没有 apt-get、brew 等软件仓库安装方法;安装第三方库没有 PIP、NPM 之类的包管理工具,须要去先谷歌,而后拷贝代码文件到指定的目录下,才能 require 使用。 代码编写须要修改 nginx.conf 和对应的 lua 代码,即便是 hello world 也是如此。固然你能够把代码写在 nginx 的配置文件里面,可是生产环境确定是要分离的。这种编写代码的方式,不像是一个编程语言,和常规的编程方式不一样。 有独特的执行阶段概念,由于 OpenResty 是基于 nginx 的,因此也继承它的这种概念。你的代码逻辑,可能须要放在不一样的阶段里面运行,才能获取你想要的预期。而这些阶段间信息如何传递,以及哪些 API 不能在某些阶段使用,就会常常拦住新手。 遇到问题只有邮件列表这一种方式来沟通,而邮件列表是被墙的。文档也只有英文版本,致使不少新手的问题没法被解决。 没有系统学习 OpenResty 的手段,大都是业务须要实现什么功能,就去文档和 API 里面去找。至于方式对不对,能不能优化,就不知道了。

而 Lua 语言自身也有一些特别的地方:

下标从 1 开始,这个是和其余编程语言很大的不一样。 不区分 array 和 dict ,会致使处理 json 的时候,没法区分 array 和 object。 默认全局变量,须要在全部变量前加 local,忘记的话,可能致使各类难查的 bug。 自带的字符串正则匹配规则和一般的 PCRE 不一样,使用的话,学习成本较高。 Lua 标准库和周边库,都是阻塞的,须要本身甄别哪些能够和 OpenResty 搭配使用。新手很容易使用了阻塞的库,而致使性能急剧降低。

有没有好的入门方法?

咱们团队正在作这方面的努力,尽可能在现有的基础上,下降学习的门槛。 对于新手,能够看 StuQ 上面 OpenResty 的系列视频教程 (http://www.stuq.org/course/detail/1015),咱们计划有 4 季,分别是入门、进阶、实战和源码分析。如今第一季已经上线,第二季正在后期制做。看完前两季,基本上就能够在项目里面用了。

对于已经使用了 OpenResty 的开发者,咱们把这两三年遇到的坑,都记录在 GitHub 的《OpenResty最佳实践》上面(https://github.com/moonbingbing/openresty-best-practices),你们能够当作 cookbook 来使用。

  1. nginScript 这样的尝试会替代 OpenResty 吗?

nginScript 是今年 nginx 大会上,Nginx 官方推出的一个新的配置语言。它是模仿了 OpenResty 的作法,把 JavaScript VM 嵌入到 nginx 中,提供简单的 nginx 配置功能。

咱们看下它的 hello world:

OpenResty的现状、趋势、使用及学习方法

再对比下 OpenResty 的 hello world:
OpenResty的现状、趋势、使用及学习方法

看上去差很少,只是 OpenResty 简洁一些。根据 nginx 官方的说明,nginScript 只是想提供一种更方便配置 nginx 的方法,并不想取代 ngx_lua。

考虑到 JavaScript 自己的流行和开发社区的强大,若是将来两三年它从一个简单的 nginx 配置语言,逐渐演变成相似 ngx_lua 这样功能很是完备的开发语言,甚至替代 OpenResty 也是有可能的。

固然,这个前提是 OpenResty 停滞不前。如今 OpenResty 已经有的功能,和计划开发的功能,倾向于覆盖 nginx Plus 的功能。因此 nginx 和 OpenResty 之间,有一个良性的竞争关系,这是你们都乐意看到的。

6 将来重点解决的问题和新增特性

短时间内的目标,是想下降入门的难度:

提供官方二进制发布包。相似于 docker 的安装方法,一行命令,下载一个sh脚本,增长一个源地址,不用手工解决依赖,不用源码编译,直接就能够试用。 并且会发布 Windows 的二进制包,方便这个平台的开发者本机作一些测试。 增长包管理。命令行工具叫 iresty,能够从 iresty.org 上面搜索、安装须要的 lua resty 库,避免找错库或者放错目录。 写一本书《 OpenResty 编程》,这本书会成为官方的入门书籍,框架和关键内容由做者春哥直接操刀,我和社区的其余同窗帮助一块儿完成。

作完上面3点,OpenResty 的入门难度会下降到和其余编程语言同样。

在功能上面,会增长不少激动人心的新特性:

支持 TCP 和 UDP 。Nginx 最新的 stream 子系统已经支持了 TCP,OpenResty 的 ngx_stream_lua 模块正在开发中,会拥有和现有的 nginx http modlue 相同的 lua API,因此不少应用和库,能够不加修改的运行在一个新的子系统上面。

更好的支持推送场景。增长 shared list 共享内存的队列,能够用于 worker 间的通信;增长 semaphore 特性,用于 ngx_lua 轻量级线程间的通信。酷狗音乐的推送服务就是基于这些实现的,这些改动点会在这个月并入 master。能够邀请酷狗音乐的同窗,来给你们详细分享下里面的细节。 创建一个开源的 WAF 平台。如今阿里云和 cloudflare 的 WAF 作的都很棒,经受住了不少实际的考验。可是都没有开源,咱们但愿最好的 WAF 是开源的,并且是基于 OpenResty 的。 在 OpenResty 中增长内存数据库。能够有持久化,或者就是全内存的,支持 SQL 的查询。这个也是出于极致性能的考虑,有时候咱们仍是须要使用 SQL 来作一些复杂的查询,但有不想使用那么重的关系型数据库,并且数据是能够丢失的。那么这个就能够排上用场。 实现 PHP、Python 等方言,让 PHP、Python 等程序员能够用本身喜欢的语言写 OpenResty 的代码,底层转换为 LuaJIT 的字节码。

春哥在 OpenResty 技术大会上面说了很是多的新特性,包括 streaming RegEx 正则引擎等等,很是高端,我挑了几个我以为有意思的作介绍。

  1. 开源社区建设
    OpenResty 诞生于 2011 年,大多数时间都是春哥主力在维护这个项目,固然也有不少开发者提交 feature 和 bugfix ,但基本上算单打独斗。

社区有 github 和邮件列表,大部分仍是提问的。春哥天天会花费不少的时间,来详细的回答各类基础问题。

今年新增了 QQ 群和微信群, QQ 群的质量很高,天天都会有不少提问,非技术问题是被禁止的。并且还有了本身的技术大会,能给你们面对面交流的机会。

咱们翻译了 ngx_lua 的英文文档,能让你们更方便的查找资料;咱们搭建了一个不用×××就能访问的论坛: bbs.iresty.com,用做提问和知识积累的地方。后面会把谷歌邮件列表的内容同步过来。

只有上面这些是不够的,在 OpenResty 技术大会的次日,咱们召集了一个很小规模的闭门会议,决定成立 OpenResty 咨询委员会。

这个委员会,是以我的名字参加的,成员来自奇虎 360、新浪、又拍云、酷狗音乐等公司和社区的开发者,但愿把国内社区的核心使用者和开发者团结在一块儿,促进 OpenResty 的发展。

同时,OpenResty 软件基金会也开始筹备工做,咱们但愿走规范的非盈利组织的模式,来保证 OpenResty 长期稳定发展。给开发者和使用者信心,勇于在关键业务上面使用 OpenResty。

Q & A

一、请问 OpenResty 的定位是什么,从分享来看彷佛全栈了?

定位主要是高性能,全部的新功能和优化,都是针对性能的。 可是也有人拿来作页面,好比京东;也有人拿来替代 PHP 作 Web server,好比新浪。 我以为它愈来愈像一个独立的开发语言。

二、请问 Lua 是否是能够实现动态配置 location?好比动态切流量?
balancer_by_lua 多是你须要的,你能够用 Lua 来定义本身的负载均衡器,能够在每一个请求的级别上去定义,当前访问的后端的节点地址、端口,还能够定制很细力度的访问失败以后的重试策略。

三、OpenResty 是能够拿到 nginx 请求里面的全部信息?那是否是能够作一些更复杂的转发操做?能介绍一下 OpenResty 在 cdn 里面的应用场景吗?

能够看下 iresty.com 的分享,又拍的张聪很是详细的介绍了 OpenResty 在又拍 CDN 的使用。

四、OpenResty 是否修改了 nginx 的源码,仍是和 nginx 彻底可剥离开的?Nginx 版本升级,OpenResty 也跟着升级吗?例如 nginx 修复漏洞 bug 等状况。

OpenResty 不修改 nginx 的源码,能够跟随 nginx 无痛升级。 若是你以为 OpenResty 升级慢了, 你能够只拿 ngx_lua 出来,当作 nginx 的一个模块来编译。实际上,OpenResty 在测试过程当中,发现了不少 nginx 自身的 bug 。

五、软 WAF nginx + Lua 是主流和将来方向么?

我以为 WAF 应该基于 nginx,无论是性能仍是流行程度。而 OpenResty 具备更灵活操控 nginx 的能力,因此我以为 OpenResty 在 WAF 领域很是合适。cloudflare 的 WAF 就是基于 OpenResty。

六、看样子将来可能有各类 ngx_xx,最有可能的是 js,不知道这方面有什么前沿的动向?
咱们组在尝试把 PHP 嵌入到 nginx 中,固然性能确定不如 LuaJIT,可是会方便不少 PHP 同窗,有进展的话,咱们会开源出来 :)

七、OpenResty 目前看彷佛是一个 proxy 的配置框架(糅合了 nginx + Lua),但之后的发展是什么样子?会不会之后更进一步,好比作一个 API gateway 之类的。OpenResty实际上是但愿你们忽略 nginx 的存在,直接使用 ngx_lua 提供的 API 实现本身的业务逻辑。更像一门独立的开发语言,只不过底层使用 nginx 的网络库而已。你能够按照你的想法搭建任何好玩的服务端应用出来。

相关文章
相关标签/搜索