外观
yidun-supervision-cms — 监管侧巡检执法业务中台(巡查 → 发现 → 处置 → 整改 → 线索沉淀)
分层:业务服务层(监管审核业务中台)| 部署单元:4 个(另 1 个有启动类不构建)| 数据库:MySQL
yidun_supervision_test(master/mirror同实例)| base image:private-registry.yidun.internal/yidun/base-image:jdk8(tagbase-220214,console/api 为1.0.0.bugfix-20260119.private)
一、模块定位与架构
它服务网信监管侧对辖区内网站、公众号、微博、App、直播间的内容巡查(巡检)→ 发现违规 → 执法处置 → 整改闭环 → 线索/开源情报沉淀这条业务链,而不是单纯做数据存取:巡检任务下发给爬虫方案、爬虫回调明细、人审/机审判定、转执法、出整改报告、沉淀黑线索与情报报告,都在这套流程里。
上游是 SaaS 审核前端(antispam-cms-web)的 HTTP 调用与爬虫/开源雷达的 Kafka 消息;下游依赖反垃圾检测、爬虫方案、融媒体、名单/关键词、导出、站内信等中台能力。改坏它的后果是监管人员巡查/执法操作不可用、前端大屏数据错、对外「大屏查询数据接口」调用方受损。
架构分层
- 接入 / 协议层:
console/api(全部/api/*HTTP 入口 + Controller + 安全鉴权CmsPreAuth)、facade/dubbo-provider(承接上游antispam-*/yidun-*Dubbo 调用)、facade/http-api(对外 HTTP 门面 + 健康检查,骨架) - 业务编排层:
service/business(包com.netease.is.antispam.cms.supervision.*)- 巡检:
InspectionTaskService、AbstractInspectionTaskHandler、CallbackReceiveController - 执法:
EnforcementService、RectificationService、ReportService - 线索/情报:
SupervisionClueService、BlackClueTaskInfoService、IntelligenceReportService - 主体/区域/统计:
SubjectService、SupervisionAreaService、SupervisionStatService - 开源雷达:
OpenRadarService、OpenRadarManager - 检测:
AiAgentCheckService、NoticeMessageService
- 巡检:
- 数据访问层:
service/base(DAO/Manager/ES/NOS 组件,如ElasticRestSearchService、DynamicDataSource) - 模型与公共层:
domain(DO/BO)、common(枚举/常量/工具)、file(SQL/文档/依赖 jar 资源) - 独立进程:
cdc(CDC 消费)、scheduler(ElasticJob)
关键数据流
- 巡检任务下发 → 组装爬虫方案 → 调爬虫方案服务(
inspection.crawler.base)提交任务 - 爬虫回调
/api/crawler/*/callback(CallbackReceiveController)→ 明细/子任务落库 - 明细送检测:
antispam-business-*(文本/图片/音视频)、antispam-media-solution(融媒体)、可选AiAgentCheckService(智能检测) - 人审/机审判定 → 违规 → 转执法(
EnforcementService)→ 整改报告与举报受理 - 结果进监管线索 / 黑线索 / 开源智库情报报告;
console/api自带大屏统计与导出(yidun.export.server) - 开源雷达:Kafka
Yidun_Supervision_Spider等由OpenRadarDataConsumer消费 → 检测 → 回调 → 转存
状态机概要
- 巡检任务:
0 未开始 / 1 进行中 / 2 已结束 - 巡检明细结果:
-1 未出结果 / 0 正常 / 1 机审异常 / 2 人审异常 - 执法:
1 处理中 / 2 已处理 - 举报受理:
0 未处理 / 1 处理中 / 2 已处理 / 3 已转执法
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
console/api | yidun-supervision-console-api | private-registry.yidun.internal/yidun/yidun-supervision-console-api:1.0.0.bugfix-20260119.private | 8908 | Spring Boot Web(主应用,含 Kafka 消费 + 定时任务) | 有(另 Dockerfile-arm) | 否(kubernetes.yml 未含该 Deployment) |
facade/dubbo-provider | yidun-supervision-facade-dubbo-provider | private-registry.yidun.internal/yidun/yidun-supervision-facade-dubbo-provider:base-220214 | Dubbo(无 Web) | Dubbo Provider | 有 | 是(Deployment yidun-supervision-facade-dubbo-provider,replicas=2,镜像名写作 yidun-supervision-image-dubbo-provider:base-220214) |
cdc | yidun-supervision-cdc | private-registry.yidun.internal/yidun/yidun-supervision-cdc:base-220214 | 无 Web | Spring Boot(CDC 消费) | 有 | 否 |
scheduler | yidun-supervision-scheduler | private-registry.yidun.internal/yidun/yidun-supervision-scheduler:base-220214 | 无 Web | ElasticJob | 有 | 否 |
facade/http-api | yidun-supervision-facade-http-api | 无(不构建) | — | Spring Boot Web(对外门面/健康检查) | 无 | 否 |
构建脚本与产物部署方式
buildAll.sh:GLOBAL_ENV=private→git pull→mvn clean install -Dmaven.test.skip=true -Pprivate→ 遍历find . -name "build.sh"以-c false -p false -e private逐个构建(只覆盖上表前 4 个)buildAll-arm.sh:ARM 分支改写脚本- 每个
build.sh的固定套路:cd ../..→ 可选git pull→ 可选mvn clean install --pl <MODEL_NAME> -am -T 1C -U -Dmaven.test.skip=true -P private→cd <MODEL_NAME>→sudo docker build -t <repo>/<name>:<tag> .→sudo docker push→source ~/.zsh_private && bash $k8s_script_path/podupdate.sh <name> <tag> MODEL_NAME取值:console/api、facade/dubbo-provider、cdc、scheduler- 无前端单元、无 WAR:4 个可构建单元都是「Spring Boot fat jar +
ENTRYPOINT ["bash","docker-entrypoint.sh"]」
仓库只有一个
kubernetes.yml,其中与本模块相关的 Deployment 是yidun-supervision-facade-dubbo-provider(replicas=2、cpu 1/2、mem 1024/2048、ENABLE_SKYWALKING=true),其余段落为antispam-business-image-*的复制粘贴残留。
三、同模块启动顺序
facade/dubbo-provider—— 上游antispam-*/yidun-*契约的承接方,先注册再启其它消费者,避免 Dubbo 引用解析失败。cdc—— 纯消费进程,不依赖console/api的 HTTP 能力,可紧随其后启动以接住积压的 CDC 消息。console/api—— 主应用:承载全部/api/*,且内置 Kafka 消费与定时任务,必须早于scheduler,避免任务/消费两侧对同批数据竞争。scheduler—— ElasticJob 与console/api内置任务的职责重叠(见第七节),最后启动便于观察是否双跑。facade/http-api—— 对外门面骨架,实际不在构建链内,可忽略。
四、逐服务启动逻辑
console/api
- 启动类:
com.netease.is.antispam.cms.console.api.ConsoleApplication(console/api/src/main/java/com/netease/is/antispam/cms/console/api/ConsoleApplication.java) @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)+@EnableOssClient+@EnableApolloConfig- 无
@EnableBusinessClient(与antispam-cms的console/api最大差异:不通过 business-client 拉 PRODUCT/TARGET 配置) - 无自定义
@Enable*组合、无@Import;模块内另有一个YidunQosApplication(带@QosRegister)负责 Qos 限流注册 - Dubbo:
dubbo.application.id=yidun-supervision-console-api、registry.id=zookeeper、registry.protocol=zookeeper、registry.timeout=10000、consumer.timeout=10000(无 Dubbo 扫描注解,靠 starter 自动装配 + properties) - Web / Session:
server.port=8908、server.http2.enabled=true、server.tomcat.max-http-post-size=576716800;spring.session.store-type=redis、spring.session.redis.namespace=yidun-supervision-api、cookieNTESwebSI(max-age: 1000d);spring.servlet.multipart.max-file-size/max-request-size=500MB - 动态数据源:
master/mirror均为com.alibaba.druid.pool.DruidDataSource,druid.max-active=5 - MyBatis:
mybatis.mapper-locations=classpath*:mybatis/mappers/*.xml、type-aliases-package=com.netease.is.antispam.domain.model、mybatis-plus.configuration.mapUnderscoreToCamelCase=false - OSS:
oss.client.default-instance=yidun-supervision(protocol=https、endpoint=nos-jd.163yun.com、bucketyidun-supervision、subDomain: true、provider=netease) - Apollo:
app.id=yidun-supervision-console-api、apollo.bootstrap.enabled=true、namespaces=application、apollo.cluster=default、apollo.cache-dir=./apollo/cache - 进程内 Kafka 消费:
consumer/OpenRadarDataConsumer消费Yidun_Supervision_Spider、Yidun_Supervision_Spider_Update_Check_Res、Yidun_Supervision_Spider_Url_Transfer_Update,kafka.consume.group.id=yidun-supervision - 进程内定时任务(
console/api/.../scheduler/):OpenRadarCheckTask/OpenRadarCallbackTask/OpenRadarTransferTask/OpenRadarAsyncResultUpdateTask(继承AbstractOpenRadarPagedTask)、BlackClueExecScheduleTask、SchemeNewMsgTask、CrawlerTask、AccountExpireTask、RadarDataCountStatTask、SubjectProductMaskReviseTask、SupervisionStatMergeTask main():仅SpringApplication.run(...)- 启动钩子:无
ApplicationRunner/CommandLineRunner/SmartLifecycle/ApplicationListener;但存在多处@PostConstruct(下一节列出)
console/api 的启动期 @PostConstruct 清单
| 类 | 所在层 | 启动期作用(推断自类名/包) |
|---|---|---|
interceptor/DomainInterceptor | console/api | 初始化域名/多域判定配置 |
scheduler/AbstractOpenRadarPagedTask | console/api | 分页任务基类初始化(子任务继承) |
scheduler/CrawlerTask | console/api | 爬虫任务初始化 |
scheduler/RadarDataCountStatTask | console/api | 雷达统计任务初始化 |
scheduler/SubjectProductMaskReviseTask | console/api | 主体产品脱敏修正任务初始化 |
cache/SupervisionAreaCache | service/business | 监管区域缓存预热 |
cache/SupervisionStatCache | service/business | 监管统计缓存预热 |
supervision/check/AiAgentCheckService | service/business | 智能检测客户端初始化 |
supervision/notice/NoticeMessageService | service/business | 站内信客户端初始化 |
component/elasticsearch/ElasticRestSearchService | service/base | ES REST 客户端初始化 |
facade/dubbo-provider
- 启动类:
com.netease.is.antispam.cms.facade.dubbo.DubboApplication @SpringBootApplication(无 exclude)+@EnableAspectJAutoProxy- 无任何
@Enable*组件注解(无 OSS、无 BusinessClient、无 Apollo 注解、无@Import),Dubbo 与依赖配置全在application.properties main():仅SpringApplication.run(...)- 启动钩子:未发现
cdc
- 启动类:
com.netease.is.antispam.cms.cdc.CdcApplication @SpringBootApplication(无 exclude)+@EnableRateLimiter+@EnableOssClient- 无 Apollo 注解(依赖
apollo.bootstrap.*配置驱动);无@Import main():仅SpringApplication.run(...);启动钩子未发现
scheduler
- 启动类:
com.netease.is.antispam.cms.scheduler.SchedulerApplication @SpringBootApplication(无 exclude)+@EnableElasticJob+@EnableBusinessClient- 任务由
elastic.job.*配置驱动(ElasticJob ZK);main()仅SpringApplication.run(...);启动钩子未发现
facade/http-api(有启动类,不构建)
- 启动类:
com.netease.is.antispam.cms.facade.http.HttpApplication - 仅
@SpringBootApplication,无任何@Enable* - 仓库中只有
application-dev.properties/application-online.properties/application-test.properties(无application-private.properties) - 无
Dockerfile、无build.sh;启动钩子未发现
五、启动前置依赖
| 依赖 | 配置键 / 地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| Apollo | app.id=yidun-supervision-console-api;apollo.bootstrap.enabled=true、namespaces=application、apollo.cache-dir=./apollo/cache、cluster=default | 阻塞 | console/api/application.yml(app.id 也在其中声明) |
| MySQL | spring.datasource.master.url=jdbc:mysql://yidun-rds-mplatform-metadata-test-gz-32288.rds.cn-gz-p1.internal.:3331/yidun_supervision_test;com.mysql.jdbc.Driver + Druid max-active=5;mirror 与 master 同实例同 URL | 阻塞 | console/api/application-private.yml |
| Redis(Cluster) | spring.redis.cluster.nodes=10.200.128.26:6001,10.200.128.26:6002,10.200.130.200:6001,10.200.130.200:6002;jedis.pool.max-active=200 / max-idle=200 / min-idle=20;cluster.max-redirects=3 | 阻塞(Session + 缓存) | console/api/application-private.yml |
| Kafka | kafka.consume.group.id=yidun-supervision;private 中 app.kafka.bootstrap.servers=kafka.test.com:18081 为占位值 | 弱 | console/api/application-private.yml、application.properties |
| OSS / NOS | oss.client.default-instance=yidun-supervision,endpoint nos-jd.163yun.com,bucket yidun-supervision | 弱 | console/api/application.yml |
| Elasticsearch | service/base 的 ElasticRestSearchService 与检索查询链路 | 弱(查询期) | service/base + 各进程配置 |
| ElasticJob ZK | elastic.job.*(仅 scheduler) | 阻塞(scheduler) | scheduler/src/main/resources/* |
| 外部 HTTP(巡检/雷达/通知) | inspection.app.base=http://consult-api.nistest.service.163.org、spider.base.domain=http://spider.nistest.service.163.org、inspection.crawler.base=https://as.test.dun.163.com、inspection.callback.base=https://supervision.test.dun.163.com | 弱(调用期) | console/api/application.yml / application-private.yml |
| 外部 HTTP(导出/消息/融媒体) | yidun.export.server=http://10.200.130.200:18811、yidun.msg.api.url=http://yidun-msg-api.nistest.service.163.org、medialSolution.secretId/secretKey、textFeature.url/key | 弱(调用期) | console/api/application-private.yml |
| ISV / 鉴权 | antispam.business.isv.isvSecretId/isvSecretKey/isvOpenApiUrl/strategyConfigs.*、common.query.secretId/secretKey、supervision.isv.tokenToPassportMap | 弱(登录/联调) | console/api/application.yml |
六、启动参数与 Profile
- Spring profile:
application.yml默认spring.profiles.active: test(不是 dev);仓库含dev/test/private/pre/online - 配置形态不统一:
console/api用.yml(application-dev.yml/-test.yml/-private.yml/-pre.yml/-online.yml),cdc/scheduler/facade/dubbo-provider用.properties(均为 dev/online/test/private 四套),facade/http-api只有 dev/online/test - maven profile:
buildAll.sh固定GLOBAL_ENV=private→mvn clean install -Pprivate;各build.sh内BUILD_ENV=private - JAVA_OPTS:4 个 Dockerfile 统一
-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private;均无 SKYWALKING 注入变量(对比antispam-cms的 k8s 侧有ENABLE_SKYWALKING=true) - base image 与仓库:
private-registry.yidun.internal/yidun/base-image:jdk8(注意是 jdk8,不是 jdk17);DOCKER_REPOSITORY=private-registry.yidun.internal/yidun;console/apitag1.0.0.bugfix-20260119.private,其余三个base-220214 - 构建方式:4 个
build.sh均用sudo docker build -t <repo>/<name>:<tag> .(非 buildx),需 sudo 权限,架构一次出包 - 环境差异全部落在
application-private.yml:DB 指向yidun_supervision_test、Redis 指向10.200.128.26/10.200.130.200、yidun.msg.api.url指向 nistest、inspection.callback.base=https://supervision.test.dun.163.com、yunAccount.apiUrl=https://id-test.grow.163.com - Node 版本:不适用(无前端单元)
七、启动期踩坑
console/api/Dockerfile不COPY target,而是COPY lib/yidun-supervision-console-api.jar,并把它复制 7 份到/temp/backup1..7.jar(注释写明「临时替换一个漏洞少的 jar 用于漏洞扫描」)——镜像内容与mvn产物脱钩:改了代码但没换console/api/lib/下的 jar,打出来的仍是旧版本;而build.sh里没有任何cp/mkdir把target产物搬到lib/。Dockerfile-arm与主Dockerfile逻辑不同:Dockerfile-arm用COPY ./target/${APP_NAME}.jar /app/(正常形态),主Dockerfile用lib/那套;而build.sh只sudo docker build(不带-f,走主 Dockerfile)且非 buildx,ARM 变体实际不会被构建。master与mirror指向同一个 RDS(URL、用户名、密码全同)——读写分离只是表单上的存在,压测时看不到分流。console/api内置 Kafka 消费 + 定时任务,与独立scheduler单元职责重叠:OpenRadarCheckTask/OpenRadarCallbackTask/OpenRadarTransferTask/OpenRadarAsyncResultUpdateTask、BlackClueExecScheduleTask、SchemeNewMsgTask都在console/api/src/main/java/.../scheduler/下,扩console/api副本会导致同批数据双跑(无 ElasticJob 分片保护)。application.yml默认 profile 是test:漏传-Dspring.profiles.active=private会静默连测试库/测试 Redis;与antispam-cms的dev默认值不同,跨模块排障时容易记混。facade/http-api有启动类却既无 Dockerfile 也无application-private.properties:以-Dspring.profiles.active=private启动会取不到 profile 配置。facade/dubbo-provider只有@SpringBootApplication+@EnableAspectJAutoProxy:无 OSS / 无 Apollo 注解 / 无 BusinessClient,配置全靠 properties 与apollo.bootstrap.*;注解层面看不出依赖,Bean 缺失时无编译期提示。- 无 Runner 但
@PostConstruct遍布核心链路:DomainInterceptor、CrawlerTask、AbstractOpenRadarPagedTask、SupervisionAreaCache、SupervisionStatCache、AiAgentCheckService、NoticeMessageService、ElasticRestSearchService都在 Bean 初始化阶段做事(ES 客户端、区域/统计缓存、HTTP 客户端),故障表现为「启动卡住 / 启动即报网络错」而非业务异常。 k8s引用的镜像名与build.sh产出一致但不完整:kubernetes.yml里写的是yidun-supervision-image-dubbo-provider:base-220214,而build.sh产出yidun-supervision-facade-dubbo-provider:base-220214(多了image-与facade-的差异),需人工对齐 tag/名字。private里 Kafka 地址是占位值(app.kafka.bootstrap.servers=kafka.test.com:18081)——console/api的雷达消费在 private 环境实际不可用,验证只能靠cdc/上游消息。
八、跨模块前置
- 上游触发方:
antispam-cms-web(SaaS 审核前端,全部/api/*,inferred);爬虫方案经/api/crawler/*/callback回调(extracted);开源雷达经 KafkaYidun_Supervision_Spider*投递(extracted);外部大屏调用方(file/doc/大屏查询数据接口.md的对接方,inferred)。 - 下游依赖(extracted,来自 pom.xml / 代码引用):
antispam-crawler-solution—— 提交巡检爬虫任务、查询爬取结果antispam-media-solution—— 融媒体检测(medialSolution.secretId/Key)antispam-business-*—— 文本/图片/音视频反垃圾检测antispam-list/antispam-keyword—— 名单与关键词yidun-cms—— 账号权限与菜单 Dubbo 接口yidun-export—— 异步导出yidun-message—— 站内信 SDKantispam-bill—— 账单/用量yidun-ai-agent——AiAgentCheckService智能检测(inferred)
- 配置与鉴权:Dubbo consumer(
yidun-supervision-console-api)访问上述服务;CmsPreAuth负责接口鉴权并与yidun-cms的菜单/权限数据联动。 - 基础设施硬前置:Apollo → MySQL → Redis(Cluster + Session)三者缺失即
console/api启动失败;Kafka、OSS、ES、ElasticJob ZK 为弱依赖,缺失只影响对应功能。 - 跨模块顺序建议:
antispam-crawler-solution、yidun-cms、yidun-message、yidun-export先于本模块可用;antispam-business-*与antispam-list/antispam-keyword至少要在首次巡检/检测前就绪。