外观
antispam-video-solution — 音视频多模态内容审核方案(切片、抽帧、送检、回调编排)
分层:解决方案层(Facade + Scheduler + Storage) | 部署单元:5 个(有 Dockerfile) | 数据库:TiDB | base image:private-registry.yidun.internal/yidun/base-image:jdk17
一、模块定位与架构
业务定位:antispam-video-solution 受理音视频(含点播音视频、短视频等)内容审核任务,负责音视频的分片/抽帧/取音轨、逐片送机审、汇总判定与回调,本身不做识别算法。
架构分层:
| 层 | 子模块目录 | 职责 |
|---|---|---|
| 协议层 | facade/http-check-api、facade/http-api、facade/dubbo-provider | 同步/异步提交、查询与回调、内部 Dubbo |
| 逻辑层 | service/business、service/base、common、domain | 切片编排与业务逻辑、DAO/Manager、模型与 DTO |
| 数据层 | TiDB、Kafka、Redis Sentinel、Elasticsearch | 任务与结果持久化、异步总线、缓存与锁、结果检索 |
关键数据流:
- 客户端 →
http-check-api:提交音视频审核任务,登记入库并投递 Kafka。 scheduler:machineFinishCheckTask/syncDataFinishTask驱动分片推进与完成判定。- 各分片(音频/视频帧)→ 送下层音视频业务引擎检测。
- 检测结果消息 →
storage(@KafkaConsumer(clusterIds={"new"}, topics={"Antispam_VideoSolution_Check"}))消费入库。 scheduler的videoSolutionCallbackPoolRemainderCountMonitor、videoSolutionCheckingMonitor做积压与状态监控。- 判定完成 →
Antispam_VideoSolution_ActiveCallback主动回调,或客户端经http-api查询。
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
facade/dubbo-provider | antispam-video-solution-facade-dubbo-provider | antispam-video-solution-dubbo-provider | Dubbo 协议端口(未显式配置) | Dubbo Provider | 有 | 是(replicas=2) |
facade/http-api | antispam-video-solution-facade-http | antispam-video-solution-http-api | 18155(private 覆写 8080) | HTTP(查询 / 回调) | 有 | 是(replicas=2) |
facade/http-check-api | antispam-video-solution-facade-http-check | antispam-video-solution-http-check-api | 18156(private 覆写 8080) | HTTP(提交受理) | 有 | 是(replicas=2) |
storage | antispam-video-solution-storage | antispam-video-solution-storage | 无 | Kafka Consumer(结果入库/归档) | 有 | 是(replicas=2) |
scheduler | antispam-video-solution-scheduler | antispam-video-solution-scheduler | 无 | ElasticJob 定时任务 | 有 | 否 |
console/api | antispam-video-solution-console-api | — | 8080 | 控制台 HTTP | 无(不构建) | 否 |
kubernetes.yml只包含 4 个 Deployment(dubbo-provider / http-check-api / http-api / storage,replicas=2,nsyidun);Service + Ingress 只给两个 http-api(port/targetPort均为 8080)。- 镜像仓库:
build.sh推送private-registry.yidun.internal/yidun,tagmigu-231016;kubernetes.yml拉取...:1.0.0.private—— tag 不一致,见第七节。
三、同模块启动顺序
storage—— 先保证结果消费/入库通路可用。http-check-api—— 打开受理入口,此时上游 producer 尚未开闸。http-api—— 打开查询与回调面。dubbo-provider—— 注册内部 Dubbo 服务。scheduler—— 最后启动:一启动即按 cron 推进分片与完成判定,过早启动会在业务引擎未就绪时制造失败与积压。
四、逐服务启动逻辑
facade/dubbo-provider
- 启动类:
com.netease.is.antispam.facade.dubbo.videosolution.DubboApplication。 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})+@EnableAspectJAutoProxy、@EnableFacadeAutoConfiguration、@EnableCdcDataSubscribe、@EnableRecoverComponent、@EnableApolloConfig。- 组件扫描:
@EnableFacadeAutoConfiguration→@Import(FacadeConfiguration)(位于service/business的com.netease.is.antispam.videosolution.configuration.facade,@ComponentScan(manager, service, component, integration, es, kafka) +@MapperScan)。 - 同包
facade.dubbo.videosolution.configuration.FacadeDubboConfiguration(@ComponentScan(redis, helper))。 - 数据源:
DynamicDataSourceConfiguration(Druidmaster/mirror+DynamicDataSource)。 - 配置:
app.id=antispam-vs-common,Apollo 命名空间application,antispam-vs-common。 main()无自定义;启动钩子:未发现。
facade/http-api
- 启动类:
com.netease.is.antispam.facade.http.videosolution.HttpApplication。 @SpringBootApplication+@EnableBusinessClient、@EnableAspectJAutoProxy、@EnableFacadeAutoConfiguration、@EnableCdcDataSubscribe、@EnableRateLimiter、@EnableRecoverComponent、@EnableI18nComponent、@EnableApolloConfig。- 组件扫描:
FacadeHttpConfiguration(@ComponentScan(controller, zookeeper, videosolution.kafka, redis, integration, helper))。 - 限流:
rate.limiter.node-size=1、need-demote=true、ratio=1.8、redis-key-prefix=videoSolution_http_api;Sentinelenabled=true(private 覆写为 false)。 - 配置:
server.port=18155(private 覆写 8080);app.id=antispam-vs-common。 - 启动钩子:未发现。
facade/http-check-api
- 启动类:
com.netease.is.antispam.facade.http.videosolution.check.HttpCheckApplication。 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)+@EnableBusinessClient、@EnableAspectJAutoProxy、@EnableRateLimiter、@EnableRecoverComponent、@EnableI18nComponent。无@EnableApolloConfig、无app.id。- 组件扫描:同包的
...check.configuration.FacadeHttpConfiguration—— 仅靠「与启动类同包」被 Spring Boot 默认扫描命中,无任何@Enable*AutoConfiguration显式引用;其@ComponentScan(videosolution.kafka, helper, redis, integration)。 - 限流前缀:
videoSolution_check_api。 - 配置:
server.port=18156(private 覆写 8080)。 - 启动钩子:未发现。
scheduler
- 启动类:
com.netease.is.antispam.scheduler.videosolution.SchedulerApplication。 @SpringBootApplication+@EnableBusinessClient、@EnableScheduling、@EnableSchedulerAutoConfiguration、@EnableCdcDataSubscribe、@EnableElasticJob、@EnableRecoverComponent。无@EnableApolloConfig。- 组件扫描:
@EnableSchedulerAutoConfiguration→SchedulerConfiguration(在service/business,@ComponentScan(service, manager, component, redis, es, kafka) +@MapperScan);同包SchedulerTaskConfiguration(@ComponentScan(scheduler.videosolution.tasks, videosolution.integration, videosolution.kafka,components.callback))。 - ElasticJob 作业:
machineFinishCheckTask(0 0/1)、syncDataFinishTask(0 0/1)、videoSolutionCallbackPoolRemainderCountMonitor、callbackRedisCleanWorker、activeCallbackErrorWorker、videoSolutionArchiveCleanWorker、videoSolutionLockRecordReleaseWorker、videoSolutionCheckingMonitor。 - ElasticJob ZK namespace
netease-antispam-videosolution-job。 - 启动钩子:
scheduler.YidunQosApplication。
storage
- 启动类:
com.netease.is.antispam.video.solution.checker.StorageApplication(注意包名为video.solution.checker,与模块其它部分不一致)。 @SpringBootApplication+@EnableBusinessClient、@EnableCdcDataSubscribe、@EnableStorageAutoConfiguration、@EnableRecoverComponent、@EnableApolloConfig。- 组件扫描:
StorageConfiguration(@ComponentScan(com.netease.is.antispam.video.solution,videosolution,components.callback) +@MapperScan);CheckerConfiguration(@ComponentScan(videosolution.helper))。 - 消费:
@KafkaConsumer(clusterIds={"new"}, topics={"Antispam_VideoSolution_Check"})(旧@KafkaListener已注释),concurrency=3、max.poll.records=100、recover.config.recoverThreshold=-1。 - 配置:
app.id=antispam-vs-common。 - 启动钩子:
storage.YidunQosApplication。
五、启动前置依赖
| 依赖 | 配置键 / 地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| Apollo | 无显式 meta;app.id=antispam-vs-common;apollo.bootstrap.namespaces=application,antispam-vs-common | 弱(仅 dubbo-provider/http-api/storage 接入) | application.properties |
| ZooKeeper(Dubbo) | dubbo.registry.address=zookeeper://zk-0/1/2.zookeeper.yidun-infra:2181;dubbo.registry.group=/yidun/antispam/online-new/yidun-antispam-dubbo | 阻塞 | application-private.properties |
| Redis Sentinel | spring.redis.sentinel.*(private) | 阻塞 | application-private.properties |
| TiDB | spring.datasource.*(private) | 阻塞 | application-private.properties |
| Kafka | cluster.main / cluster.log;topic Antispam_VideoSolution_Check、Antispam_VideoSolution_ActiveCallback、Antispam_Bill_ArchiveStat、yidun_request_stat;discardTopics=Antispam_VideoSolution_Business_Monitor,Antispam_Sdk_Business_Monitor | 阻塞 | application-*.properties |
| ElasticJob ZK | elastic.job.zk.serverLists(private 配成了 Kafka 地址) | 阻塞(仅 scheduler) | scheduler/application-private.properties |
| 下游视频业务引擎 | video.wall.base.url=http://antispam-business-video-facade-http-api.yidun.svc:8080 | 阻塞(提交/送检链路) | application-private.properties |
| Undertow 线程 | server.undertow.threads.io=1 / worker=2(private 覆写 io=8 / worker=128) | 弱 | application-*.properties |
六、启动参数与 Profile
- Spring profiles:容器统一
-Dspring.profiles.active=private。 - Maven profile:
default、test、online、online-jd、private。 - JAVA_OPTS:
Dockerfile全部-Xmx512m -Xms512m -XX:+UseG1GC -Dspring.profiles.active=private;而kubernetes.yml统一-Xmx1024m -Xms1024m -XX:+UseG1GC+ENABLE_SKYWALKING=true—— 两处不一致。 - base image 与仓库:
FROM private-registry.yidun.internal/yidun/base-image:jdk17;推送仓库private-registry.yidun.internal/yidun;build.shtagmigu-231016,kubernetes.ymlimage tag1.0.0.private。
七、启动期踩坑
- ElasticJob ZK 指向 Kafka:
application-private.properties里elastic.job.zk.serverLists=kafka-yidun-0/1/2...:9092,把 Kafka broker 当成 ZooKeeper 用;online/test/dev 才是真正的 ZK(nisp-zk5.../yidun-test-commonzk01...:2181)。 http-check-api与scheduler无 Apollo:两者均无@EnableApolloConfig(http-check-api连app.id都没有),配置只能重打镜像。http-check-api的FacadeHttpConfiguration仅靠「与启动类同包」被默认扫描:一旦包路径重构(启动类或配置类换包),配置会静默失效且无任何显式@Import报错。http-check-apiexclude 数据源但 properties 无spring.datasource.url:依赖 Mapper 的 Bean 将无法装配。- Dubbo 协议端口未显式配置:依赖 Dubbo 默认值,容器端口暴露与 Service 编排需自行确认。
- k8s
-Xmx1024m与 Dockerfile-Xmx512m不一致:本地/容器内构建的 jar 以 Dockerfile 的JAVA_OPTS为准,容易被误判为堆内存问题。 storage启动类包名在video.solution.checker:与模块的videosolution.*命名习惯不一致,排障时易找不到类。- 仓库镜像 tag 双轨:
build.sh推送migu-231016,kubernetes.yml拉1.0.0.private,发布脚本(podupdate.sh)需保证两者对齐。
八、跨模块前置
- 视频业务引擎:
antispam-business-video-facade-http-api.yidun.svc:8080必须先就绪,音视频送检链路才成立。 - 共享基础设施:Kafka、ZooKeeper、Redis Sentinel、TiDB 由平台提供,需先于本模块启动。
- 公共配置:Apollo
application与antispam-vs-common命名空间需预置。 - 自家 http-api 可达:回调与内部查询依赖
antispam-video-solution-facade-http-api的 Service/DNS。