smsBomb 调度引擎深度拆解:一文读懂多节点轮换与故障降权的秘密
【免费下载链接】smsBomb短信💣炸🐔项目地址: https://gitcode.com/gh_mirrors/sms/smsBomb
用短信轰炸工具时,你最怕遇到什么?我猜是"某个服务商的接口突然失联,整个任务当场卡死"。smsBomb 是一款基于 Python 的短信轰炸工具,它的调度引擎(SmsBomb类)专门解决"多节点稳定轮换 + 故障自动降权"这个痛点,让一轮轰炸在节点频繁失效时依然能撑到底。这篇文章就把这个调度大脑掰开揉碎讲给你听。
📋 先看能力边界:调度引擎做了什么、没做什么
| 能力 | 说明 | 边界 |
|---|---|---|
| 多节点加权随机选择 | 按weight权重从配置池里挑服务商 | 只负责"选",不负责"发" |
| 故障节点自动降权 | 发送失败就把该节点权重减 1,直至 0 | 不主动探活(ping) |
| 配置池自愈 | 正常池抽空后,把失败节点池整体重置回来 | 重置后失败计数继续累计 |
| 多进程并发 | 用multiprocessing.Pool并行发请求 | 进程数会被攻击次数兜底限制 |
| 进度回调 | 每轮上报"成功/失败/总数" | 展示形式由调用方(CLI/GUI)决定 |
一句话:它是整个工具的"调度大脑",把"打谁、怎么打、打挂了怎么办"全包了。
⚙️ 机制一:加权随机选节点,为什么不是"轮流来"?
如果按顺序挑节点,排在前面的服务商必然先被打爆、先被限流。smsBomb 用weight做加权随机,权重越高的节点被选中的概率越大。
[源码位置:smsBomb/smsBomb.py]
def _random_weight_select(self): weight_lst = [[k, v.copy()] for (k, v) in enumerate(self.config_lst) for _ in range(v.get('weight', 1))] if weight_lst: return random.choice(weight_lst) return None关键点说明:
- 它先把每个配置按权重"复制"若干份塞进一个池子再随机抽,权重 10 的节点出现概率就是权重 1 的 10 倍。
v.copy()是为了防止后续降权操作污染原始配置。- 返回
(下标, 配置副本)二元组,下标用于定位原始配置做降权。 - 返回
None表示池子空了,这是触发"自愈重置"的信号。
🔄 机制二:故障降权 + 配置池自愈
一次发送失败后,调度引擎不会立刻放弃节点,而是把它悄悄"边缘化":权重减一,并记入失败池。
[源码位置:smsBomb/smsBomb.py]
self.config_lst[index]['weight'] = max(current_config.get('weight', 1) - 1, 0) current_config['weight'] = 1 self.failed_config_lst.append(current_config) failed_cnt += 1关键点说明:
- 权重最低降到 0,相当于把该节点"暂时拉黑"。
- 失败节点会带着一份"权重=1"的副本进失败池,将来被重置时还有翻身机会。
- 当正常池被抽空、选节点返回
None时,主循环调用re_config把失败池整体塞回来继续跑——这就是自愈,但失败计数仍会计数,避免无限死循环。 - 全程还有一道保险:失败率上限
max_allowed_failed_rate = 0.95,一旦失败率超过 95%,主循环直接退出,宣告任务失败。
⚡ 机制三:多进程并行 + 统一进度回调
发请求是 IO 密集操作,单线程太慢。引擎用进程池并行执行,同时通过回调把每一轮结果实时上报。
[源码位置:smsBomb/smsBomb.py]
success = pool.apply(worker, args=(cls, 'send', self.target), kwds=payloads) if success: success_cnt += 1 else: # ... 降权逻辑 ... cb(success_cnt, failed_cnt, self.limit)关键点说明:
worker是模块级函数,负责调用对象.send(mobile)——因为进程池要求任务可 pickle 序列化,不能直接传类方法。pool.apply是同步提交、循环串行收集结果,计数天然不会乱。cb默认指向progress_info,CLI 里靠它输出进度日志;GUI 里则换成refresh_progress_bar驱动进度条。
🎬 实战演示:跑一次攻击,看调度日志怎么说
装好依赖后直接执行(并发 5 进程、攻击 20 次、开启 INFO 日志):
python -m smsBomb -t 13800138000 -n 20 --process 5 -v你会看到类似这样的输出节奏(节选):
[INFO 2018-05-31 11:29:17 root] Start attacking phone: 13800138000 [INFO 2018-05-31 11:29:17 yunpian] {'http_status': 200} [DEBUG 2018-05-31 11:29:17 root] 攻击进度(成功数/期望攻击次数): 1/20 = 5.00%, 实际攻击目标次数(含失败): 1(失败0次) [WARNING 2018-05-31 11:29:17 root] 节点{'product': 'ucp', ...}请求失败,尝试降低此配置的优先级如果换成-vvv,日志升级到 DEBUG 级别,你还能看到每个插件拼出来的完整请求体——这是排查"某节点为什么失败"最直接的抓手。
🧩 进阶玩法:把进度"抢"到自己手里
不想看默认日志?start()的cb参数允许你完全接管进度展示,例如写一个自定义回调:
[源码位置:smsBomb/smsBomb.py(start 方法签名)]
def custom_cb(success, failed, total, finished=False): if finished: print(f"完成: 成功{success} 失败{failed}") else: print(f"进度: {success}/{total}") sms_bomb = smsBomb.SmsBomb(plugins, config, target, limit=10) sms_bomb.start(cb=custom_cb)关键点说明:
- 回调必须接收 4 个参数:成功数、失败数、总数、是否强制结束。
- 当成功数没跑满
limit就停止时,会以force_finished=True再触发一次回调,方便你收尾。 - 另一个调优点:在
config/sms.json里把稳定节点的weight调大(如 10),它被抽中的概率就更高——相当于手动给"敢死队"排序。GUI 版就是靠这套回调驱动进度条可视化的。
🕳️ 避坑指南:这些坑我替你踩过了
| 常见问题 | 原因 | 解决办法 |
|---|---|---|
| 任务跑很久不结束 | 配置池里全是失效接口,失败率没到 95% 阈值 | 用-vvv看日志,删掉持续失败的节点 |
| 日志提示"无此插件:xxx,跳过" | 配置的product名与plugins/下文件名对不上 | 检查config/sms.json的product字段拼写 |
| 设了 10 进程却只看到几个在跑 | 攻击次数小于进程数,代码里min()做了兜底 | 想并发高就把-n调大,或减小--process |
| 节点失败后权重变 0 就再也没出现 | 这是降权机制的预期行为 | 想重新启用,重启进程或手动把weight改回正数 |
✅ 收尾总结
一句话概括:smsBomb 的调度引擎 = 加权随机选节点 + 失败自动降权 + 配置池自愈 + 多进程并发 + 可插拔进度回调。
记住这三点,你就掌握了它的精髓:
weight越大越容易被选中,失败一次减一分,减到 0 暂时"雪藏"。- 全部节点被雪藏时会把失败池整体重置再战,但 95% 失败率的保险丝会兜底止损。
- 想二次开发,盯住
start()的cb参数和plugins/目录——新增一个XxxPlugin就多一个可用节点。
想继续深入?建议从plugins/aliyun.py的 HMAC-SHA1 签名看起,了解一个云厂商接口是如何被"翻译"成可复用插件的;也可以git clone https://gitcode.com/gh_mirrors/sms/smsBomb把代码拉下来,亲手给失败率阈值加一个命令行参数试试。
【免费下载链接】smsBomb短信💣炸🐔项目地址: https://gitcode.com/gh_mirrors/sms/smsBomb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考