Apache StormCrawler 3.6.0 配置参数详解

Apache StormCrawler 3.6.0 配置参数详解:配置加载链(crawler-default.yaml 内置默认、crawler-conf.yaml 覆盖、Flux 注入),拓扑并发、HTTP 协议、抓取调度、重抓策略、解析、索引、元数据与后端八类核心参数的默认值与改法,含生产配置模板与 FAQ,全程实测。

Apache StormCrawlerApache StormCrawler2026/10/12

Apache StormCrawler 3.6.0 配置参数详解

目标:系统讲解 Apache StormCrawler 3.6.0 的配置体系与核心参数。StormCrawler 的配置分两层:StormCrawler 自带的内置默认配置(core jar 内的 crawler-default.yaml)与用户自定义覆盖(archetype 生成的 crawler-conf.yaml),再经 Flux 拓扑的 includes 机制合并后传入拓扑。本文给出参数查看方式、参数总览、八类核心参数详解与生产配置模板。所有默认值均在 Ubuntu 22.04.5 + StormCrawler 3.6.0 环境实测提取,合并后的完整配置已在拓扑启动日志中核实。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • Java:OpenJDK 17.0.20.1
  • StormCrawler 版本:3.6.0(官方 archetype 生成工程 /root/build/crawler-demo/)
  • Storm 运行时:Apache Storm 2.8.8(/opt/apache-storm-2.8.8/)
  • 配置载体:crawler-default.yaml(内置默认)+ crawler-conf.yaml(用户覆盖)+ crawler-local.flux / crawler.flux(拓扑定义)
  • 演示账号:root

二、前置条件

已按《Ubuntu 22.04 安装 Apache StormCrawler 3.6.0 指南》完成工程生成与构建,可正常编译:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
cd /root/build/crawler-demo
mvn -B clean package

实测结果:BUILD SUCCESS。

三、参数查看与修改方式

3.1 配置加载链

StormCrawler 启动时按以下顺序合并配置(后者覆盖前者):

顺序载体位置作用
1crawler-default.yamlstormcrawler-core-3.6.0.jar 内全部内置默认值
2crawler-conf.yaml工程根目录用户自定义覆盖
3flux 拓扑文件 config 段crawler-local.flux 等拓扑级覆盖(含 topology.kryo.register 等必选项)

flux 的 includes 段声明了合并顺序(archetype 生成的拓扑文件实测内容):

includes:
    - resource: true
      file: "/crawler-default.yaml"
      override: false

    - resource: false
      file: "crawler-conf.yaml"
      override: true

3.2 查看合并后的生效配置

storm local(或 storm jar)启动时,StormSubmitter 会把合并后的完整配置打印到日志(Submitting topology ... with conf {...}),可直接检索确认任意参数的生效值。实测片段(节选):

