Ceryx:一个动态 NGINX 已翻译 100%

oschina 投递于 2015/07/28 17:22 (共 6 段, 翻译完成于 08-15)
阅读 5432
收藏 122
2
加载中

反向代理包含数百甚至上千个微服务是一个很有意思的事情,也是我们在 Sourcelair 每天都要面对的事情。这也是为什么我们今天要很高兴地宣布 Ceryx,一个动态反向代理,使用 OpenResty,Lua 和 Flask,可以代理主机上任意多的服务。它的配置是即时生效。在过去几个月里我们一直在做 Ceryx 项目。现在我们将它开源。

摘要

SourceLair,我们快速提供开发环境并努力让 web 开发可以无障碍,并使用云的力量。我们提供的一个优秀服务之一是每个项目有一个公共的 URL,它始终可用,并自动刷新你的代码。这样我们需要每小时启动和停止多用户容器,并在不停机的情况下路由每个用户的公共 URL 到当前容器。

wancheng
wancheng
翻译于 2015/07/29 10:22
2

以前的解决方案

Ceryx 是去年我们开发的内部项目。为了找到解决我们问题的最佳方案,我们尝试了各种技术。在这条路上,我们保持 API 的稳定不受变化的影响。有一个很好的话题没有放到这里,你可以在 API Meetup Athens 找到我们的 slides

Twisted,MongoDB 和 Redis

首先,我们使用基于 Twisted 自定义反向代理,Twisted 非常好用,是使用 Python 写的事件驱动的网络引擎。如果在 Redis 缓存中没有查到,服务就以 MongoDB 查询做为路由。不管是使用数据库查询,还是调用 API 添加,更新或删除路由,缓存都是流行的方式。对我们来说,它工作得很好,很快 Twisted 有了一个很好用的反向代理 API 可以使用。这个应用让我们错失的一件事情是,Twisted 在默认情况下,每个反向代理头部不能设置成你想要的,在某些情况会导致一些无效的转发。但是用它工作是很方便的。

wancheng
wancheng
翻译于 2015/08/01 11:21
1

tproxy和Redis

在 Twisted 之后,我们又尝试了 tproxy。tproxy 是一个使用 Gevent 创建的 TCP 路由代理(第七层),Gevent 深受 Ruby 的 ProxyMachine 影响由著名的 Gunicorn 创建。我们创建了一个查找层用来替代静态路由和文件,它会查找后端的 Redis。我们从 MongoDB 彻底地分离了服务,因为路由是短暂且易于重建的。同样我们将 API 分离出来用 Flask 写了独立的服务。主要的问题是 tproxy 的开发有点被遗弃。最后一次提交是一年前。我们需要重新做一些性能优化,还有一个有趣的 bug,响应没有包含响应长度,并保持开放直到超时。

NGINX 和 etcd

我们已经决定将代理作为一个服务而不是一个盒子,我们调研了 NGINXHAProxy。因为我们非常熟悉前者并且对它的表现很满意。我们所有的前端都是一直使用 NGINX。我们创建了一个监控脚本,它监控etcd 的重要变更,并自动加载 NGINX 的配置。我们还修改了我们的 API,让它和 etcd 一起做为后端工作。这大大改善了性能。但过了几周我们发现配置的变更没有我们想像得快。NGINX 的重新加载几乎是瞬间的。但配置要花一段时间接收人工配置才能生效。导致路由更新变得缓慢。对我们来说最重要的问题是这种重新加载时间超过10秒,导致多次出现“服务已停止"页面,直到新的配置生效。

wancheng
wancheng
翻译于 2015/08/02 22:33
1

OpenResty 和 Lua 就是我们的救星

当前,Github 记录关于他们在 NGINX 使用 Lua 脚本对 GitHub pages 进行更频繁的重载 - 之前他们大概 30 分钟重载一次。

当我们在寻找另外一个替代品的时候,对这篇博文非常感兴趣,就开始深入研究 OpenResty - NGINX 的风情版本,使用 Lua JIT 编译,还有其他第三方 NGINX 模块。

我们决定继续用回 Redis 作为后端,因为我们已经准备好 API ,Redis 也已经在内存中,也因此查询速度非常快。我们同时使用 Redis 进行其他服务和缓存,所以不需要再考虑其他集群。

解决方案就是 Ceryx,现在已经开源,提供给每个人使用。这包括了 NGINX lua 脚本和 API,可以轻松的使用 Docker Compose 部署。

