2019 年 3 月 23 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·北京站,好未来高级工程师吴钧泽在活动上做了《 当 OpenResty 遇上教育行业 》的分享。

OpenResty x Open Talk 全国巡回沙龙是由 OpenResty 社区、又拍云发起,邀请业内资深的 OpenResty 技术专家,分享 OpenResty 实战经验,增进 OpenResty 使用者的交流与学习,推动 OpenResty 开源项目的发展。活动将陆续在深圳、北京、上海、杭州、成都、武汉等城市巡回举办。

1.jpg

吴钧泽:好未来高级工程师。Swoft开源框架开发者,ServiceMesher 社区成员,重度开源爱好者。目前主要负责商城交易系统,对分布式系统架构、高性能应用有着浓厚的兴

GithubID:wujunze

个人博客:https://www.wujunze.com/

以下是分享全文:

OpenResty 由于它的特性所在,很多情况下大家都用它来做网关,好未来现在也大量深度地使用 OpenResty。

我在 2014 年开始接触 OpenResty,发现一个有意思的事情,金砖国家包括中国、巴西、印度、俄罗斯、南非,而 OpenResty 的所有的技术都源自于金砖国家,Lua 是作者是巴西教授,Nginx 来自俄罗斯,OpenResty 的创始人章亦春来自中国,可以说 OpenResty 这个项目是由金砖国家孵化的。

回到分享主题,我今天为大家分享的主要是四点,背景、选型、架构,以及未来的规划。

好未来为什么要用网关

好未来有很多事业部,技术栈非常复杂,语言包括 PHP、GO、Java 等,但 PHP 占主流。我之前曾尝试用 PHP 解决微服务网关,但是效果并不是很理想。后来一直在寻找合适的解决方案,直到遇上 OpenResty。

我们有许多项目要对外提供一些 API 的服务,不同的项目也有不同的权限:比如 A模块是负责商户的,要走商户的权限;B 模块是负责顾客,要走顾客的权限,或者是对外部的其他接口。在这种情况下,要是没有网关做统一管理,那就要“架构不规范,搬砖两行泪”。

此外是 API 的互相调用,好未来会经常做线上活动,为了保护后端 API 的健壮,不能让它承担业务承载量超过阈值的请求量,那就需要限流、限频次。我想大家应该需要有一个统一的流量接入层,网关服务本身就是一个流量接入层,要求网关的高可用、高性能,所以说网关本身的高可用也是很重要的。

2.jpg

我对网关做了一些技术调研:一类是基 于OpenResty 的 Kong 和 Orange;与 GO 相关的是 Traefik 和 APIGateway;还有基于Java 的 Zuul 和 Spriag Cloud Gateway;还有 PHP 的 Swoole 和 Vrata;最后就是阿里云和 AWS 等云服务的网关。

我做技术选型时考虑的首先是 Java 生态很好,但是我不熟悉;GO 是一个比较合适的备选方案,GO 是后起之秀,国内的社区生态也越来越好了,但是 GO 我也不是很熟;然后就是 OpenResty,Kong 是一个非常成功的商业化公司,它有开源版和商业版。开源版已经可以满足我们大部分的需求,它的商业版可以满足更好的需求,比如 UI 面板等高级功能,但我感觉它对中国本地化做得不是太好;最后就是 Orange,它是国内开发者做的开源网关平台。

好未来的自研之路

3.png

最开始为了业务,产品部提出需要快速上线,第一个方案就是刀耕火种的时代,为了业务,真的是能用就行。于是,我们做了一个可以跑起来的版本,很简单:直接用原生的 OpenResty 开发方式,不管是什么框架,先满足业务。然后我们所有的 API 都是通过自研的 JWT 组件鉴权。

“吃饱了还要吃好”,于是我们做了进化方案。

好未来接着做了 OpenResty 的自研网关,是兄弟部门从 0 到 1 开发的。后来我们组合了网关的内部共创,一起交流怎么来让网关满足我们的需求。当时我们有两个方案,称之为 Plan A 和 Plan B。

网关演进之 Plan A

PlanA 是一个基于 OpenReaty 开发的现代化网关,它比我们一开始的刀耕火种版本强很多,比如有插件化开发、内置丰富变量、可视化后台,还支持分布式。

4.jpg

