综合 如何在短时间内向250万个主机发送5亿个不符合RFC的HTTP/1.1请求

2024-11-18 13:38:35 +0800 CST views 500

如何在短时间内向250万个主机发送5亿个不符合RFC的HTTP/1.1请求

任务背景

我需要在短时间内向250万个主机发送5亿个不符合RFC的HTTP/1.1请求,理想情况下要在几个小时内完成。为此,我深入研究了HTTP/1.1和Go语言的细节,并通过多种方法来优化这个过程,包括利用Kubernetes进行水平扩展,优化代码以充分利用每个CPU核心,甚至修改了Go的HTTP库来加速这一过程。

为什么选择Go?

我选择Go语言,因为它简单易用,具有出色的并发支持,而且速度快。此外,Go语言的学习曲线较低,即使是JS开发者也能轻松上手。这点对于我来说尤其重要,因为我曾尝试过用Rust来实现这一任务,但由于异步编程的复杂性,我选择了更易理解的Go。

5亿个HTTP/1.1请求有多少?

你可能想知道这是多还是少。实际上,这是一个非常庞大的数量级。假设每个请求耗时0.5秒,如果你使用curl从单台机器依次发送这些请求,需要7.9年才能完成。然而,现实情况会更慢,服务器会限制速率,且响应时间可能超过0.5秒。

从数据传输的角度来看,这个量并不算巨大:

  • 5亿个请求 * 1 KB(平均请求大小)≈ 478 GB
  • 5亿个响应 * 5 KB(平均响应大小)≈ 2.33 TB

问题不在于数据量,而在于如何高效地发送这些请求。

HTTP/1.1请求的复杂性

images
发送单个HTTP/1.1请求涉及多个步骤,例如DNS解析、TCP连接、TLS握手、请求构建与发送、响应处理等。每个步骤都可能失败,因此必须准备好处理重试。

即使是在高性能服务器上,解析DNS记录和打开TLS连接也可能耗时160ms左右。对于需要向不同网络中的多个主机发送大量请求的任务,这种延迟是不可接受的。

优化策略

移除不必要的步骤

通过提前解析DNS记录并手动构建HTTP/1.1请求,我消除了请求解析和DNS解析的延迟。此外,我使用了massdns工具来快速解析大量DNS记录,进一步加快了请求速度。

HTTP/1.1发送大炮的设计

我使用多个工作池来处理请求生成、发送和响应处理,每个工作池由并发安全的队列隔离。这样做的好处是,每个组件可以独立扩展,且易于调试和优化。

选择合适的HTTP库

Go语言中的net/http库虽然功能强大,但在性能方面存在不足。我选择了fasthttp库,它是为速度优化的低级HTTP库。通过一些自定义优化,例如跳过请求规范化步骤,我进一步提升了性能。

跳过DNS解析

为了避免每次请求都进行DNS解析,我使用自定义拨号器直接连接到已解析的IP地址。这一优化显著减少了请求的延迟。

优化TLS握手

由于TLS握手消耗了大量的CPU周期,我考虑硬编码密钥来加快这一过程,尽管最终我选择了更易实现的方案。

工作分块

我将250万个主机分成每块200个主机,每个块由一个工作线程处理。这一分块策略平衡了效率和可靠性,确保在请求失败时能够最小化重试的工作量。

Kubernetes扩展

为了完成这一庞大的任务,我使用DigitalOcean上的Kubernetes集群进行扩展。每个Pod可以达到每秒100-400个请求,通过扩展到60个Pod,我在几个小时内完成了向250万个主机发送5亿个HTTP/1.1请求的任务。

结论

最终结果相当令人满意:

  • 每个Pod达到每秒100-400个请求
  • 扩展到60个Pod
  • 在几个小时内完成了任务

这次任务的成功归功于对Go语言和HTTP/1.1的深入理解,以及对工具和架构的有效优化。在下一篇文章中,我会分享更多关于任务结果的细节。

参考链接

  1. @kannthu1
  2. 通配符DNS
  3. massdns
  4. 并发安全队列
  5. fasthttp基准测试
  6. 自定义fasthttp库
  7. DigitalOcean带宽
复制全文 生成海报 编程 网络 性能优化 云计算

推荐文章

rangeSlider进度条滑块
2024-11-19 06:49:50 +0800 CST
LLM驱动的强大网络爬虫工具
2024-11-19 07:37:07 +0800 CST
如何实现虚拟滚动
2024-11-18 20:50:47 +0800 CST
前端如何优化资源加载
2024-11-18 13:35:45 +0800 CST
MySQL 1364 错误解决办法
2024-11-19 05:07:59 +0800 CST
Shell 里给变量赋值为多行文本
2024-11-18 20:25:45 +0800 CST
使用Ollama部署本地大模型
2024-11-19 10:00:55 +0800 CST
mysql 计算附近的人
2024-11-18 13:51:11 +0800 CST
开源AI反混淆JS代码:HumanifyJS
2024-11-19 02:30:40 +0800 CST
Plyr.js 播放器介绍
2024-11-18 12:39:35 +0800 CST
WebSQL数据库:HTML5的非标准伴侣
2024-11-18 22:44:20 +0800 CST
服务器购买推荐
2024-11-18 23:48:02 +0800 CST
Vue3中如何进行异步组件的加载?
2024-11-17 04:29:53 +0800 CST
CSS 媒体查询
2024-11-18 13:42:46 +0800 CST
Vue3中怎样处理组件引用?
2024-11-18 23:17:15 +0800 CST
markdowns滚动事件
2024-11-19 10:07:32 +0800 CST
php使用文件锁解决少量并发问题
2024-11-17 05:07:57 +0800 CST
程序员茄子在线接单