【发布时间】:2023-03-23 15:21:01
【问题描述】:
我可能遗漏了一些明显的东西,但我遇到了架构问题。
我正在构建正常运行时间监控服务。
我有监视器表,每个监视器代表一个 URL。我的任务是将http请求发送到url。我从多个服务器发送 http 请求。每台服务器每分钟将处理数千个网址。
因此,在每台服务器中,我都有 supervisord,它会产生 50-100 个队列工作人员。每分钟一次,我将所有监视器推送到队列中,然后队列工作人员正在检查这些监视器。
但是,每个队列工作者都会创建一个到 MySQL 的连接。我认为这是因为我将 Monitor 模型传递给队列 Job,而 Laravel 仅将监视器 id 放入队列中。然后在处理作业时从数据库中检索整个监视器模型。
或者可能我弄错了,原因只是因为 laravel 在运行任何类型的代码时默认连接,包括排队的作业。
但是 10 个服务器 * 100 个工作人员 = 1000 个连接,这可能很糟糕(我不确定,但我认为它不可扩展)。
我的队列基于本地redis。
所以我觉得把序列化的模型数据放到redis里面是合理的。然后,我把http请求的结果放到redis中。然后在 MySQL 中一次推送一堆结果。
那么如何实现呢?
【问题讨论】:
-
为什么网络请求通过工作队列系统而不是内联处理请求? Web 请求已经是一种衍生的工作线程。确保您的数据库检索快速(它看起来像一个简单的索引查找)并且连接网络连接将显着高于数据库连接。
-
感谢您的回复!我不确定我明白你的意思。就像,好的,每分钟一次我需要运行 1000 个请求。如果我在 for 循环中的 php 脚本中执行此操作,那么它们将是同步的,不是吗?我看到 guzzle 有某种异步请求,但是将排队的作业作为我处理 1 个监视器的单个对象/位置处理会更容易,不是吗?
-
对不起,我搞砸了我对你的架构的理解。它看起来像每个工作人员,根据 monitor_id 拉出一个监视器信息(为什么不只是这个在队列中?),执行需要一些时间的探测,然后将结果推送回 mysql。
-
1000 个连接在大部分时间处于空闲状态或进行简单的插入/单行选择/更新时并不算太糟糕。
-
它从有监视器的队列中提取作业(我认为 Laravel 只保留 monitor_id 然后从 mysql 获取整个模型),然后执行探测,然后将结果推送到 Redis。然后每秒一次,我将所有保存在 Redis 中的检查推送到 mysql(一种插入而不是单个,以提高性能)好吧,如果我有大量监视器,那么这些连接将执行很多操作,比如从数据库中进行 3000 次选择.虽然我不确定一切是如何运作的,但我认为将整个监视器模型保留在 redis 队列中是合理的,不是吗?