我很快将为即将启动的应用程序购买一堆服务器,但我对我的设置感到担忧。我很感激收到的任何反馈。
我有一个应用程序将使用我编写的 API。其他用户/开发人员也将使用此 API。API 服务器将接收请求并将其转发到工作服务器。API 将仅保存请求的 mysql db,用于日志记录、身份验证和速率限制。
每个工作服务器执行不同的工作将来为了扩大规模,我将添加更多工作服务器以处理工作。API 配置文件将被编辑以记录新的工作服务器。工作服务器将进行一些处理,一些将图像路径保存到本地数据库,以便稍后由 API 检索并在我的应用程序上查看,一些将返回进程结果的字符串并将其保存到本地数据库。
这种设置对您来说是否有效?有没有更好的方法来重构它?我应该考虑哪些问题?请参见下图,希望它有助于理解。
答案1
更高的可用性
正如 Chris 提到的,API 服务器是布局中的单点故障。您正在设置的是消息队列基础架构,许多人之前已经实现过。
继续沿着同样的路径
您提到在 API 服务器上接收请求并将作业插入到每个服务器上运行的 MySQL DB 中。如果您想继续这条路,我建议删除 API 服务器层,并设计 Workers 以直接接受来自 API 用户的命令。您可以使用诸如循环 DNS 之类的简单方法将每个 API 用户连接直接分发到可用的工作节点之一(如果连接不成功,则重试)。
使用消息队列服务器
更强大的消息队列基础设施使用为此目的设计的软件,如活动消息队列。您可以使用 ActiveMQ 的 RESTful API 接受来自 API 用户的 POST 请求,空闲的工作人员可以获取队列中的下一条消息。但是,这可能超出您的需求 - 它是为延迟、速度和每秒数百万条消息而设计的。
使用 Zookeeper
作为中间立场,你可能需要看看Zookeeper,即使它不是专门的消息队列服务器。我们在 $work 中使用它来实现这个目的。我们有一组三台服务器(类似于您的 API 服务器),它们运行 Zookeeper 服务器软件,并有一个用于处理来自用户和应用程序的请求的 Web 前端。Web 前端以及与工作程序的 Zookeeper 后端连接都有一个负载平衡器,以确保我们继续处理队列,即使服务器因维护而停机。工作完成后,工作程序会告诉 Zookeeper 集群该作业已完成。如果一个工作程序死亡,该作业将被发送到另一个工作程序来完成。
其他问题
- 在工人没有回应的情况下确保工作完成
- API 如何知道一项工作已完成,并从工作者的数据库中检索它?
- 尝试降低复杂性。您是否需要在每个工作节点上设置一个独立的 MySQL 服务器,或者它们是否可以与 API 服务器上的 MySQL 服务器(或复制的 MySQL 集群)通信?
- 安全性。任何人都可以提交作业吗?有身份验证吗?
- 哪个工人应该接手下一项工作?你没有提到任务预计需要 10 毫秒还是 1 小时。如果它们很快,你应该删除层以降低延迟。如果它们很慢,你应该非常小心,确保较短的请求不会被卡在一些长时间运行的请求后面。
答案2
我看到的最大问题是缺乏故障转移计划。
您的 API 服务器是一个巨大的单点故障。如果它发生故障,那么即使您的工作服务器仍在运行,一切都将无法正常工作。此外,如果工作服务器发生故障,那么该服务器提供的服务将不再可用。
我建议你看一下Linux虚拟服务器项目(http://www.linuxvirtualserver.org/) 了解负载平衡和故障转移的工作原理,并了解它们如何使您的设计受益。
构建系统的方法有很多种。哪种方法更好是一个主观判断,最好由您来回答。我建议您做一些研究;权衡不同方法的利弊。如果您需要有关植入方法的信息,请提交新问题。