叶秀兰
叶秀兰
翻译于 2015/08/15 17:15
2

把所有的一切都缝合在一起

NGINX 提供几个钩子,可以在请求的几个阶段执行 Lua 代码。Ceryx 只会在代理阶段之前采取行动 -在  "access_by_lua_file" 阶段,即是 Lua 路由器。

此路由器会查询 NGINX 和 Redis 后端的本地内存缓存,以此确定目标主机和将会到来的主机端口,如果没找到就返回一个通配符目标。一个 Redis 查询返回一个结果时,这个结果会被缓存 5 秒,所以后续请求不会影响 Redis - 当需要静态文件(比如 CSS,JavaScript 和图像)的时候这会是一个很好的改进,这时候会同时抛出多个请求。可以通过增加缓存超时来对 Ceryx 进行量身定做,适应各个应用的需求。

与此同时,提供一个简单的 Flask 服务,为路由和使用新路由更新 Redis 后端提供一个 CRUD API。代理和 API 服务共享相同的环境变量,用来配置 Redis,保持一致性。

叶秀兰
叶秀兰
翻译于 2015/08/15 17:52
1

第一印象

最新的 Ceryx 发布第一周后,我们看到了其在反向代理和大幅减少休眠服务页上的巨大改进。在更多地细节上,升级前的 Ceryx,每个开发会话平均有 10 个页面浏览量,而现在我们仅仅需要 2.5 个。

下一步

Ceryx 是在 MIT 协议下的开源项目,因此我们乐见用户贡献或者提出 bug 以及新功能请求。我们计划添加 StatsD 测量功能到 Ceryx,这样我们可以更好改进和优化一些相应的部分。

Ceryx Github项目期待你的想法和贡献。

溪边九节
溪边九节
翻译于 2015/08/04 20:17
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(15)

p
pinghe125
@CalssNotFound ,看ceryx的源码,好像完全不是这么一回事。他是用host作为key,查redis,得到container_url,最后反向代理到 http://$container_url$request_uri,完全没用
i19
i19
@CalssNotFound 看起来很酷的样子。 非常感谢。
Storm-Cai
Storm-Cai
@i19 说个简单的例子:比如我有一个系统,它分为许多子系统:注册/登陆/权限模块,产品系统,订单系统等等。那么,在微服务架构中,这些模块都是被单独划分出来的。前端一般使用ngx作为反代,后端有许多服务在运行。这个时候如果你有一个服务路由配置改变了,比如从/login变成/auth/login 那么就需要重新启动ngx以加载新的配置。这样对体验来讲是非常糟糕的。而且,不具备自动发现服务的功能。比如我新增一个服务,那么必须得重新修改配置文件。这个时候,在ngx后面挂个路由功能就显得非常重要了,你更改过配置以后,goruter是可以及时生效的。而且,还能利用路由功能做自动服务发现这些功能。比如你新增了一个子系统, 那么只需要向ruter里面注册一条路由功能就能够正常工作。其中, 最重要的一点就是配置要及时生效。
Storm-Cai
Storm-Cai

引用来自“CalssNotFound”的评论

非常好的东西, 以前一直是etcd + goruter 不知道这个是否可以替代

引用来自“i19”的评论

看了文章以后,还是不太清楚这个东西是为了解决什么问题?能说下否?
说个简单的例子:比如我有一个系统,它分为许多子系统:注册/登陆/权限模块,产品系统,订单系统等等。那么,在微服务架构中,这些模块都是被单独划分出来的。前端一般使用ngx作为反代,后端有许多服务在运行。这个时候如果你有一个服务路由配置改变了
i19
i19

引用来自“CalssNotFound”的评论

非常好的东西, 以前一直是etcd + goruter 不知道这个是否可以替代
看了文章以后,还是不太清楚这个东西是为了解决什么问题?能说下否?
叶秀兰
叶秀兰

引用来自“zhonghai”的评论

PV(page view)即页面浏览量
zhonghai
zhonghai
PV(page view)即页面浏览量
叶秀兰
叶秀兰

引用来自“Jacktom2012”的评论

翻译很有问题,基本的术语都不清楚,比如Page View。
能解释一下吗?
完颜阿骨再打
完颜阿骨再打
翻译很有问题,基本的术语都不清楚,比如Page View。
Storm-Cai
Storm-Cai
非常好的东西, 以前一直是etcd + goruter 不知道这个是否可以替代
返回顶部
顶部