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

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

如何在短时间内向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带宽
复制全文 生成海报 编程 网络 性能优化 云计算

推荐文章

PHP 8.4 中的新数组函数
2024-11-19 08:33:52 +0800 CST
Golang 随机公平库 satmihir/fair
2024-11-19 03:28:37 +0800 CST
使用Ollama部署本地大模型
2024-11-19 10:00:55 +0800 CST
程序员出海搞钱工具库
2024-11-18 22:16:19 +0800 CST
Go 如何做好缓存
2024-11-18 13:33:37 +0800 CST
Golang Select 的使用及基本实现
2024-11-18 13:48:21 +0800 CST
Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
nuxt.js服务端渲染框架
2024-11-17 18:20:42 +0800 CST
如何使用go-redis库与Redis数据库
2024-11-17 04:52:02 +0800 CST
纯CSS绘制iPhoneX的外观
2024-11-19 06:39:43 +0800 CST
WebSQL数据库:HTML5的非标准伴侣
2024-11-18 22:44:20 +0800 CST
FastAPI 入门指南
2024-11-19 08:51:54 +0800 CST
CSS 特效与资源推荐
2024-11-19 00:43:31 +0800 CST
Nginx 防止IP伪造,绕过IP限制
2025-01-15 09:44:42 +0800 CST
程序员茄子在线接单