在可扩展的网站上显示实时数据?
Display real time data on website that scales?
我正在启动一个项目,我想创建一个网站来显示实时航班信息和状态。我们都在机场看到过这个。这里给出了一个例子 - http://www.computronics.biz/productimages/prodairport4.jpg. As you can see this information changes continuously. The website will talk to a backend api and the this backend api will talk to database. Now the important part is that the flight information in the database will be updated by the airline itself. There could be several airlines and they will update their data respectively. I have drawn a diagram and uploaded here - https://imgur.com/a/ssw1S.
现在这些航空公司显然会有一个界面(网站与某些后端对话 API),他们将通过该界面更新数据库。
下面是我尝试解决的问题。我们需要某种触发器,这样如果任何航空公司在当前时间 - 1 小时到当前 + 4 小时之间更新数据库中的航班详细信息(网站将只显示几个小时的航班),我们需要调用网络 api 然后将更新实时发送到网站。 用户根本不能刷新页面。同时网站需要很好地扩展,即如果网站上有 100 万用户,并且在数据库中有更新正确的时间范围,所有 100 万用户的网站都应该在适当的时间内得到更新。
我做了一些研究,看起来我们需要一种基于事件的方法。例如 - 我们需要创建一个函数(AWS lambda 或 Azure 函数),只要在正确的时间范围内数据库(例如 Dynamo DB)有更新,就应该调用该函数。然后这个函数应该调用一个 API ,然后它应该通过网络套接字技术更新网站。
我不是在寻找任何代码,而是在寻找一些关于如何以可扩展的方式解决这个问题的替代建议。还有我们如何测试可扩展性?
首先,请不要想太多。这是一个需要解决的小问题,不需要任何特殊的技术、技术或流行的模式和框架。
您实际上拥有三个几乎可以分别处理的功能区域。
- 摄取 - 从各种来源收集和规范化数据。为此,您需要一个流程和转换引擎、LogicApps 等。
- 你的数据库。您很快就会了解到并非所有航班都相同 ;)。虽然看起来如此,但数据量并不那么。针对特定功能调整的 MySQL/SQL 服务器实例将正常工作。提示,您不需要随时准备好每个动作的数据。
- 介绍。数据 API 和 UI。这真的是最简单的部分。我建议您首先使用基本轮询。由于您永远无法控制的原因,飞行数据的 SLA 约为 5 分钟,因此 real-time 客户端通知系统是您应该首先花在其他地方的时间。
不要使用无服务器函数(Lambda/Azure 函数)
虽然我是无服务器函数的忠实粉丝,并且目前 运行正在使用 Lambda 构建一个完整的 Web 应用程序,但我认为您的用例不需要它,并且在经济上没有意义。正如您在评论中回答的那样,每家航空公司都不会直接写入数据库,它们会推送到 API,这意味着您会在航班发生变化时得到明确告知。当航空公司向您发送新数据时,您可以简单地将其通过 websockets 传播到所有浏览器端点。这使设计非常简单。无需人为创建一个数据库事件,然后触发一个函数,然后告诉您航班已更新。这就像取下门铃并用触发门铃的运动检测器替换它:)
费用
钱总是值得的。 Lambda 与其说是技术突破,不如说是经济突破。你必须知道什么时候它的成本效益。你按请求付费,所以如果你处理一个每月处理 10,000 次操作的进程,或者每天只触发 1,000 次的进程,那么 lambda 非常便宜而且几乎免费。您还需要为函数执行的时间长度和执行时消耗的内存付费。通常,在专用服务器大部分时间处于空闲状态的情况下使用 lambda 函数是有意义的。因此,AWS 为您提供了一个按需容器,而不是整个 EC2 实例。在某些情况下,高请求率和不断 运行ning 进程使 lambda 比 EC2 更昂贵。本文讨论了在一定程度上使用 lambda 通常更便宜 -> https://www.trek10.com/blog/lambda-cost/ 这同样适用于 Azure 函数和 google 等效函数。它们都是按需提供的容器。
如果您正在处理航班信息,我想您每分钟都会更新数千个航班,因此您的 lambda 函数将不断触发,就好像您在 运行 一个 EC2 实例一样。您最终将支付比 EC2 多得多的费用。当您有一项服务需要保持 24/7 和 运行 24/7 高 activity 时,这肯定是一个或多个专用服务器的有效用例。
建议的解决方案
这些是我将在下面使用的组件:
- 某种消息队列(可能是 RabbitMQ 或带有 SNS 的 AWS SQS)
- Web Socket 后端(选择取决于编程语言)
- 航空公司输入 API(REST、GraphQL 或 AWS Kinesis Data Firehose)
航空公司将他们的数据发布到 back-end api。更新存储在消息队列中,实际向用户显示结果的 Web 应用程序通过 websockets 从队列中读取。
可扩展性
为了可扩展性,您可以 运行 自动缩放组中多个 EC2 实例(全部从同一个队列服务读取)上的 websocket 应用程序,因此随着额外的负载,将自动创建更多实例,因此名称 "autoscaling"。这些实例可以位于弹性负载均衡器后面。许多关于如何执行此操作及其旗舰设计模式的 AWS 文档。如果您使用 AWS SQS,则不必自己管理可扩展性细节,aws 会处理。唯一真正需要扩展的组件是您的 websocket 应用程序和飞行数据输入端点。您也可以 运行 自动缩放组中的航班 api,但 AWS 确实提供了一个额外的工具来处理高流量数据。我在下面详细说明。
测试可扩展性
让一家模拟航空公司用成千上万的虚假更新来炸毁您的服务相当容易,而在另一端,您可以轻松地 运行 selenium 测试的多个线程模拟浏览器点击并验证UI 仍在运行。
其他工具
如果它最终成为大量数据,而不是使用传统的 REST api 作为您的航班更新服务,您可以考虑使用 AWS 提供的专门用于处理大量实时更新的服务(Kinessis Data Firehose) https://aws.amazon.com/kinesis/data-firehose/ 但我从未使用过它。
我正在启动一个项目,我想创建一个网站来显示实时航班信息和状态。我们都在机场看到过这个。这里给出了一个例子 - http://www.computronics.biz/productimages/prodairport4.jpg. As you can see this information changes continuously. The website will talk to a backend api and the this backend api will talk to database. Now the important part is that the flight information in the database will be updated by the airline itself. There could be several airlines and they will update their data respectively. I have drawn a diagram and uploaded here - https://imgur.com/a/ssw1S.
现在这些航空公司显然会有一个界面(网站与某些后端对话 API),他们将通过该界面更新数据库。
下面是我尝试解决的问题。我们需要某种触发器,这样如果任何航空公司在当前时间 - 1 小时到当前 + 4 小时之间更新数据库中的航班详细信息(网站将只显示几个小时的航班),我们需要调用网络 api 然后将更新实时发送到网站。 用户根本不能刷新页面。同时网站需要很好地扩展,即如果网站上有 100 万用户,并且在数据库中有更新正确的时间范围,所有 100 万用户的网站都应该在适当的时间内得到更新。
我做了一些研究,看起来我们需要一种基于事件的方法。例如 - 我们需要创建一个函数(AWS lambda 或 Azure 函数),只要在正确的时间范围内数据库(例如 Dynamo DB)有更新,就应该调用该函数。然后这个函数应该调用一个 API ,然后它应该通过网络套接字技术更新网站。
我不是在寻找任何代码,而是在寻找一些关于如何以可扩展的方式解决这个问题的替代建议。还有我们如何测试可扩展性?
首先,请不要想太多。这是一个需要解决的小问题,不需要任何特殊的技术、技术或流行的模式和框架。
您实际上拥有三个几乎可以分别处理的功能区域。
- 摄取 - 从各种来源收集和规范化数据。为此,您需要一个流程和转换引擎、LogicApps 等。
- 你的数据库。您很快就会了解到并非所有航班都相同 ;)。虽然看起来如此,但数据量并不那么。针对特定功能调整的 MySQL/SQL 服务器实例将正常工作。提示,您不需要随时准备好每个动作的数据。
- 介绍。数据 API 和 UI。这真的是最简单的部分。我建议您首先使用基本轮询。由于您永远无法控制的原因,飞行数据的 SLA 约为 5 分钟,因此 real-time 客户端通知系统是您应该首先花在其他地方的时间。
不要使用无服务器函数(Lambda/Azure 函数)
虽然我是无服务器函数的忠实粉丝,并且目前 运行正在使用 Lambda 构建一个完整的 Web 应用程序,但我认为您的用例不需要它,并且在经济上没有意义。正如您在评论中回答的那样,每家航空公司都不会直接写入数据库,它们会推送到 API,这意味着您会在航班发生变化时得到明确告知。当航空公司向您发送新数据时,您可以简单地将其通过 websockets 传播到所有浏览器端点。这使设计非常简单。无需人为创建一个数据库事件,然后触发一个函数,然后告诉您航班已更新。这就像取下门铃并用触发门铃的运动检测器替换它:)
费用
钱总是值得的。 Lambda 与其说是技术突破,不如说是经济突破。你必须知道什么时候它的成本效益。你按请求付费,所以如果你处理一个每月处理 10,000 次操作的进程,或者每天只触发 1,000 次的进程,那么 lambda 非常便宜而且几乎免费。您还需要为函数执行的时间长度和执行时消耗的内存付费。通常,在专用服务器大部分时间处于空闲状态的情况下使用 lambda 函数是有意义的。因此,AWS 为您提供了一个按需容器,而不是整个 EC2 实例。在某些情况下,高请求率和不断 运行ning 进程使 lambda 比 EC2 更昂贵。本文讨论了在一定程度上使用 lambda 通常更便宜 -> https://www.trek10.com/blog/lambda-cost/ 这同样适用于 Azure 函数和 google 等效函数。它们都是按需提供的容器。
如果您正在处理航班信息,我想您每分钟都会更新数千个航班,因此您的 lambda 函数将不断触发,就好像您在 运行 一个 EC2 实例一样。您最终将支付比 EC2 多得多的费用。当您有一项服务需要保持 24/7 和 运行 24/7 高 activity 时,这肯定是一个或多个专用服务器的有效用例。
建议的解决方案
这些是我将在下面使用的组件:
- 某种消息队列(可能是 RabbitMQ 或带有 SNS 的 AWS SQS)
- Web Socket 后端(选择取决于编程语言)
- 航空公司输入 API(REST、GraphQL 或 AWS Kinesis Data Firehose)
航空公司将他们的数据发布到 back-end api。更新存储在消息队列中,实际向用户显示结果的 Web 应用程序通过 websockets 从队列中读取。
可扩展性
为了可扩展性,您可以 运行 自动缩放组中多个 EC2 实例(全部从同一个队列服务读取)上的 websocket 应用程序,因此随着额外的负载,将自动创建更多实例,因此名称 "autoscaling"。这些实例可以位于弹性负载均衡器后面。许多关于如何执行此操作及其旗舰设计模式的 AWS 文档。如果您使用 AWS SQS,则不必自己管理可扩展性细节,aws 会处理。唯一真正需要扩展的组件是您的 websocket 应用程序和飞行数据输入端点。您也可以 运行 自动缩放组中的航班 api,但 AWS 确实提供了一个额外的工具来处理高流量数据。我在下面详细说明。
测试可扩展性
让一家模拟航空公司用成千上万的虚假更新来炸毁您的服务相当容易,而在另一端,您可以轻松地 运行 selenium 测试的多个线程模拟浏览器点击并验证UI 仍在运行。
其他工具
如果它最终成为大量数据,而不是使用传统的 REST api 作为您的航班更新服务,您可以考虑使用 AWS 提供的专门用于处理大量实时更新的服务(Kinessis Data Firehose) https://aws.amazon.com/kinesis/data-firehose/ 但我从未使用过它。