首先这是一个老生常谈的图,大家都见过类似的图,访问量包括 PC、App 和其他一些终端,中间层就是网关层,最后是服务层。有插件和模块,请求改写,然后是流量控制、认证、鉴权,还有 API 的版本控制、协议转换、缓存、报警、日志监控……这些都是常用网关都有的功能,然后我们为了内部的其他定制化和自主可控,做了一些开发。日志监控是通过异步的消息队列,然后做 ES 分析。通过整体的网关,做接入流量的管控和鉴权,可以满足大部分的业务场景。

网关演进之 Plan B

当然我们还有 Plan B 的方案,是另外一个兄弟事业部主导开发的,简约而不简单。Plan B 是基于 Orange 开发,方案包括了插件化开发、分布式配置文件、集群管理和动态 Upstream 管理。

5.png

上图是网关的工作图:最上面一层是 LVS,四层的负载均衡,LVS 把流量打到最外面,再到第一层的 Gateway,中间再到业务层,此处又做了业务网关,最后是 API 层,这就是整体的一个网站的架构。

网关的作用是什么?负责负载均衡,包括内外隔离,让外层负责一些流量相关,内部负责一些更细的业务相关,这和大家写代码会有一些抽象和分层的套路类似。智能调度可以把流量切到不同集群,不同可用区,还有对后端服务的管理。

如果大家对原版 Orange 有了解,可以看出我们这个方案相当于是 Orange Plus。Orange 的开源版本是用 MySQL 存储配置的,加强的第一个地方是把 Orange 拆成两块,一个是 Gateway,一个是 Gwadmin:Gwadmin 做配置管理,Gateway 就是做网关,做配置的做配置,做流量的做流量。

6.png

它们之间是通过 ECTD 来同步的。Gwadmin 把配置推到 ETCD,然后 confd 再把配置拉下来,拉下来之后,我们会专门有一个 Worker,比如说在 20 个 Worker 中有 1 个 Worker 每隔十秒钟监听一下文件变动,Worker 然后会起一个 timer,如果有配置文件发生变化,它会通知到另外的 19 个 Worker 来更新这些配置文件,所以说,ETCD 解决了我们网关存储的问题。

然后介绍一下动态 Upstream 管理,我们发现了有个模块叫 DYUPS,基于 DYUPS 我们就做了一个动态 Upstream 管理。配置文件如果重启可能会丢失 Upstream,针对丢失的可能性我们有一个兜底的方案,confd 拉完之后会往本地保存一份,如果 ETCD 凉了,起码网关有一个老版本的配置文件,不至于网关凉。

总结 Orange 和 OpenResty

Orange 是一个基于 OpenResty 的轻量级网关,有丰富的插件支持。据我了解,有一些公司在生产环境上已经使用 Orange。Orange 是可用的,已经经过生产环境验证。Orange 目前的情况“已经可以吃饱了,但是并不是吃得很好”,我们未来要做的就是“让大家吃得更好”。

Orange 后续还会支持 k8s 和 gRPC,做一些开发和包装,包括完善的单元测试,对于一个开源项目来说单元测试是很重要的,像我一般用开源项目,我会先看这个单元测试的项目,出了 BUG 就凉了,或者你不知道改了这个 BUG 会不会出现其他的 BUG;然后我们要让 Orange 更稳定,更健壮。

OpenResty 有一些非常好玩的东西,我自己常琢磨一些玩法。这是我个人在玩的或者看到的一些好玩东西:

7.jpg

比如把Rust塞进 OpenResty,rlua 相当于是 Rust 和 Lua 的绑定器,Lua 和 Rust 可以互相调用,但是建议这个东西不要在生产环境使用。

还有把 GO 塞进 Lua,变成 gopher-lua。

玩法也包括把 Lisp 塞进 Lua。之前有人分享过,他们生产环境用的是 urn,相当于 Lisp 的一个方言,他们用得很舒服。我这里要吐槽一下 Lua,如果它在大规模业务当中写的话,Lua 工程化有点麻烦,所以说他们可能就用 Lisp。不得不佩服这个项目,不管东西合不合适,起码人家可以做出来,思路很清晰,用 Lisp 写一些 Lua 模块。

此外还有相关的生态拓展,有人把 PHP 塞进 Nginx,这个东西也是一个玩具,但是思路还是挺有意思的。

现在 Orange 这个项目主要是我和社区的开发者在维护,大家对 Orange 有什么建议、或者想一起来开发、优化、使用它的话,可以一起来交流。