反向代理包含数百甚至上千个微服务是一个很有意思的事情,也是我们在 Sourcelair 每天都要面对的事情。这也是为什么我们今天要很高兴地宣布 Ceryx,一个动态反向代理,使用 OpenResty,Lua 和 Flask,可以代理主机上任意多的服务。它的配置是即时生效。在过去几个月里我们一直在做 Ceryx 项目。现在我们将它开源。 摘要在 SourceLair,我们快速提供开发环境并努力让 web 开发可以无障碍,并使用云的力量。我们提供的一个优秀服务之一是每个项目有一个公共的 URL,它始终可用,并自动刷新你的代码。这样我们需要每小时启动和停止多用户容器,并在不停机的情况下路由每个用户的公共 URL 到当前容器。 以前的解决方案Ceryx 是去年我们开发的内部项目。为了找到解决我们问题的最佳方案,我们尝试了各种技术。在这条路上,我们保持 API 的稳定不受变化的影响。有一个很好的话题没有放到这里,你可以在 API Meetup Athens 找到我们的 slides。 Twisted,MongoDB 和 Redis 首先,我们使用基于 Twisted 自定义反向代理,Twisted 非常好用,是使用 Python 写的事件驱动的网络引擎。如果在 Redis 缓存中没有查到,服务就以 MongoDB 查询做为路由。不管是使用数据库查询,还是调用 API 添加,更新或删除路由,缓存都是流行的方式。对我们来说,它工作得很好,很快 Twisted 有了一个很好用的反向代理 API 可以使用。这个应用让我们错失的一件事情是,Twisted 在默认情况下,每个反向代理头部不能设置成你想要的,在某些情况会导致一些无效的转发。但是用它工作是很方便的。 tproxy和Redis在 Twisted 之后,我们又尝试了 tproxy。tproxy 是一个使用 Gevent 创建的 TCP 路由代理(第七层),Gevent 深受 Ruby 的 ProxyMachine 影响由著名的 Gunicorn 创建。我们创建了一个查找层用来替代静态路由和文件,它会查找后端的 Redis。我们从 MongoDB 彻底地分离了服务,因为路由是短暂且易于重建的。同样我们将 API 分离出来用 Flask 写了独立的服务。主要的问题是 tproxy 的开发有点被遗弃。最后一次提交是一年前。我们需要重新做一些性能优化,还有一个有趣的 bug,响应没有包含响应长度,并保持开放直到超时。 NGINX 和 etcd我们已经决定将代理作为一个服务而不是一个盒子,我们调研了 NGINX 和 HAProxy。因为我们非常熟悉前者并且对它的表现很满意。我们所有的前端都是一直使用 NGINX。我们创建了一个监控脚本,它监控etcd 的重要变更,并自动加载 NGINX 的配置。我们还修改了我们的 API,让它和 etcd 一起做为后端工作。这大大改善了性能。但过了几周我们发现配置的变更没有我们想像得快。NGINX 的重新加载几乎是瞬间的。但配置要花一段时间接收人工配置才能生效。导致路由更新变得缓慢。对我们来说最重要的问题是这种重新加载时间超过10秒,导致多次出现“服务已停止"页面,直到新的配置生效。 OpenResty 和 Lua 就是我们的救星 |