13:27:21.636 [main] INFO  o.a.s.StormSubmitter - Submitting topology crawler-local in distributed mode with conf {"http.content.limit":65536,"fetcher.threads.number":50,"http.agent.name":"DemoCrawler","http.protocol.implementation":"org.apache.stormcrawler.protocol.okhttp.HttpProtocol","parser.emitOutlinks":true,"scheduler.class":"org.apache.stormcrawler.persistence.DefaultScheduler","urlbuffer.class":"org.apache.stormcrawler.persistence.urlbuffer.SimpleURLBuffer",...

3.3 查看内置默认值

内置默认值可从 core jar 中直接提取查看:

python3 - <<'EOF'
import zipfile
z = zipfile.ZipFile("/root/.m2/repository/org/apache/stormcrawler/stormcrawler-core/3.6.0/stormcrawler-core-3.6.0.jar")
data = z.read("crawler-default.yaml")
open("/tmp/crawler-default.yaml", "wb").write(data)
EOF
grep -n "http.content.limit" /tmp/crawler-default.yaml

实测回显:

122:  http.content.limit: -1

💡 说明:crawler-conf.yaml 把 http.content.limit 覆盖为 65536,故启动日志中生效值为 65536;内置默认为 -1(不限制)。

3.4 修改方式

修改用户层配置 crawler-conf.yaml 后重新 mvn package(配置打包进 uberjar)再运行;仅调临时参数也可直接改 flux 拓扑文件的 config: 段。Java 进程堆参数用 STORM_JAR_JVM_OPTS 或 topology.worker.childopts 调整(建议限制在 256-512MB 并用 jps -v 核实)。

四、参数总览

以下默认值均提取自 crawler-default.yaml(3.6.0 实测);crawler-conf.yaml 覆盖值一栏为 archetype 生成工程的实际值。

参数内置默认值archetype 覆盖值作用
fetcher.threads.number1050抓取线程总数
fetcher.server.delay1.0未覆盖同一主机两次抓取的最小间隔(秒)
fetcher.threads.per.queue1未覆盖每个抓取队列的线程数
fetcher.queue.modebyHost未覆盖队列组织模式(byHost/byIP/byDomain)
fetcher.max.crawl.delay30未覆盖尊重 robots Crawl-delay 的上限(秒)
partition.url.modebyHost未覆盖URLPartitionerBolt 分区依据
urlbuffer.class...urlbuffer.SimpleURLBuffer未覆盖spout 端 URL 缓冲实现
http.protocol.implementation...protocol.httpclient.HttpProtocolokhttp 版HTTP 协议实现类
http.content.limit-165536响应体大小上限(字节,-1 不限)
http.timeout10000未覆盖HTTP 超时(毫秒)
http.allow.redirectsfalse未覆盖是否跟随重定向
http.robots.403.allowtrue未覆盖robots.txt 返回 403 时是否仍允许抓取
robots.cache.specmaximumSize=10000,expireAfterWrite=6h未覆盖robots 规则缓存
scheduler.class...persistence.DefaultScheduler未覆盖抓取调度器
fetchInterval.default14401440成功抓取后的重抓间隔(分钟)
fetchInterval.fetch.error120120抓取失败(临时错误)重试间隔(分钟)
fetchInterval.error-1-1永久错误重抓间隔(-1 不重抓)
max.fetch.errors3未覆盖单 URL 最大错误次数
status.updater.use.cachetrue未覆盖状态组件 DISCOVERED 去重缓存开关
status.updater.cache.specexpireAfterAccess=1h,softValues未覆盖该缓存的 Guava 规格
parser.emitOutlinkstrue未覆盖解析时是否输出外链
jsoup.treat.non.html.as.errortruefalse非 HTML 文档是否按错误处理
sitemap.discoveryfalsetrue是否自动发现 sitemap
detect.mimetypetrue未覆盖内容嗅探 MIME 类型
indexer.url.fieldnameurlurl索引文档的 URL 字段名
indexer.text.fieldnamecontentcontent索引文档的正文字段名
indexer.text.maxlength-1未覆盖正文字段长度上限(-1 不限)
indexer.ignore.empty.fieldsfalse未覆盖是否忽略空字段
metadata.track.path / depthtrue / true未覆盖元数据是否记录路径/深度

💡 说明:http.agent.name 在内置默认中为注释状态(示例值 AnonymousCoward),必须由用户显式设置,否则启动报错;archetype 生成值实测为 DemoCrawler。

五、核心参数分类详解

5.1 拓扑与并发参数(topology.*)

archetype 生成 crawler-conf.yaml 中的实测值:

config:
  topology.workers: 1
  topology.message.timeout.secs: 300
  topology.max.spout.pending: 100
  topology.debug: false

  topology.worker.childopts: "-Xmx2g -Djava.net.preferIPv4Stack=true"

  topology.kryo.register:
    - org.apache.stormcrawler.Metadata
    - org.apache.stormcrawler.persistence.Status
参数说明与建议
topology.workersworker 进程数。本地调试用 1;生产按抓取量横向扩到多个 worker 并配多 supervisor
topology.message.timeout.secs元组完整处理链的超时秒数。慢站点多时可保持 300
topology.max.spout.pendingspout 未完成元组上限,控制抓取并发与背压,100 为保守起步值
topology.worker.childoptsworker JVM 参数。默认 -Xmx2g 偏大,生产建议 256-512MB 起步按需上调,并保留 -Djava.net.preferIPv4Stack=true
topology.kryo.registerFlux 模式必配项,注册 Metadata 与 Status 的 Kryo 序列化,缺省会导致元组序列化异常

5.2 HTTP 协议参数(http.*)

参数默认/覆盖值说明
http.agent.name必填(实测 DemoCrawler)代理名,RFC 9309 合规,用于 robots.txt 匹配
http.agent.version / description / url / emailarchetype 生成 1.0 / Demo crawler for local test / http://www.example.com / root@example.com组成完整 User-Agent
http.protocol.implementation / https.protocol.implementation默认 httpclient 实现;archetype 覆盖为 okhttp 实现切换协议栈改这两项
http.content.limit默认 -1;archetype 65536响应体截断字节上限
http.timeout10000单请求超时毫秒
http.accepttext/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8Accept 头
http.accept.languageen-us,en-gb,en;q=0.7,*;q=0.3Accept-Language 头
http.allow.redirectsfalsetrue 时抓取端跟随重定向,false 交给 RedirectionBolt 处理
http.retry.on.connection.failuretrue连接失败自动重试
http.store.headersfalse是否把响应头写入元数据

⚠️ 注意:http.allow.redirects: false(默认)时重定向由拓扑中的 RedirectionBolt(shunt 组件)处理并记录 _redirTo 元数据,不要同时开启抓取端跟随,避免重复抓取。

5.3 抓取调度参数(fetcher.* 与分区)

参数默认值说明
fetcher.threads.number10(archetype 50)FetcherBolt 全局抓取线程数
fetcher.threads.per.queue1每队列并发,1 保证对单主机礼貌抓取
fetcher.server.delay1.0同主机最小抓取间隔秒
fetcher.server.min.delay0.0同主机额外最小延迟
fetcher.queue.modebyHost可选 byIP/byDomain
fetcher.max.crawl.delay30robots Crawl-delay 钳制上限秒
fetcher.max.crawl.delay.force / fetcher.server.delay.forcefalsetrue 时无视钳制直接采用配置值
fetcher.max.urls.in.queues-1队列内 URL 总量上限(-1 不限)
fetcher.thread.timeout / fetcher.timeout.queue-1单 URL/队列抓取超时秒(-1 不限)
partition.url.modebyHostURLPartitionerBolt 按 host 分区,与 fetcher 队列模式保持一致

5.4 重抓策略参数(scheduler 与 fetchInterval.*)

  # revisit a page daily (value in minutes)
  fetchInterval.default: 1440

  # revisit a page with a fetch error after 2 hours (value in minutes)
  fetchInterval.fetch.error: 120

  # never revisit a page with an error (or set a value in minutes)
  fetchInterval.error: -1
  • scheduler.class 默认 org.apache.stormcrawler.persistence.DefaultScheduler,按 fetchInterval.* 计算下次抓取时间;也可实现 Scheduler 接口或换成 AdaptiveScheduler。
  • 支持按元数据条件覆盖间隔(如 fetchInterval.isFeed=true: 10 表示带 isFeed 元数据的页面 10 分钟重抓)。
  • max.fetch.errors: 3:单 URL 连续错误达 3 次后按 fetchInterval.error 处理。

5.5 解析参数(parser/textextractor/sitemap)

  sitemap.discovery: true
  parsefilters.config.file: "parsefilters.json"
  urlfilters.config.file: "urlfilters.json"
  jsoup.filters.config.file: "jsoupfilters.json"

  textextractor.no.text: false

  textextractor.include.pattern:
   - DIV[id="maincontent"]
   - DIV[itemprop="articleBody"]
   - ARTICLE

  textextractor.exclude.tags:
   - STYLE
   - SCRIPT

  jsoup.treat.non.html.as.error: false

  parser.mimetype.whitelist:
   - application/.+word.*
   - application/.+excel.*
   - application/.+powerpoint.*
   - application/.*pdf.*

  parse.tika.config.file: "tika-config.xml"
参数默认值说明
parser.emitOutlinkstrue解析后输出外链到 status 流(递归抓取的来源)
parser.emitOutlinks.max.per.page-1单页外链输出上限(-1 不限)
textextractor.no.textfalsetrue 时不抽取正文
textextractor.include.pattern空(默认全文抽取)CSS 选择器白名单,命中元素才抽文本
textextractor.exclude.tagsSTYLE/SCRIPT排除的标签
jsoup.treat.non.html.as.error默认 true;archetype 改 falsefalse 时非 HTML 转交 Tika 流而非报错
parser.mimetype.whitelist内置 word/excel/powerpoint/pdf 四类正则允许 Tika 解析的 MIME 白名单
parse.tika.config.file无默认(archetype 引用 tika-config.xml)Tika 解析器配置;archetype 不生成该文件,需自建
sitemap.discovery默认 false;archetype 改 true解析页面时自动发现 sitemap

5.6 索引参数(indexer.*)

  indexer.url.fieldname: "url"
  indexer.text.fieldname: "content"
  indexer.canonical.name: "canonical"

  indexer.md.mapping:
  - parse.title=title
  - parse.keywords=keywords
  - parse.description=description
  - domain
  - format
  • indexer.md.mapping 决定元数据到索引字段的转换:parse.title=title 表示把元数据键 parse.title 映射为字段 title;不带 = 的条目(domain、format)用元数据键原名作字段名;还支持 key[0] 取第 N 个值与 parse.* 通配。
  • indexer.text.maxlength(默认 -1)控制正文字段长度;indexer.ignore.empty.fields(默认 false)过滤空值字段。

实测输出对照(StdOutIndexer 打印的字段即来自上述映射):

content	StormCrawler Local Test Site Welcome to the local crawler test site. Page One Page Two Page Three
url	http://localhost:8080/index.html
domain	localhost
format	html
title	Local Test Site

5.7 元数据传递与持久化(metadata.*)

  metadata.persist:
   - _redirTo
   - error.cause
   - error.source
   - isSitemap
   - isFeed
  • metadata.transfer:随外链传递给子页面的元数据键(支持 follow.* 通配),默认为空。
  • metadata.persist:仅持久化到状态存储、不外传的键。默认持久化重定向目标 _redirTo、错误原因 error.cause/error.source 与 isSitemap/isFeed 标记。
  • metadata.track.path / metadata.track.depth(默认 true):在元数据中记录抓取路径与深度,供 MaxDepthFilter 等使用。

5.8 后端参数(urlfrontier.*)

archetype 默认拓扑使用 URLFrontier 状态后端,crawler-conf.yaml 实测值:

  urlfrontier.host: "localhost"
  urlfrontier.port: 7071

  urlfrontier.max.buckets: 50
  urlfrontier.max.urls.per.bucket: 10
参数默认值说明
urlfrontier.host / urlfrontier.portlocalhost / 7071URLFrontier gRPC 服务地址
urlfrontier.max.buckets50同时拉取的最大队列桶数
urlfrontier.max.urls.per.bucket10每桶单次拉取的 URL 数

💡 说明:若使用 OpenSearch / Solr / SQL 后端,对应参数(如 opensearch.addresses、sql.connection 等)由其模块的默认配置文件提供,写法同为「crawler-conf.yaml 覆盖」;内存后端(MemorySpout/MemoryStatusUpdater)无任何配置项,仅限本地调试。

六、生产配置模板

💡 适用场景:4 核 8GB 内存、单 supervisor、日均百万级页面、增量抓取的生产节点。Java worker 堆按 256-512MB 起步。

config:
  topology.workers: 1
  topology.message.timeout.secs: 300
  topology.max.spout.pending: 200
  topology.debug: false

  # worker 堆限制在 512MB,保留 IPv4 栈
  topology.worker.childopts: "-Xmx512m -Djava.net.preferIPv4Stack=true"

  topology.kryo.register:
    - org.apache.stormcrawler.Metadata
    - org.apache.stormcrawler.persistence.Status

  fetcher.threads.number: 50
  fetcher.threads.per.queue: 1
  fetcher.queue.mode: "byHost"
  fetcher.server.delay: 1.0
  fetcher.max.crawl.delay: 30

  http.agent.name: "YourCrawler"
  http.agent.version: "1.0"
  http.agent.description: "Production crawler"
  http.agent.url: "http://www.example.com"
  http.agent.email: "root@example.com"

  http.protocol.implementation: "org.apache.stormcrawler.protocol.okhttp.HttpProtocol"
  https.protocol.implementation: "org.apache.stormcrawler.protocol.okhttp.HttpProtocol"
  http.content.limit: 262144
  http.timeout: 10000

  fetchInterval.default: 10080
  fetchInterval.fetch.error: 120
  fetchInterval.error: -1
  max.fetch.errors: 3

  sitemap.discovery: true
  parser.emitOutlinks: true
  parser.emitOutlinks.max.per.page: 1024

  indexer.url.fieldname: "url"
  indexer.text.fieldname: "content"
  indexer.text.maxlength: 1048576
  indexer.md.mapping:
  - parse.title=title
  - parse.keywords=keywords
  - parse.description=description
  - domain
  - format

  metadata.persist:
   - _redirTo
   - error.cause
   - error.source
   - isSitemap
   - isFeed
场景建议配置
本地调试(2GB 内存单机)MemorySpout/MemoryStatusUpdater 内存后端 + StdOutIndexer + STORM_JAR_JVM_OPTS=-Xms256m -Xmx512m + fetcher.threads.number 10
中小规模生产(4 核 8GB)URLFrontier/OpenSearch 后端 + topology.workers 1 + max.spout.pending 200 + 堆 512MB
大规模抓取(多 supervisor)URLFrontier 集群 + topology.workers 2 以上 + fetcher.threads.number 100+ + byHost 队列
礼貌抓取(对源站友好)fetcher.server.delay 5.0 + fetcher.max.crawl.delay 30 + threads.per.queue 1

七、常见问题

Q1:改了 crawler-conf.yaml 不生效? 配置打包进 uberjar,改完必须 mvn package 重新构建;另外检查参数是否被 flux 拓扑 config 段覆盖(flux 层优先级最高)。最直接的核实方式是看启动日志 Submitting topology ... with conf {...} 中的生效值。

Q2:启动报错 http.agent.name 缺失或为空? StormCrawler 要求显式设置 http.agent.name(内置默认仅是注释示例)。在 crawler-conf.yaml 中设置 RFC 9309 合规的代理名(仅字母、数字、下划线、连字符)。

Q3:robots.txt 拒绝导致全站抓不到? 检查目标站 robots.txt 与代理名是否匹配;http.robots.403.allow: true 仅在 robots.txt 返回 403 时放行。robots 解析结果缓存在 robots.cache.spec(默认 6 小时)定义的 Guava 缓存中,改规则后需等缓存过期或重启拓扑。

Q4:抓取本机/内网站点被过滤? archetype 自带 default-regex-filters.txt 默认拒绝 localhost/127.x 与 10/192.168/172.16 私网地址(防 SSRF)。内网或本地测试需注释对应规则行并重新构建;公网生产请保持开启。

Q5:worker 内存占用过高? 默认 topology.worker.childopts: "-Xmx2g ..." 偏大。生产建议改为 -Xmx512m(或 256MB)起步;本地模式用 STORM_JAR_JVM_OPTS="-Xms256m -Xmx512m" 注入,并以 jps -v 核对生效值(实测回显含 -Xms256m -Xmx512m)。

Q6:重定向页面重复抓取? 保持 http.allow.redirects: false(默认)由 RedirectionBolt 统一处理;若开启抓取端跟随,重定向页会同时进入两个处理路径。

八、参考链接

  • StormCrawler 官方配置文档:https://stormcrawler.net/
  • 内置默认配置源文件:https://github.com/apache/stormcrawler/blob/main/core/src/main/resources/crawler-default.yaml
  • Apache Storm 配置说明:https://storm.apache.org/releases/2.8.8/Configuration.html
  • Flux 拓扑定义规范:https://storm.apache.org/releases/2.8.8/flux.html