外观
antispam-crawler-solution — 网站内容爬虫监测
分层:业务层 | 部署单元:6 个 | 数据库:TiDB(antispam)+ DDB(yidun_online) | base image:private-registry.yidun.internal/yidun/base-image:jdk17
一、模块定位与架构
本模块是易盾「内容安全爬虫监测」的服务端实现:客户或运营通过 HTTP 提交网站、公众号、微博、视频、PayPal 等监测任务,系统按调度周期驱动爬虫采集页面,把待检测内容送反垃圾媒体解决方案做机审/人审,再把结果经回调/查询接口送客户。它把「持续采集 + 送检 + 回传」串成一条事件驱动的流水线。
架构分层(协议/逻辑/数据三层映射到子模块):
- 协议层:
facade/http-check-api(客户提交/回调/查询主入口,端口 8765)、facade/dubbo-api+facade/dubbo-provider(Dubbo 契约与实现)、facade/http-api(骨架/健康检查,未构建镜像)。 - 逻辑层:
manager(消费爬虫资源消息提交检测)、worker(消费任务/资源消息驱动爬取)、scheduler(ElasticJob 定时推进任务/周期/断点续爬/报表/清理)、storage(CDC 消费入库 + 归档/快照)、service/business(业务服务、爬虫 pipeline/processor/spider、状态机)、common、domain。 - 数据层:
service/base(DAO/Manager/Repository,MyBatis)。
关键数据流:
客户 HTTP 提交任务 → http-check-api/CrawlerJobSubmitController → service/business CrawlerJobService.createJobReturnId → scheduler 启动任务并推进周期 → worker 消费 Kafka/Redis 消息爬取 → CrawlerResource 落库/入队列 → PipelineFactory 选管线 → manager/CheckConsumer 消费 Antispam_Crawler_File_Check 送媒体解决方案 → storage 消费结果 CDC 入库/归档 → http-check-api 回调接口把结果回传客户。
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
facade/dubbo-provider | antispam-crawler-solution-facade-dubbo-provider | antispam-crawler-solution-facade-dubbo-provider | 随机(dubbo.protocol.port=-1) | Dubbo Provider | 有 | 无(模块无 kubernetes.yml) |
facade/http-check-api | antispam-crawler-solution-facade-http-check-api | antispam-crawler-solution-facade-http-check-api | 8765 | HTTP 提交/检测入口 | 有 | 无(模块无 kubernetes.yml) |
manager | antispam-crawler-solution-manager | antispam-crawler-solution-manager | 无(Kafka 消费) | Kafka Consumer | 有 | 无(模块无 kubernetes.yml) |
worker | antispam-crawler-solution-worker | antispam-crawler-solution-worker | 无(Kafka 消费) | Kafka Consumer / 爬虫执行 | 有 | 无(模块无 kubernetes.yml) |
storage | antispam-crawler-solution-storage | antispam-crawler-solution-storage | 无(Kafka 消费) | Kafka Consumer / 归档存储 | 有 | 无(模块无 kubernetes.yml) |
scheduler | antispam-crawler-solution-scheduler | antispam-crawler-solution-scheduler | 无(ElasticJob Worker) | 定时任务 | 有 | 无(模块无 kubernetes.yml) |
facade/http-api | antispam-crawler-solution-facade-http | — | 8080(默认) | HTTP 骨架/健康检查 | 无(不构建) | 否 |
facade/dubbo-api | antispam-crawler-solution-facade-dubbo-api | — | 无 | Dubbo 接口定义(非部署单元) | 无(不构建) | 否 |
console/api | —(空工程,无启动类) | — | 无 | 骨架占位 | 无(不构建) | 否 |
三、同模块启动顺序
facade/dubbo-provider— 注册 Dubbo Provider,manager/worker/storage等消费方要能解析到它;先起避免消费到消息后 Dubbo 反查失败。manager— 消费爬虫资源消息把内容送媒体解决方案检测,是任务提交后的第一处理环。worker— 消费任务/资源消息驱动爬取,产出待检资源给manager。storage— 消费 CDC/回调结果消息入库、归档,保证结果可查。scheduler— ElasticJob 依赖就绪时反复触发任务。facade/http-check-api— 对外提交入口,放最后,确保入口打开时下游已就绪。
四、逐服务启动逻辑
4.1 facade/dubbo-provider
- 启动类:
com.netease.is.antispam.crawler.facade.dubbo.DubboApplication(facade/dubbo-provider/src/main/java/com/netease/is/antispam/crawler/facade/dubbo/DubboApplication.java)。 - exclude:无(未排除任何自动配置)。
@Enable*/@Import:@EnableAspectJAutoProxy、@EnableCdcDataSubscribe、@EnableConfigurationProperties(CrawlerSolutionProperties.class)、@EnableBusinessClient、@EnableOssClient、@EnableDistributeId、@EnableIsolateComponent、@EnableRecoverComponent、@EnableEventClient、@ImportResource("classpath:dubbo-consumer.xml")。- 配置类:
configuration/FacadeDubboConfiguration——@ComponentScan({crawler.service, crawler.manager, crawler.limiter, crawler.component, crawler.kafka, crawler.template, crawler.apollo, crawler.remote, crawler.archive, crawler.es, crawler.statemachine, crawler.repository, crawler.helper, crawler.checker})+@MapperScan("com.netease.is.antispam.crawler.dao")+@ImportResource("classpath:crawler-dubbo-provider.xml");dubbo.scan.basePackages=com.netease.is.antispam.crawler.facade.dubbo.provider。 main()自定义:无,仅SpringApplication.run。- 启动钩子:本单元无独立钩子,随扫包加载
service/business的共享@PostConstruct/InitializingBean(见 4.7)。
4.2 facade/http-check-api
- 启动类:
com.netease.is.antispam.crawler.facade.http.HttpCheckApplication(facade/http-check-api/src/main/java/com/netease/is/antispam/crawler/facade/http/HttpCheckApplication.java)。 - exclude:无。
@Enable*/@Import:@EnableRepeatCheck、@EnableCdcDataSubscribe、@EnableConfigurationProperties(CrawlerSolutionProperties.class)、@EnableBusinessClient、@EnableOssClient、@EnableRateLimiter、@EnableDistributeId、@EnableI18nComponent、@ImportResource("classpath:dubbo-consumer.xml")、@EnableIsolateComponent、@EnableRecoverComponent、@EnableEventClient(注意:未加@EnableAspectJAutoProxy)。- 配置类:
configuration/HttpCheckConfiguration——@ComponentScan({crawler.service, crawler.manager, crawler.limiter, crawler, crawler.monitor, components.callback})+@MapperScan("com.netease.is.antispam.crawler.dao")。 main()自定义:无。- 启动钩子:限流组件(
@EnableRateLimiter,rate.limiter.limiter-type=REDIS)+ Sentinel(spring.cloud.sentinel.enabled=true)+ 扫包内@PostConstruct。
4.3 manager
- 启动类:
com.netease.is.antispam.crawler.manager.ManagerApplication(manager/src/main/java/com/netease/is/antispam/crawler/manager/ManagerApplication.java)。 - exclude:无。
@Enable*/@Import:@EnableAspectJAutoProxy、@EnableScheduling、@EnableCdcDataSubscribe、@ComponentScan({"com.netease.is.antispam.crawler"})、@MapperScan("com.netease.is.antispam.crawler.dao")、@EnableConfigurationProperties(CrawlerSolutionProperties.class)、@EnableBusinessClient、@EnableOssClient、@ImportResource("classpath:dubbo-consumer.xml")、@EnableIsolateComponent、@EnableRecoverComponent。- 配置类:
ManagerConfiguration(@ComponentScanservice/manager/limiter/component/kafka/apollo/remote +@MapperScan);KafkaConfiguration(DefaultKafkaConsumerFactory);NewKafkaConfiguration。 main()自定义:无。- 启动钩子:
consumer/CheckConsumer.@PostConstruct,并声明@KafkaConsumer(clusterIds={"new"}, topics={CrawlerConstant.CRAWLER_RESOURCE_CHECK_TOPIC}, groupId="crawler-solution-manager", concurrency=8)与@MultipleKafkaConsumer。
4.4 worker
- 启动类:
com.netease.is.antispam.crawler.worker.WorkerApplication(worker/src/main/java/com/netease/is/antispam/crawler/worker/WorkerApplication.java)。 - exclude:无。
@Enable*/@Import:@EnableAspectJAutoProxy、@EnableTransactionManagement、@EnableCdcDataSubscribe、@EnableConfigurationProperties(CrawlerSolutionProperties.class)、@EnableBusinessClient、@EnableOssClient、@EnableIsolateComponent、@EnableRecoverComponent、@ImportResource("classpath:dubbo-consumer.xml")、@EnableCaching。- 配置类:
WorkerConfiguration、ApolloConfiguration、CacheConfiguration。 main()自定义:无。- 启动钩子:
CrawlerJobConsumer/CrawlerResourceConsumer/IsolationCrawlerResourceConsumer均@PostConstruct;优雅下线listener/YidunQosApplication.doOffline()依次调crawlerResourceConsumer.offline()、isolationCrawlerResourceConsumer.offline(),再LockSupport.parkNanos(60s)。
4.5 storage
- 启动类:
com.netease.is.antispam.crawler.storage.StorageApplication(storage/src/main/java/com/netease/is/antispam/crawler/storage/StorageApplication.java)。 - exclude:无。
@Enable*/@Import:@EnableAspectJAutoProxy、@EnableTransactionManagement、@EnableCdcDataSubscribe、@EnableConfigurationProperties(CrawlerSolutionProperties.class)、@EnableBusinessClient、@EnableOssClient、@ImportResource("classpath:dubbo-consumer.xml")、@EnableIsolateComponent、@EnableRecoverComponent、@EnableDistributeId。- 配置类:
StorageConfiguration、KafkaConfiguration、NewKafkaConfiguration、ApolloConfiguration。 main()自定义:无。- 启动钩子:大量消费者
@PostConstruct(CrawlerCdcConsumer、CrawlerResultsCdcConsumer、CrawlerDomainConsumer、CrawlerPreprocessConsumer、CrawlerResultAsyncMsgConsumer、CrawlerSolutionHttpCheckConsumer、CrawlerV2TransitionConsumer(@KafkaListener)、CrawlerLiveVideoRpcCallbackConsumer、MediaCallbackConsumer、OfficialAccountsConsumer、WeiboConsumer、CrawlerArchiveConsumer、ConcurrencyMonitorConsumer、PackageEventConsumer、CrawlerResultCallbackConsumer),全部clusterIds={"new"}、groupId="crawler-solution-storage"。
4.6 scheduler
- 启动类:
com.netease.is.antispam.crawler.scheduler.SchedulerApplication(scheduler/src/main/java/com/netease/is/antispam/crawler/scheduler/SchedulerApplication.java)。 - exclude:无。
@Enable*/@Import:@EnableCdcDataSubscribe、@EnableConfigurationProperties(CrawlerSolutionProperties.class)、@EnableElasticJob、@EnableBusinessClient、@EnableOssClient、@EnableIsolateComponent、@EnableRecoverComponent、@ImportResource("classpath:dubbo-consumer.xml")。- 配置类:
SchedulerConfiguration、StateMachinePushConfiguration。 main()自定义:无。- 启动钩子:ElasticJob namespace
netease-antispam-crawlersolution-job,约 20 个@ElasticJobConf(crawlerJobTask、crawlerMonitorTask、detectJobResourceTask、interfaceJobMonitorTask、jobBreakpointContinuedCrawlTask、jobCycleReportTask、officialAccountsCrawlerTask、weiboCrawlerTask、snapshotTaskWorker、crawlerResourcePushTask、crawlerJobCycleStartTask/ReportTask/CheckFinishTask等)。
4.7 facade/http-api(无 Dockerfile,不构建)
- 启动类:
com.netease.is.antispam.crawler.facade.http.HttpApplication;仅@SpringBootApplication。 - 配置类:
FacadeHttpConfiguration——@ComponentScan({"com.netease.is.antispam.service","com.netease.is.antispam.manager"})+@MapperScan("com.netease.is.antispam.dao")+RedisComponentBean。 - 容器:Undertow(
server.undertow.io-threads=1、worker-threads=2);无application-private.properties。 - 共享钩子(随
service/business扫包加载,被 4.1~4.6 各 crawler 服务共同加载):RedisRecoverService implements InitializingBean、AbstractProcessStrategy、ParseManager、EsDataSourceManager、InterfaceCheckRedisScheduler、JobRedisScheduler、BusinessMonitorKafkaProducer、CrawlerOpRecordAppender、CrawlerJobStateMachine/CrawlerResourceStateMachine、ResourceArchiveInsertRecoverService/ResultsArchiveInsertRecoverService(均@PostConstruct)。
五、启动前置依赖
| 依赖 | 配置键/地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| Apollo | app.id=antispam-crawler(storage=antispam-crawler-storage、worker=antispam-crawler-worker、http-check=antispam-crawler-http-check);namespaces application,antispam-crawler-common;apollo.meta=http://yd-apollo-config.nistest.netease.com | 阻塞 | application.properties |
| ZooKeeper(Dubbo 注册) | dubbo.registry.address=zookeeper://zk-0.zookeeper.yidun-infra:2181?...;group /yidun/antispam/online-new/yidun-antispam-dubbo | 阻塞 | application-private.properties |
| ZooKeeper(业务配置/分布式ID/CDC/ElasticJob) | zookeeper.config.root.path=/netease-antispam/online/config;distribute.id.zookeeper-host;elastic.job.zk.serverLists | 阻塞 | application-private.properties |
| TiDB | jdbc:mysql://tidb-cluster0-tidb.tidb.svc:4000/antispam(com.mysql.cj.jdbc.Driver + Hikari) | 阻塞 | application-private.properties(dubbo-provider/http-check) |
| DDB | jdbc:mysql:ddb://10.122.167.231:6000,.../yidun_online(com.netease.lbd.LBDriver + Druid) | 阻塞 | application-private.properties(manager/scheduler/storage/worker) |
| Redis | Sentinel redis0-redis-ha.yidun-infra.svc:26379(dubbo-provider/http-check);Cluster 10.196.38.116:6301,...(manager/storage);spring.cache.redis(worker) | 阻塞 | application-private.properties / application.properties |
| Kafka | 收 netease.kafka.consumer.cluster.new.bootstrap.servers;发 app.kafka.bootstrap.servers;CDC cdc.kafka.bootstrap-servers | 阻塞 | application-private.properties |
| Elasticsearch | EsDataSourceManager.@PostConstruct 建数据源 | 阻塞 | 经 ZK/Apollo |
| OSS | oss.client.provider=netease;endpoint=nos.netease.com;明文 AK/SK | 弱依赖 | application.properties |
| 外部 HTTP | spider-gateway.nistest.service.163.org;media.solution.submit.url;file.solution.query.url | 弱依赖 | application-private.properties |
| Dubbo consumer | classpath:dubbo-consumer.xml 引 MediaCallbackFacade(version 1.0.0,check=false) | 弱依赖 | service/business/src/main/resources/dubbo-consumer.xml |
六、启动参数与 Profile
- Profiles:各单元
application.properties默认spring.profiles.active=dev;已有dev/test/jiande-online/private(http-check-api、dubbo-provider、manager、scheduler、storage、worker),facade/http-api另有online但无private。 - Maven profile:根
buildAll.sh设GLOBAL_ENV=private,逐模块build.sh -e private触发mvn clean install -P private。 - JAVA_OPTS:
facade/dubbo-provider、facade/http-check-api为-Xmx512m -Xms512m -XX:+UseG1GC;manager/scheduler/storage/worker为-Xmx1024m -Xms1024m -XX:+UseG1GC;全部附-Dspring.profiles.active=private。 - base image 与仓库:
private-registry.yidun.internal/yidun/base-image:jdk17;镜像仓库private-registry.yidun.internal/yidun;tagbase-250409;jar 落/app/,入口bash docker-entrypoint.sh。
七、启动期踩坑
- 两套数据源体系:
dubbo-provider/http-check-api用 TiDB(com.mysql.cj.jdbc.Driver+ Hikari),manager/scheduler/storage/worker用 DDB(com.netease.lbd.LBDriver+jdbc:mysql:ddb://+ Druid),Druid 驱动类缺失或网络不通会直接启动失败。 - MyBatis 别名包不一致:
http-check-api/dubbo-provider为com.netease.is.antispam.crawler.domain,其余为com.netease.is.antispam.domain.model,写错包名会导致映射不到实体。 dubbo.protocol.port=-1随机端口,k8s NetworkPolicy / 探针需按端口范围放开,否则消费方连不上。@EnableCdcDataSubscribe/@EnableDistributeId强依赖 ZooKeeper,ZK 不可达时启动阻塞在初始化。@EnableBusinessClient需 ZK 业务配置可用且business.client.options.remote.address可达,否则反复重试。- base image 默认
spring.profiles.active=dev,Dockerfile 强制-Dspring.profiles.active=private;facade/http-api无application-private.properties,会回落 dev 配置。 - OSS 明文凭据(AK/SK 硬编码于
application.properties),且存在两套 endpoint(nos.netease.com与nos2-i.service.163.org)。 - worker 优雅下线 park 60s(
YidunQosApplication.doOffline),PodterminationGracePeriodSeconds必须 ≥ 60s,否则被强杀丢消息。 facade/http-check-api的application-private.properties中dubbo.application.id=antispam-crawler-solution-manager(疑似复制粘贴),仅影响 Dubbo 元数据展示。facade/http-api的FacadeHttpConfiguration扫的是com.netease.is.antispam.service/.manager骨架包,并未指向 crawler 业务包,该单元本身不可独立起完整业务。
八、跨模块前置
- 依赖 antispam-business(
@EnableBusinessClient,读产品/密钥/套餐配置,ZKrootPath=/netease-antispam/online/config)。 - 依赖 antispam-media-solution(
media.solution.submit.url)与 antispam-file(file.solution.query.url)承接检测。 - 中间件前置:ZooKeeper、Kafka(new/cdc 集群)、TiDB、DDB、Redis、Elasticsearch 全部就绪。
- Dubbo 侧:
facade/dubbo-provider应先于消费方单元启动;上游 Dubbo 契约若变更需同步消费方。
与既有描述差异:Undertow
io-threads=1/worker-threads=2实际配置在facade/http-api(http-check-api走 Tomcat 参数,未见 Undertow 配置);facade/http-api的 artifactId 为antispam-crawler-solution-facade-http;dubbo-provider额外@ImportResource("classpath:crawler-dubbo-provider.xml")。