外观
antispam-business-video — 点播视频内容安全
分层:业务层 | 部署单元:8 个(k8s 实部署 6 个) | 数据库:PostgreSQL(库
antispam) | base image:混合base-image:jdk8/base-image:jdk17(tagbase-250409-pg)
一、模块定位与架构
模块是易盾「点播视频」内容安全检测的服务端:受理客户提交的点播视频,入库并调度底层 AI 视频检测集群完成机审,汇聚人工审核结果后回调客户,同时负责检测数据入库、归档与计量。它不自己做模型推理,而是把"提交 → 调度 → 结果回流 → 出口"这条链路编排可靠。
架构分层
- 协议层:
facade/http-check-api/controller/submit/*(/v2/video/submit、/v3/video/check、/v4/video/submit)、facade/http-api(回调/查询)、facade/dubbo-provider/facade/dubbo-check-provider - 逻辑层:
facade/dubbo-check-provider/TargetProcessor(按 targetId 编排 9 类检测器)、service/business(VideoProxyService代理 AI 集群) - 数据层:
service/base+storage/consumer/*(VideoSubmitHandler入库、CdcConsumer消费 CDC 结果、ES 落库/回调/归档)、scheduler - 公共:
common、domain、service、facade/{dubbo-api,dubbo-check-api}、async、console/api、file/doc、file/sql
关键数据流
- 客户提交 →
AbstractSubmitController.submitPool(限流/缓冲池/重复检测) VideoCheckService.checkDubbo 预检 → KafkaAntispam_Video_SubmitVideoSubmitHandler入库 →VideoStartCheckService调度 AI(VideoProxyServiceHTTP 调/video/yidun/start|detect|recover)- AI 结果经 CDC
Antispam_Cdc_Video_New回流 →CdcConsumer分发 - ES 落库 /
VideoCallbackHandler回调 /VideoArchiveService归档 /VideoBillService计量
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
facade/dubbo-provider | antispam-business-video-facade-dubbo-provider | antispam-business-video-dubbo-provider | 无 HTTP(Dubbo) | Dubbo Provider(查询出口) | 有 | 是 |
facade/dubbo-check-provider | antispam-business-video-facade-dubbo-check-provider | antispam-business-video-dubbo-check-provider | 无 HTTP(Dubbo) | Dubbo Provider(预检编排) | 有 | 是 |
facade/http-check-api | antispam-business-video-facade-http-check-api | antispam-business-video-http-check-api | base 8510 / private 8080 | HTTP 提交/检测 | 有 | 是 |
facade/http-api | antispam-business-video-facade-http-api | antispam-business-video-http-api | base 8500 / private 8080 | HTTP 回调/查询 | 有 | 是 |
storage | antispam-business-video-storage | antispam-business-video-storage | 无 HTTP(Kafka/CDC 消费) | 消费落库/回调/归档 | 有 | 是 |
scheduler | antispam-business-video-scheduler | antispam-business-video-scheduler | 无 HTTP(定时任务) | Elastic-Job | 有 | 是 |
async | antispam-business-video-async | antispam-business-video-async | 无 HTTP(Kafka 消费) | 异步消费 | 有 | 否 |
console/api | antispam-business-video-console-api | — | — | 控制台后端骨架 | 无(不构建) | 否 |
common、domain、service/base、service/business、service、facade/dubbo-api、facade/dubbo-check-api、facade、file为非部署库模块。
三、同模块启动顺序
facade/dubbo-check-provider—TargetProcessor预检编排能力注册 ZKfacade/dubbo-provider— 查询出口 Dubbo 服务(VideoFacadeProvider)facade/http-check-api— 提交入口,预检走 Dubbo,调度依赖 AI 集群可用facade/http-api— 回调/查询入口,依赖同库 DAO 与 Dubbo 提供方storage— 消费Antispam_Video_Submit与 CDCAntispam_Cdc_Video_New,需 Kafka/DB/PG/ES/OSS 就绪scheduler— Elastic-Job 任务(VideoReviseTask等),需 ZK 与 DB
理由:Dubbo 提供方先于消费方;storage 的 CDC 消费需 CDC 源(Kafka)先可用,否则启动期订阅失败。
四、逐服务启动逻辑
video 全部启动类使用 inline
@ComponentScan,无自定义@Enable*AutoConfiguration间接层;仅存在SwaggerConfiguration这类辅助配置类。
facade/http-check-api
- 启动类:
com.netease.is.antispam.business.video.facade.http.HttpCheckApplication(facade/http-check-api/.../HttpCheckApplication.java) @SpringBootApplication(无 exclude):@EnableBusinessClient、@EnableAspectJAutoProxy、@EnableRateLimiter、@EnableRecoverComponent、@EnableI18nComponent、@EnableApolloConfig、@ComponentScan({"com.netease.is.antispam.business.video"})main():无自定义- 钩子:
ElasticRestSearchService @PostConstruct(service/base)、VideoIdCache/VideoMachineCheckCache/NosCdnService @PostConstruct - Apollo:
app.id=antispam-video_http-check,namespaces=application,antispam-audiovideo_common
facade/http-api
- 启动类:
com.netease.is.antispam.business.video.facade.http.HttpApplication @SpringBootApplication;@EnableBusinessClient、@EnableAspectJAutoProxy(proxyTargetClass=true)、@EnableTransactionManagement、@EnableCdcDataSubscribe、@EnableOssClient、@EnableRateLimiter、@EnableRecoverComponent、@EnableI18nComponent、@ComponentScan({"com.netease.is.antispam.business.video"})、@MapperScan("com.netease.is.antispam.business.video.dao")、@PropertySources({@PropertySource("classpath:video-oss.properties")})main():无自定义;Apollo:app.id=antispam-video_http
facade/dubbo-provider
- 启动类:
com.netease.is.antispam.business.video.facade.dubbo.DubboApplication - exclude:
DataSourceAutoConfiguration @EnableBusinessClient、@EnableAspectJAutoProxy(proxyTargetClass=true)、@EnableTransactionManagement、@EnableCdcDataSubscribe、@EnableOssClient、@EnableRecoverComponent、@ComponentScan({"com.netease.is.antispam.business.video"})、@MapperScan("...business.video.dao")、@PropertySources({video-oss.properties})main():无自定义;Apollo:app.id=antispam-video_dubbo
facade/dubbo-check-provider
- 启动类:
com.netease.is.antispam.business.video.facade.dubbo.check.CheckDubboApplication @SpringBootApplication、@EnableBusinessClient、@EnableAspectJAutoProxy、@ComponentScan({"com.netease.is.antispam.business.video"})、@EnableRecoverComponent、@EnableApolloConfigmain():无自定义;Apollo:app.id=antispam-video_dubbo-check
storage
- 启动类:
com.netease.is.antispam.business.video.storage.StorageApplication @SpringBootApplication;@EnableBusinessClient、@EnableAspectJAutoProxy(proxyTargetClass=true)、@EnableTransactionManagement、@EnableCdcDataSubscribe、@EnableOssClient、@EnableRecoverComponent、@ComponentScan({"com.netease.is.antispam.business.video","com.netease.is.antispam.components.callback"})、@MapperScan("...business.video.dao")、@PropertySources({video-oss.properties})main():无自定义- 钩子:
configuration/YidunQosApplication(doOffline()pause Kafka)、StorageSmartLifecycle implements SmartLifecycle(start()遍历List<WrapRecover>逐个WrapRecover::start,失败仅记日志)、多个AbstractArchiveHandler/AbstractCallbackHandler/AbstractCensorStatHandler/AbstractRequestStatHandler @PostConstruct - Apollo:
app.id=antispam-video_storage
scheduler
- 启动类:
com.netease.is.antispam.business.video.scheduler.SchedulerApplication @SpringBootApplication;@EnableBusinessClient、@EnableAspectJAutoProxy(proxyTargetClass=true)、@EnableTransactionManagement、@EnableElasticJob、@EnableOssClient、@EnableCdcDataSubscribe、@EnableRecoverComponent、@EnableApolloConfig、@ComponentScan({"com.netease.is.antispam.business.video","com.netease.is.antispam.components.callback.clean","com.netease.is.antispam.components.callback.activeretry"})、@MapperScan("...business.video.dao")、@PropertySources({video-oss.properties})main():无自定义;钩子:YidunQosApplication、VideoReviseTask @PostConstruct- Apollo:
app.id=antispam-video_scheduler
async
- 启动类:
com.netease.is.antispam.business.video.async.AsyncApplication @SpringBootApplication;@EnableAspectJAutoProxy(proxyTargetClass=true)、@EnableOssClient、@EnableRecoverComponent、@ComponentScan({"com.netease.is.antispam.business.video"})、@PropertySources({video-oss.properties})- 钩子:
com.netease.is.antispam.business.video.async.YidunQosApplication - 有 Dockerfile 但不在 kubernetes.yml;异步逻辑实际由
storage承担
console/api
- 启动类:
com.netease.is.antispam.business.video.console.api.ConsoleApplication(SwaggerConfiguration) - 无 Dockerfile、不在 kubernetes.yml
共通:所有启动类
main()无业务自定义逻辑,仅SpringApplication.run。
五、启动前置依赖
| 依赖 | 配置键/地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| ZooKeeper | zookeeper://zk-0.zookeeper.yidun-infra:2181,group /yidun/antispam/online-new/yidun-antispam-dubbo;zookeeper.config.root.path=/netease-antispam/online/config | 阻塞 | application-private.properties |
| PostgreSQL | jdbc:postgresql://<PG_HOST>:5432/antispam?connectTimeout=60&socketTimeout=130&TimeZone=Asia/Shanghai(org.postgresql.Driver) | 阻塞(http-api/http-check-api/dubbo-provider/storage/scheduler) | application-private.properties |
| Kafka / CDC | netease.kafka.producer.cluster.{main,log}.bootstrap.servers、cdc.kafka.bootstrap-servers=kafka-yidun-{0,1,2}.kafka-yidun-headless...:9092 | 阻塞(storage/scheduler 启用 @EnableCdcDataSubscribe) | application-private.properties |
| Redis Sentinel | redis0-redis-ha.yidun-infra.svc:26379,master master01 | 阻塞(限流/缓冲池) | application-private.properties |
| 视频 AI 集群 | video.check.host=http://video-service-api.yidun-ai.svc、area.ai.domain.map | 弱依赖(调度失败重试) | application-private.properties |
| OSS | classpath:video-oss.properties(@PropertySource 显式引用) | 弱依赖 | video-oss.properties |
| Elasticsearch | elasticsearch.cluster.servers.jd 等 | 弱依赖 | application.properties |
| Apollo | app.id=antispam-video_*,apollo.bootstrap.namespaces=application,antispam-audiovideo_common,apollo.cache-dir=./apollo/cache | 阻塞 | application.properties |
| 大区集群代理 | remote.clusterProxy.apiUrl=http://clusterfeature-yd.service.163.org/dataservice/cluster | 弱依赖 | application-private.properties |
六、启动参数与 Profile
-Dspring.profiles.active:默认dev;Dockerfile 与 k8s 覆盖为private- Maven profile:
buildAll.sh以-P private全量构建后遍历build.sh;模块build.sh -e <env> - JAVA_OPTS(Dockerfile):http-check-api/storage 等 jdk17 单元为
-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private;dubbo-provider(jdk8)为-Xmx512m -Xms512m ... - JAVA_OPTS(k8s 覆写):6 个 Deployment 统一
-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private(注意双空格),与 dubbo-provider Dockerfile 里的 512m 不一致 - base image(混用):
facade/dubbo-provider、facade/dubbo-check-provider、scheduler用private-registry.nis.netease.com/library/base-image:jdk8;facade/http-check-api、facade/http-api、storage用base-image:jdk17;镜像 tagbase-250409-pg - 镜像名三处:Dockerfile
ENV APP_NAME=antispam-business-video-facade-<unit>、build.sh 推private-registry.nis.netease.com/yidun/antispam-business-video-<unit>、k8s 拉private-registry.yidun.internal/yidun/antispam-business-video-<unit>:1.0.0.private - k8s 通用:namespace
yidun,replicas=2,env 注入ENABLE_SKYWALKING=true、SW_AGENT_COLLECTOR_BACKEND_SERVICES=skywalking-skywalking-oap.yidun-infra.svc:11800
七、启动期踩坑
- base image 混用 jdk8/jdk17:
dubbo-provider/dubbo-check-provider/scheduler仍是base-image:jdk8,.jar与依赖必须兼容 Java 8,新增 jdk17 专属 API 会在这三个单元启动即崩。 - 数据库是 PostgreSQL:
org.postgresql.Driver+jdbc:postgresql://<PG_HOST>:5432/antispam;分页方言与 SQL(limit/offset、::转换)与其它模块的 MySQL/TiDB 不通用,迁移 SQL 时别照抄。 @EnableCdcDataSubscribe在 http-api/dubbo-provider/storage/scheduler 生效(与 text 模块相反),CDC 源是硬前置:cdc.kafka.bootstrap-servers不可达会阻断启动。storage的StorageSmartLifecycle.start()遍历WrapRecover::start,内部catch后仅log.error;isRunning()恒返回false,可能被重复触发,恢复器启动失败的信号容易被日志淹没。async有独立 Dockerfile 却不在 kubernetes.yml;部署清单里看不到它,但异步消费逻辑实际被打包进storage,别误以为异步链路缺失。video-oss.properties用@PropertySource显式引用(非application-*.properties自动加载);该文件缺失或未打进 jar 会直接启动失败。dubbo-providerDockerfile JAVA_OPTS 是-Xmx512m,k8s env 覆写成-Xmx1024m;本地用 Dockerfile 默认值起会与线上内存口径不一致。- 无任何自定义
@Enable*AutoConfiguration间接层,扫包全部靠 inline@ComponentScan;漏写某个子包不会报错,只会静默少装配 bean(如某类 Consumer/Handler 不生效)。
八、跨模块前置
antispam-business:TargetCache/ProductCache/SecretInfoCache/TargetConfigCache(@EnableBusinessClient)——判定 secretId/businessId/targetType/策略组的前置antispam-image:VideoProxyService.getCheckParams经 Dubbo 调ImageCheckFacade取检测参数;截图检测复用图片体系antispam-video-solution:VideoProxyServiceHTTP 调/video/yidun/start|detect|recover,实际机审由底层视频 AI 集群完成(video.check.host,可按areaDomainMap切海外大区)antispam-list/antispam-rule/antispam-keyword:名单、规则、关键词检测 Dubbo 依赖antispam-bill:VideoBillService计量消息(antispam-bill-common/antispam-bill-domain)antispam-cms:控制台经VideoFacadeProvider等 Dubbo 查询检测数据与操作记录- 基础设施:ZooKeeper、Kafka、Redis Sentinel、PostgreSQL、Elasticsearch、Apollo、OSS