外观
antispam-stream-solution — AIGC 流式输出内容审核(流式会话、片段送检、回调)
分层:解决方案层(Facade + MQ + Scheduler + Console) | 部署单元:5 个(有 Dockerfile) | 数据库:未发现数据源配置 | base image:private-registry.nis.netease.com/library/base-image:jdk17
一、模块定位与架构
业务定位:antispam-stream-solution 面向 AIGC 大模型的流式输出(打字机式逐段返回)做实时内容审核,按会话(session)维护流转状态,把输出片段(snippet)逐段送文本/关键词引擎检测,并在命中时触发回调与审核动作。
架构分层:
| 层 | 子模块目录 | 职责 |
|---|---|---|
| 协议层 | facade/http-check-api、facade/dubbo-provider | 同步检测入口、对外 Dubbo 服务(经 ShenYu 网关暴露) |
| 逻辑层 | service/business、service/base、common、domain、mq、scheduler | 会话状态机与 Redis 编排、DAO/Manager、模型与 DTO、Kafka 消费与 ElasticJob |
| 数据层 | Redis Cluster、Kafka、Elasticsearch(多集群)、ZooKeeper | 会话与片段状态、异步总线、检索、Dubbo/ElasticJob 协调 |
关键数据流:
- 业务方 →
http-check-api(8282):以会话为单位提交流式审核请求,会话状态写 Redis。 - 输出片段继续到达 →
http-check-api/mq:把片段投递 Kafka(Antispam_Stream_Session_Storage、Antispam_Stream_Callback、Antispam_Stream_Left_Snippets_Check)。 mq消费片段:组装上下文 → 调文本检测 HTTP(/text/async-check)与antispam-keyword的KeywordCheckRemoteService(Dubbo)。- 命中/会话结束 →
Antispam_Stream_Active_Callback主动回调审核结果。 scheduler(ElasticJob,设计上)负责会话自动关闭与主动纠偏(autoCloseSessionJob、autoCorrectActiveSessionJob)。dubbo-provider(20880):经 ShenYu(appName=aigc-solution)对外提供 AIGC 审核 Dubbo 服务。
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
facade/http-check-api | antispam-stream-solution-facade-http-check | antispam-stream-solution-http-check-api | 8282 | HTTP(同步/流式检测入口) | 有 | 模块根未发现 kubernetes.yml |
facade/dubbo-provider | antispam-stream-solution-facade-dubbo-provider | antispam-stream-solution-dubbo | 20880(dubbo.protocol.port 显式) | Dubbo Provider(ShenYu 暴露) | 有 | 同上(未发现) |
mq | antispam-stream-solution-mq | antispam-stream-solution-mq | 无 | Kafka Consumer + ElasticJob | 有 | 同上(未发现) |
scheduler | antispam-stream-solution-scheduler | antispam-stream-solution-scheduler | 无 | ElasticJob 定时任务 | 有 | 同上(未发现) |
console/api | antispam-stream-solution-console-api | antispam-stream-solution-console-api | 8080 | 控制台 HTTP | 有 | 同上(未发现) |
- 模块根目录未发现
kubernetes.yml,K8s 清单由外部维护。 console/api虽有 Dockerfile 与build.sh,但其ConsoleConfiguration的@MapperScan被注释、也无业务扫描配置,属可发布但无功能的骨架。scheduler同理:SchedulerConfiguration的@ComponentScan包名前缀写错(见第七节),实际为空跑。
三、同模块启动顺序
mq—— 先把片段消费与回调出队通路建好,避免片段堆积。dubbo-provider—— 注册 Dubbo 服务(port=20880)并接入 ShenYu,供同步审核调用。http-check-api—— 打开对外检测入口;此时消费侧已就绪。scheduler/console/api—— 当前为空骨架,可最后启动或暂不部署。
四、逐服务启动逻辑
facade/http-check-api
- 启动类:
com.netease.is.antispam.stream.solution.facade.http.check.HttpCheckApplication。 - 仅
@SpringBootApplication:无 exclude、无任何@Enable* main()无自定义逻辑。- 实际生效的配置类是与启动类同包的
facade.http.check.configuration.FacadeHttpConfiguration(靠默认包扫描命中):@Configuration+@EnableAspectJAutoProxy(proxyTargetClass=true)+@EnableBusinessClient+@EnableRecoverComponent+@EnableRateLimiter+@EnableI18nComponent+@ComponentScan({"com.netease.is.antispam.stream.solution","com.netease.is.antispam.components.callback","com.netease.is.platform.components.rate.limiter"})。 - Dubbo 消费:
dubbo.registry.id=streamCheckRegistry、consumer.timeout=5000、connections=20、retries=0、loadbalance=shortestResponsePlus、filter=remoteStatusStat。 - 配置:
server.port=8282;app.id=antispam-stream-solution_http-check,Apollo 命名空间application,antispam-stream-solution-common(无@EnableApolloConfig,靠apollo.bootstrap.enabled=true)。 - 启动钩子:未发现。
facade/dubbo-provider
- 启动类:
com.netease.is.antispam.stream.solution.facade.dubbo.DubboApplication。 - 仅
@SpringBootApplication+@EnableAspectJAutoProxy+@EnableOssClient。 - 配置类:同包
facade.dubbo.configuration.FacadeDubboConfiguration=@Configuration+@EnableBusinessClient+@ComponentScan(recover, redis, repo, service, facade.dubbo.provider)。 - Dubbo:
dubbo.protocol.port=20880、dubbo.scan.basePackages=...facade.dubbo.provider、dubbo.provider.filter=qos-access、dubbo.protocal.register=false(拼写错误,该属性不生效)。 - ShenYu:
shenyu.register.registerType=http、shenyu.client.dubbo.props.contextPath=/aigc-solution、appName=aigc-solution。 - 业务:
business.client.options.businessTypes=TEXT,UINFO;app.id=antispam-stream-solution_dubbo。 main()无自定义;启动钩子:未发现。
mq
- 启动类:
com.netease.is.antispam.stream.solution.mq.MqApplication(仅@SpringBootApplication)。 - 配置类:同包
mq.configuration.MqConfiguration=@Configuration+@EnableAspectJAutoProxy(proxyTargetClass=true)+@EnableBusinessClient+@EnableRecoverComponent+@EnableElasticJob+@ComponentScan({"com.netease.is.antispam.stream.solution","com.netease.is.antispam.components.callback"})—— Kafka 消费与 ElasticJob 由这里启动。 - Kafka consumer:
group=antispam-stream-solution-mq、concurrency=3、auto.offset.reset=earliest、enable.auto.commit=false、max.partition.fetch.bytes=10485760;topicAntispam_Stream_Session_Storage、Antispam_Stream_Callback、Antispam_Stream_Left_Snippets_Check、Antispam_Stream_Active_Callback。 - Dubbo 消费:
dubbo.registry.id=streamMqRegistry、short.default-timeout=2000、long.default-timeout=5000。 - 配置:
app.id=antispam-stream-solution_mq。 - 启动钩子:
mq.configuration.MqQosConfiguration(@QosRegister),其doOffline()只打印日志、不真正停止 Kafka 消费者。
scheduler
- 启动类:
com.netease.is.antispam.stream.solution.scheduler.SchedulerApplication。 @SpringBootApplication+@EnableScheduling(无 Apollo、无 Dubbo、无 Kafka 配置)。- 配置类:同包
scheduler.configuration.SchedulerConfiguration,其@ComponentScan({"com.netease.is.antispam.**antispam**.stream.solution.service", "...manager"})—— 包名前缀多打一层antispam,实际不扫描任何 Bean;@MapperScan被注释 → 空跑。 main()无自定义;启动钩子:未发现。
console/api
- 启动类:
com.netease.is.antispam.stream.solution.console.api.ConsoleApplication(仅@SpringBootApplication)。 - 配置类:
console.api.configuration.ConsoleConfiguration,@MapperScan同样被注释,无业务扫描。 - 配置:
application.properties只有server.port=8080与 mybatis 配置。 main()无自定义;启动钩子:未发现。
五、启动前置依赖
| 依赖 | 配置键 / 地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| Apollo | app.id=antispam-stream-solution_http-check/_dubbo/_mq;apollo.bootstrap.enabled=true;ns application,antispam-stream-solution-common | 弱(但承载阻塞项,见下) | application.properties |
| ZooKeeper(Dubbo) | online zookeeper://nisp-zk5..9.service.163.org:2181;dubbo.registry.group=/yidun/jiande-online/dubbo | 阻塞 | application-*.properties / Apollo |
| Redis 集群 | spring.redis.cluster.nodes=10.196.180.49:6907,...;spring.redis.password=ad3528623aa5 | 阻塞 | application-*.properties |
| Kafka | online yidun-jd-nrkafka01..05.service.163.org:9092 | 阻塞 | Apollo / application-*.properties |
| Elasticsearch | 多集群 elasticsearch.multiple.*;useDefaultWhenMiss=true、config.enableListener=true、changeDataCapture.enable=false | 弱 | application.properties |
| ElasticJob ZK | elastic.job.zk.server-lists=nisp-zk5..9:2181;namespace=antispam-stream-scheduler-jobs-online | 阻塞(仅 mq/scheduler) | application-*.properties |
| 下游文本检测 | 易盾文本检测 HTTP /v{n}/text/check 与 /text/async-check(TextChecker) | 阻塞 | Apollo |
| 下游关键词服务 | antispam-keyword Dubbo KeywordCheckRemoteService | 阻塞 | Apollo |
| ShenYu | shenyu.register.registerType=http(dubbo-provider) | 弱 | application.properties |
六、启动参数与 Profile
- Spring profiles:容器统一
-Dspring.profiles.active=private。 - Maven profile:
default、test、online、private。 - JAVA_OPTS:
http-check-api/dubbo-provider/mq=-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private;console/api/scheduler=-Xmx512m(同款 GC/Profile)。 - base image 与仓库:
FROM private-registry.nis.netease.com/library/base-image:jdk17;推送仓库private-registry.nis.netease.com/yidun;build.shtagmigu-231016。 - 资源过滤:
src/main/filter/{default,test,online,private}.properties;占位符@filter.sentry.app.name@/@filter.sentry.cluster.name@。 - 资源目录缺 private:只有
application-{dev,test,online}.properties,没有application-private.properties(见第七节)。
七、启动期踩坑
- 没有
application-private.properties:而buildAll.sh用-P private、Dockerfile 用-Dspring.profiles.active=private→ private 环境下没有任何 profile 专属文件被加载,只能靠 Apollo 兜底。 dubbo.registry.address缺失:application.properties里 Redis/Kafka 只有池参数与组件开关,没有bootstrap-servers/registry.address;若 Apollo 未下发,http-check-api/dubbo-provider会因缺dubbo.registry.address启动失败。scheduler的@ComponentScan包名多一层antispam:com.netease.is.antispam.antispam.stream.solution.*不匹配任何实际包,@MapperScan又被注释 → 该单元空跑,定时任务不生效。dubbo.protocal.register=false拼写错误:属性名应为dubbo.protocol.register,当前写法不生效,服务仍会注册。- Redis 用集群而非哨兵:
spring.redis.cluster.nodes指向 IP 列表(非 Sentinel),与其它模块的 Sentinel 模式不同,配置模板勿混用。 MqQosConfiguration.doOffline()不停消费者:滚动发布时旧 Pod 仍可能在拉取消息,造成重复消费,需业务侧幂等兜底。console/api有 Dockerfile 但无业务扫描配置:可成功发布镜像,但接口不可用,容易被误判为「已上线」。- ElasticJob 配置 key 用连字符:
elastic.job.zk.server-lists(而非 video/livevideo/media 的驼峰serverLists),跨模块复用配置模板时易漏改。
八、跨模块前置
- 文本检测引擎:易盾文本检测 HTTP 接口(
/text/check、/text/async-check)与antispam-keyword的 DubboKeywordCheckRemoteService必须先可用,否则片段送检全量失败。 - ShenYu 网关:
dubbo-provider注册依赖 ShenYu Admin(registerType=http),网关未就绪时对外不可见。 - Redis Cluster / Kafka / ZooKeeper / Elasticsearch:由平台提供,需先于本模块启动。
- Apollo:
antispam-stream-solution-common命名空间必须下发 Dubbo 注册地址与 Kafka 地址,否则服务无法启动。