发送大量 webhook 消息时结果不一致

Posted

技术标签:

【中文标题】发送大量 webhook 消息时结果不一致【英文标题】:Inconsistent results when sending a large volume of webhook messages 【发布时间】:2022-01-10 06:25:45 【问题描述】:

我是 node.js 和 discord.js 的新手,这个机器人的早期版本是用 discord.py 编写的(现已弃用)。

此函数遍历我的 SQL 数据库中的所有 webhook(id 和令牌),并向它们中的每一个发送一条消息。其中大约有 1500 个(每个服务器一个)。我必须大约每 5 秒发送一次消息。这在 python 版本中完美运行,但只需要在大约 300 个公会上运行。我不再有它的代码,但它的工作方式相同(所有请求都是一次发送的,可能在 500 毫秒内发送了大约 300 个请求,这工作正常),所以我不认为这是一个速率限制问题.

    client.on('messageCreate', (message) => 
        if (message.channelId === '906659272744665139') 
            console.log('found message');
    
                const url = message.content;
                var webhooklist = [];
                
                //get all the webhooks from the database
                db.prepare('SELECT * FROM webhooks').all().forEach(webhook => 
                    const webhookclient = new WebhookClient(id: webhook.webhookID, token: webhook.webhookToken);
                    webhooklist.push(webhookclient);
                )
    
                console.time('sent');
                
                var failed = 0;
                webhooklist.forEach(webhook => 
    
                    var row = new MessageActionRow()
                        .addComponents(
                            savebutton,
                            reportbutton
                        )
                    
                    webhook.send(content: url, components: [row])
                        .catch(err => 
                            if (err instanceof DiscordAPIError) 
                                if (err.code === 10015) 
                                    //remove the webhook from the database
                                    db.prepare('DELETE FROM webhooks WHERE webhookID = ?').run(webhook.id);
                                    console.log(`Removed webhook $webhook.id`);
                             else 
                                failed += 1;
                                console.log(err);
                            
                         else 
                            failed += 1;
                        
                    );
                );
    
                console.timeEnd('sent');
                console.log(failed);
              
            );
        
    );

问题: 向每个 webhook 发送一个请求,但是,消息实际上并没有被发送一半。例如,我正在查看这个机器人所在的 3 个不同的服务器,其中一个出现了一条消息,而另外两个没有出现(这些结果的任何其他组合也会出现,这不是问题服务器已设置)。也没有错误,由 failed 变量指示。澄清一下,大约 50% 的消息会通过,但另外 50% 应该是由机器人发送的,但从未出现在频道中。

(最有可能)不是问题的事情:

-Discord 速率限制 原因:通过 webhook 发送消息不计入 bot 发送的消息,因此不会导致速率限制(全球每秒 50 条消息)。这会导致我受到速率限制的唯一方法是,如果我分别超过每个 webhook 的 5/5 速率限制(这与您尝试向一个频道发送垃圾邮件时发生的情况相同)。

-API 速率限制 原因:API 速率限制只有在我在 10 分钟内发送超过 10,000 个无效请求时才会触发。所有请求都通过,并且控制台中没有错误。如果我受到 API 速率限制,我将被完全阻止使用不和谐 API 长达一个小时。

-我正在启动某种垃圾邮件保护 这个我已经考虑过了。由于大多数消息都通过了,我认为这不是问题。如果我确实设置了有关请求量的任何过滤器,请求可能会超时,或者我会被阻止。

其他说明:

-请求之间的延迟不是一个可行的解决方案,因为几乎任何延迟量乘以必须运行的 1500 次都会导致此函数需要数分钟才能运行。

-这可能与我遇到的另一个问题有关,其中按钮需要很长时间才能响应,因此在我什至可以运行 .deferReply() 之前交互通常会超时,但是,没有一个 webhook 请求时间out(这表明这可能不是问题)

-尽管我有千兆位,但我的互联网最近似乎很慢,但同样,如果互联网是问题,就会出现错误。

总之,像这样的大量 webhook 消息应该可以工作,所以这个问题很可能是客户端的问题。

【问题讨论】:

这怎么和***.com/questions/70197477/…不一样? 不要试图粗鲁,但是当 a) 你没有发布实际发送 webhook 的代码和 b) 你似乎没有记录任何可能的错误时,任何人应该如何提供帮助除了一个特定的错误代码之外,是否来自 Discord API? @BrendanBond 发送 webhook 的代码在那里,failed 变量指示发送 webhook 是否有任何错误。我说它是0,这意味着没有任何错误。 1) 正如我所提到的,如果错误是 Discord API 错误,failed 不会递增,这很容易导致不一致的行为。 2) 不,有问题的代码不存在 - webhook.send 中有什么,实际发送 webhook 的函数?请阅读how to ask。 @BrendanBond webhook.send 是 discord.js 库的一部分。如果你愿意,你可以阅读它的文档,并且该库在 github 上可用(如果你懒得去寻找自己,它所做的只是发送一个 POST 请求)。此外,如果错误是 Discord API 错误,failed 也会增加,如您在代码中所见。如果它是 10015 错误代码,则它不递增的唯一原因是这意味着 webhook 已被删除(因此,只需将其从数据库中删除)。 【参考方案1】:

发现问题:在如此短的时间内发送的大量 Webhook 消息使我的互联网速度变慢,以至于很多 Web 请求最终都没有通过。我编写这个函数的方式,这些错误没有被正确记录。我通过使用 await 而不是 .then() 解决了这个问题。

【讨论】:

以上是关于发送大量 webhook 消息时结果不一致的主要内容,如果未能解决你的问题,请参考以下文章

解决KafKa数据存储与顺序一致性保证

python在linux发送request得到结果不一致

发送从 webhook 收到的消息的 Discord 机器人

微服务架构之最终一致性设计概述

NSZombie 分配日志不一致

我正在尝试让我的不和谐 webhook 使用按钮发送消息