外观
antispam-livevideo-solution — 直播音视频内容安全解决方案(含直播音频 gRPC 流式接入)
分层:解决方案层(Facade + Dubbo + gRPC + Scheduler + Storage) | 部署单元:7 个(有 Dockerfile) | 数据库:TiDB | base image:private-registry.nis.netease.com/library/base-image:jdk17
一、模块定位与架构
业务定位:antispam-livevideo-solution 面向直播场景,受理直播视频与直播音频两类流式内容,负责直播流/音频流的接流、切片分帧、逐片送机审、断流与回调;其中直播音频另有一条 gRPC 长连接流式接入通道。
架构分层:
| 层 | 子模块目录 | 职责 |
|---|---|---|
| 协议层 | facade/http-check-api、facade/http-api、facade/dubbo-provider、facade/dubbo-check-provider、facade/grpc-stream | 提交受理、查询与回调、内部 Dubbo 读写/检测服务、gRPC 流式接入 |
| 逻辑层 | service/business、service/base、common、domain、scheduler | 直播编排与状态机、DAO/Manager、模型与 DTO、定时补偿与监控 |
| 数据层 | TiDB、Kafka、Redis Sentinel、Elasticsearch、OSS | 任务/流水持久化、消息总线、缓存与连接数控制、结果检索、证据存储 |
关键数据流:
- 客户端 / 直播平台 →
http-check-api:提交直播审核任务,建立直播会话并投递 Kafka。 - 直播音频另一路:
grpc-stream以 gRPC 长连接接收音频流片段 → 投递Antispam_Live_Audio_Grpc_Evidence。 scheduler:推进切片送检、完成判定、回调池积压监控。- 各切片 → 下层直播视频/直播音频业务引擎检测。
- 结果消息 →
storage(netease.kafka.consumer.cluster.new+tsNew+tsNewGZ)消费入库并生成流水号(分布式 ID)。 - 判定完成 →
Antispam_LiveSolution_ActiveCallback(+_Backup)回调客户;断流经antispam.livesolution.cancel-url=http://av-api.yidun-ai.svc/av/yidun/stop。
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
facade/dubbo-provider | antispam-livevideo-solution-facade-dubbo-provider | antispam-livevideo-solution-dubbo-provider | Dubbo 协议端口(默认) | Dubbo Provider | 有 | 是(replicas=2) |
facade/dubbo-check-provider | antispam-livevideo-solution-facade-dubbo-check-provider | antispam-livevideo-solution-dubbo-check-provider | Dubbo 协议端口(默认) | Dubbo Provider(检测) | 有 | 是(replicas=2) |
facade/http-api | antispam-livevideo-solution-facade-http | antispam-livevideo-solution-http-api | 18165 | HTTP(查询 / 回调) | 有 | 是(replicas=2) |
facade/http-check-api | antispam-livevideo-solution-facade-http-check | antispam-livevideo-solution-http-check-api | 18166 | HTTP(同步提交受理) | 有 | 是(replicas=2) |
facade/grpc-stream | antispam-livevideo-solution-facade-grpc | antispam-livevideo-solution-facade-grpc-stream | 9090(gRPC) | gRPC 流式接入 | 有 | 否 |
scheduler | antispam-livevideo-solution-scheduler | antispam-livevideo-solution-scheduler | 无 | ElasticJob 定时任务 | 有 | 是(replicas=2) |
storage | antispam-livevideo-solution-storage | antispam-livevideo-solution-storage | 无 | Kafka Consumer(结果入库) | 有 | 是(replicas=2) |
facade/grpc-demo | antispam-livevideo-solution-facade-grpc-demo | — | — | gRPC 示例 | 无(不构建) | 否 |
console/api | antispam-livevideo-solution-console-api | — | 8080 | 控制台 HTTP | 无(不构建) | 否 |
console/web | — | — | — | 控制台前端(空骨架) | 无(不构建) | 否 |
kubernetes.yml含 6 个 Deployment(dubbo-provider / dubbo-check-provider / http-check-api / http-api / scheduler / storage,各replicas=2)。grpc-stream有 Dockerfile 但无build.sh,且不在kubernetes.yml—— 既不被buildAll.sh构建,也不随清单部署,需人工处理。- Service/Ingress 只给两个 http-api,且
port: 80/targetPort: 80,与容器实际监听 18165/18166 不一致。 - base image 仓库与镜像仓库:
private-registry.nis.netease.com/library/base-image:jdk17;推送private-registry.nis.netease.com/yidun;build.shtagbase-250409,kubernetes.ymlimage tag1.0.0.private。
三、同模块启动顺序
storage—— 先让结果消费/入库与分布式 ID 通路就绪。dubbo-provider+dubbo-check-provider—— 注册 Dubbo 服务,其中dubbo-check-provider是同步提交链路的服务提供方,必须先于http-check-api。http-check-api—— 打开同步提交受理(同步链路,下游 Dubbo 未就绪会直接超时)。http-api—— 打开查询与回调面。scheduler—— 最后开闸,推进切片与回调补偿。grpc-stream(独立) —— 与主链路解耦,只需 Redis 就绪即可单独启动;迁移/发布时注意其 60s 优雅下线。
四、逐服务启动逻辑
facade/dubbo-provider
- 启动类:
com.netease.is.antispam.livevideosolution.facade.dubbo.provider.DubboApplication。 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})+@EnableCdcDataSubscribe、@EnableAspectJAutoProxy、@EnableDubboAutoConfiguration(→@Import(DubboConfiguration))、@EnableBusinessClient、@EnableAsync、@EnableRecoverComponent。无@EnableApolloConfig。- 组件扫描:
DubboConfiguration(@ComponentScan(manager, redis, service, component, es, kafka, integration) +@MapperScan)。 - 数据源:
DynamicDataSourceConfiguration(Druidmaster/mirror+DynamicDataSource)。 - 配置:
business.client.autoStart=false。 main()无自定义;启动钩子:未发现。
facade/dubbo-check-provider
- 启动类:
com.netease.is.antispam.livesolution.facade.dubbo.check.DubboCheckApplication(注意包名为livesolution)。 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)+@EnableAspectJAutoProxy、@EnableDubboCheckAutoConfiguration(→@Import(DubboCheckConfiguration))、@EnableBusinessClient、@EnableRecoverComponent、@EnableConfigurationProperties、@EnableApolloConfig。- 组件扫描:
DubboCheckConfiguration的@ComponentScan({"com.netease.is.antispam.liveaudio"})+@MapperScan("com.netease.is.antispam.liveaudio.dao")—— 扫的是 liveaudio 包,跨模块复用直播音频的 DAO。 - 配置:
app.id=antispam-lvs_dubbo-check。 - 启动钩子:未发现。
facade/http-api
- 启动类:
com.netease.is.antispam.facade.http.livevideosolution.api.HttpApplication。 @SpringBootApplication+@EnableCdcDataSubscribe、@EnableBusinessClient、@EnableAspectJAutoProxy、@EnableFacadeAutoConfiguration(→@Import(FacadeConfiguration))、@EnableRateLimiter、@EnableRecoverComponent、@EnableI18nComponent、@EnableApolloConfig、@EnableOssClient。- 组件扫描:
FacadeConfiguration(在service/business:@ComponentScan(redis, kafka, service, manager, component, es, integration) +@MapperScan(livevideosolution.dao));同包FacadeHttpConfiguration(@ComponentScan(controller, zookeeper, monitor, kafka, redis, helper) +@MapperScan)。 - 限流前缀:
liveVideoSolution_http_api。 - 配置:
server.port=18165;app.id=antispam-lvs_http;OSS private 用 S3 协议:oss.client.provider=s3、yidun-video-7d-sgtc-1314975822.endpoint=cos.ap-singapore.myqcloud.com。 - 启动钩子:未发现。
facade/http-check-api
- 启动类:
com.netease.is.antispam.facade.http.livevideosolution.check.HttpCheckApplication。 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)+@EnableBusinessClient、@EnableAspectJAutoProxy、@EnableFacadeHttpCheckAutoConfiguration(→@Import(FacadeHttpCheckConfiguration))、@EnableRateLimiter、@EnableRecoverComponent、@EnableI18nComponent、@EnableApolloConfig。- 组件扫描:
FacadeHttpCheckConfiguration(在service/business:@ComponentScan(redis, kafka, component, check));同包FacadeHttpConfiguration(@ComponentScan(check.controller, check.zookeeper, monitor, kafka, redis, helper))。 - 配置:
server.port=18166;app.id=antispam-lvs_http-check。 - 启动钩子:未发现。
scheduler
- 启动类:
com.netease.is.antispam.scheduler.livevideosolution.SchedulerApplication。 @SpringBootApplication+@EnableCdcDataSubscribe、@EnableBusinessClient、@EnableScheduling、@EnableElasticJob、@EnableRecoverComponent、@EnableSchedulerAutoConfiguration(→SchedulerConfiguration)。无@EnableApolloConfig。- 组件扫描:
SchedulerConfiguration(@ComponentScan(manager, redis, service, component, es, integration) +@MapperScan);同包SchedulerTaskConfiguration(@ComponentScan(scheduler.livevideosolution.tasks, livevideosolution.kafka, redis,components.callback))。 - ElasticJob ZK:private =
zk-0/1/2.zookeeper.yidun-infra:2181(正确);namespacenetease-antispam-livevideosolution-job。 - 启动钩子:
scheduler.YidunQosApplication。
storage
- 启动类:
com.netease.is.antispam.livevideosolution.storage.StorageApplication。 @EnableConfigurationProperties({ProxySeaConfig.class})+@EnableCdcDataSubscribe、@EnableBusinessClient、@SpringBootApplication、@EnableRecoverComponent、@EnableStorageAutoConfiguration(→StorageConfiguration)、@EnableDistributeId。无@EnableApolloConfig。- 组件扫描:
StorageConfiguration(@ComponentScan(manager, redis, service, component, storage.consumer.cache,components.callback, kafka, es, integration, monitor, check, storage.config) +@MapperScan)。 - 消费:
netease.kafka.consumer.cluster.new+tsNew+tsNewGZ(max.poll.records=100/200);recover.config.recoverThreshold=-1、versionAdaptEnable=true。 - 分布式 ID:
distribute.id.namespace=antispam-lvs-tsRecord-id、startTime=1722441600000(private 的 ZK 用yidun-test-commonzk01..03:2181)。 - 其它:
spring.main.allow-bean-definition-overriding=true。 - 启动钩子:
storage.YidunQosApplication。
facade/grpc-stream
- 启动类:
com.netease.is.antpc.livevideosolution.stream.StreamApplication。 @ComponentScan({"com.netease.is.antispam.facade.grpc","com.netease.is.antispam.livevideosolution.redis"}) + @SpringBootApplication + @EnableBusinessClient(无 Apollo / 无 Dubbo / 无 Cdc/Oss/Recover)。- 配置:
server.port=9090、grpc.server.port=${server.port}、grpc.server.security.enabled=false;live.grpc.nos.bucket=yidun-audio-15d、live.grpc.topic=Antispam_Live_Audio_Grpc_Evidence、business.client.autoStart=false。 - gRPC 拦截器:
AuthServerInterceptor、ConnectionCountFilter(io.grpc.ServerTransportFilter,连接数限制依赖 Redis)。 - 启动钩子:
facade.grpc.livevideosolution.stream.YidunQosApplication。doOffline()遍历StreamInfo.getConnectionMap()逐个safeComplete,并redisCommonService.decrease(AuthServerInterceptor.CONNECTION_REDIS_KEY_PREFIX + targetId),随后Thread.sleep(60000L)。 main()无自定义。
五、启动前置依赖
| 依赖 | 配置键 / 地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| Apollo | 仅 antispam-lvs_http / antispam-lvs_http-check / antispam-lvs_dubbo-check 接入 | 弱 | 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 | Druid initial-size=50 / max-active=50 | 阻塞 | application-private.properties |
| Kafka | topic Antispam_LiveSolution_Evidence_New、Antispam_Live_Audio_Evidence_New、Antispam_Live_Audio_Grpc_Evidence、yidun_live_video_control、Antispam_LiveSolution_ActiveCallback(+_Backup)、Antispam_LiveSolution_Barrage、Antispam_Sdk_Business_Monitor | 阻塞 | application-*.properties |
| Elasticsearch | elasticsearch-yidun-master.yidun-infra.svc:9200 | 弱 | application-*.properties |
| OSS | 弱依赖;http-api private 走 S3 协议(腾讯云 COS 新加坡) | 弱 | application.properties |
| ElasticJob ZK | elastic.job.zk.serverLists(private 正确) | 阻塞(仅 scheduler) | scheduler/application-private.properties |
| 下游业务引擎 | live.wall.base.url=http://antispam-business-livevideo-facade-http-api.yidun.svc;live.audio.base.url=http://antispam-business-liveaudio-facade-http-api.yidun.svc | 阻塞 | application-private.properties |
| 断流接口 | antispam.livesolution.cancel-url=http://av-api.yidun-ai.svc/av/yidun/stop | 弱 | application-private.properties |
六、启动参数与 Profile
- Spring profiles:容器统一
-Dspring.profiles.active=private。 - Maven profile:
default、test、online、online-jd、xjp-online、xjp-test、private。 - JAVA_OPTS:
dubbo-provider/http-api/http-check-api/dubbo-check-provider/storage/grpc-stream=-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private;scheduler=-Xmx512m。kubernetes.yml统一-Xmx1024m。 - base image 与仓库:
private-registry.nis.netease.com/library/base-image:jdk17;推送private-registry.nis.netease.com/yidun;build.shtagbase-250409,kubernetes.ymlimage tag1.0.0.private。 - ARM 构建:
buildAll-arm.sh会把 registry 前缀替换为private-registry.yidun.internal/arm/yidun、给docker build加--platform linux/arm64,结束后git checkout -- .还原。
七、启动期踩坑
dubbo-check-provider扫com.netease.is.antispam.liveaudio包与 DAO:目标环境若没有 liveaudio 的库表/Mapper,@MapperScan会失败或装配出空 Bean。storage设了spring.main.allow-bean-definition-overriding=true:同名 Bean 会被静默覆盖,配置/依赖冲突时不报错、行为异常。storage分布式 ID 的 ZK 指向 test 环境:yidun-test-commonzk01..03:2181,private 环境可能生成重复或异常 ID。grpc-stream既无build.sh也不在kubernetes.yml:且doOffline()固定Thread.sleep(60000L),Pod 的terminationGracePeriodSeconds必须 > 60s,否则被强杀导致连接/计数未清理。- k8s Service 端口与容器不符:两个 http-api 的 Service
targetPort: 80,而容器监听 18165/18166,探针/转发会失配。 http-check-api是同步提交链路:下游dubbo-check-provider未注册或超时,客户提交会直接超时报错(不是异步降级)。dubbo-provider/scheduler/storage/grpc-stream无 Apollo:改配置只能重打镜像。http-apiprivate 的 OSS 走 S3 协议(腾讯云 COS 新加坡):与其它单元默认的网易 NOS 不同(oss.client.provider=s3、...endpoint=cos.ap-singapore.myqcloud.com),跨环境迁移时凭据与桶需单独配置,否则证据上传递交失败。grpc-stream的连接数控制强依赖 Redis:ConnectionCountFilter(io.grpc.ServerTransportFilter)依赖 Redis 计数,Redis 不可达时会拒绝新增连接。
八、跨模块前置
- 下游直播业务引擎:
antispam-business-livevideo-facade-http-api.yidun.svc与antispam-business-liveaudio-facade-http-api.yidun.svc必须先就绪,切片送检链路才成立。 - 断流服务:
av-api.yidun-ai.svc/av/yidun/stop需可用,否则直播结束后无法正确断流。 - 共享基础设施:Kafka、ZooKeeper、Redis Sentinel、TiDB、Elasticsearch、OSS 由平台提供,需先于本模块启动。
- 公共配置与镜像仓库凭据:
antispam-lvs_*三个 Apollo app 的命名空间需预置;build.sh依赖~/.zsh_private与podupdate.sh。