外观
yidun-ai-agent — 数字人审核与大模型应用平台
分层:平台/AI 应用层 | 部署单元:4 个可构建(
console/api、facade/http-api、scheduler、facade/dubbo-provider),另 2 个(ai-dhs-worker、mq)无构建产物 | 数据库:MySQL / GoldenDB | base image:private-registry.nis.netease.com/library/base-image:jdk17· 轻舟harbor.nisp-qzbeta.service.163.org/bsd-public/yd-java-app:v3(tagbase-250409)
一、模块定位与架构
模块是易盾面向数字人场景的 AI 应用平台:一边承接数字人账号/审核事件(Kafka 消费 + 向 ZK 注册的 worker 集群),一边把 LLM 能力(LangChain4j + 多家 provider)包装成对外的控制台后端、HTTP 接口与 Dubbo 服务。
它同时是「大模型接入 + 数字人任务分发」两类链路的交汇点:worker 的在线注册与任务派发逻辑直接决定数字人审核任务的分发效率与吞吐。
架构分层
- 协议层:
console/api(控制台后端,ShenYu 注册)、facade/http-api(限流 HTTP 接口)、facade/dubbo-provider(Dubbo 服务,ApiKeyProvider)、mq(Kafka 骨架) - Worker 层:
ai-dhs-worker(WorkerApplication,向 ZK 注册自身能力与负载,暴露/snapshot) - 逻辑层:
service/business(...business.dhs数字人链路、components.langchainLLM 接入、ManagedWorkerClient选 worker) - 调度层:
scheduler(ElasticJob:数字人分配、LLM 请求量统计、样本验证) - 支撑层:
models/yidun-ai-agent-models-langchain4j-inner-ai、-qianfan(LLM adapter,不部署)、common、domain、facade/dubbo-api、console/web、support/*
关键数据流(数字人审核 / LLM 请求)
- CMS 发出数字人账号事件 → Kafka topic
DhsKafkaConstants.CMS_DIGITAL_HUMAN_ACCOUNT_TOPIC console/api的CmsDigitalHumanEventConsumer(@KafkaConsumer(clusterIds={"default"}))消费- 消息交
CmsDigitalHumanEventHandlerManager.getHandler(type)按类型分派到对应CmsDigitalHumanEventHandler - 各环境
ai-dhs-worker启动即通过ManagedWorkerServerImpl把自己注册到 ZK scheduler的CmsDigitalHumanDispatchJob经managedWorkerClient.getWorkers()拉 ZK 中的 worker,挑最小负载节点派发- worker 侧用
multiAgentExecutor线程池执行多 Agent 流程,LLM 调用由LangChainConfiguration+ provider adapter 完成 LlmRequestPreMinuteStatWorker/LlmRequestPreHourStatWorker统计请求量,SampleValidateTaskWorker做样本验证
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml/Helm |
|---|---|---|---|---|---|---|
console/api | yidun-ai-agent-console-api | yidun-ai-agent-console | 8080 | 控制台后端 HTTP | 有 | 否(仓库内无清单,外部流水线部署) |
facade/http-api | yidun-ai-agent-facade-http | yidun-ai-agent-http | 8081 | HTTP 接口(限流) | 有 | 否(同上) |
scheduler | yidun-ai-agent-scheduler | yidun-ai-agent-scheduler | 无业务端口 | ElasticJob 调度 | 有 | 否(同上) |
facade/dubbo-provider | yidun-ai-agent-facade-dubbo-provider | 无(无 build.sh,轻舟构建) | 无 HTTP(Dubbo 20880) | Dubbo Provider | 有 | 否(同上) |
ai-dhs-worker | ai-dhs-worker | — | 8085(dev,application.properties) | Dubbo Provider + Worker 注册 | 无(不构建) | 否 |
mq | yidun-ai-agent-mq | — | 无 HTTP | Kafka 生产/消费 | 无(不构建) | 否 |
说明:
models/yidun-ai-agent-models-langchain4j-inner-ai、-qianfan、common、domain、service/*、facade/dubbo-api、console/web、support/*为非部署库/工具模块。ai-dhs-worker与mq目录下无Dockerfile,不在buildAll.sh的构建范围内。
有 build.sh 的 3 个单元(buildAll.sh 的 find . -name build.sh 命中范围):
console/api/build.sh(MODEL_NAME=console/api、BUILD_ENV=private)facade/http-api/build.sh(MODEL_NAME=facade/http-api、BUILD_ENV=private)scheduler/build.sh(MODEL_NAME=scheduler、BUILD_ENV=private)
仅 Dockerfile、无 build.sh 的 1 个单元:facade/dubbo-provider(轻舟 yd-java-app:v3,需外部流水线构建)
三、同模块启动顺序
support/database(若存在 Flyway 单元)— 建表;是全部读写库单元的硬前置ai-dhs-worker— 注册到 ZK,是scheduler派发数字人任务的必要目标console/api/facade/dubbo-provider/facade/http-api— 三个入口互不依赖,可并行scheduler— ElasticJob 依赖 ZK 与 DB;CmsDigitalHumanDispatchJob需要 ZK 中已有 worker 才有派发目标
理由:worker 必须先注册,调度才有可选节点;Dubbo 提供方先于消费方;入口层与调度层共享同一 DB,需 DB 先就绪。
四、逐服务启动逻辑
console/api
- 启动类:
com.netease.yidun.ai.agent.console.api.ConsoleApplication(console/api/src/main/java/.../ConsoleApplication.java) - 注解:
@SpringBootApplication(无 exclude)+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig+@EnableOssClient @Import:ConsoleConfiguration→@Import({ServiceConfiguration, MapperConfiguration, CacheConfiguration, LangChainConfiguration, ManagedWorkerClientConfiguration, ZkConfigConfiguration, DhsNotifyConfiguration})implements WebMvcConfigurer,@Bean validator()(fail_fast=false)- 额外
@Bean:DhsNotifyManager(ZkConfig zkConfig)(@ConditionalOnMissingBean,需 ZkConfig 就绪)、DhsStatService()(@ConditionalOnMissingBean)
- Kafka 消费:
consumer/CmsDigitalHumanEventConsumer(@KafkaConsumer(clusterIds={"default"}, topics={CMS_DIGITAL_HUMAN_ACCOUNT_TOPIC})→CmsDigitalHumanEventHandlerManager分派) - Kafka 配置:
netease.kafka.consumer.groupId=antispam-ai-agent、netease.kafka.consumer.concurrency=3、...[default].enable.auto.commit=false、...[default].auto.offset.reset=earliest main():无自定义;启动钩子:无显式 Runner;端口 8080;Apolloapp.id=yidun-ai-agent_console
facade/dubbo-provider
- 启动类:
com.netease.yidun.ai.agent.facade.dubbo.DubboApplication(facade/dubbo-provider/src/main/java/.../DubboApplication.java) - 注解:
@SpringBootApplication+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig+@EnableDubbo @Import:FacadeDubboConfiguration→@Import({ServiceConfiguration, MapperConfiguration}),validator()fail_fast=false- 服务:
provider/ApiKeyProvider(@DubboService(version="1.0.0") implements ApiKeyFacade,各方法带@ShenyuDubboClient(path="/apiKey/...")) - Dubbo 配置:
dubbo.protocol.port=20880、dubbo.application.qos-enable=false、dubbo.scan.basePackages=com.netease.yidun.ai.agent.facade.dubbo.provider main():无自定义;启动钩子:无
facade/http-api
- 启动类:
com.netease.yidun.ai.agent.facade.http.HttpApplication(facade/http-api/src/main/java/.../HttpApplication.java) - 注解:
@SpringBootApplication+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig+@EnableRateLimiter(com.netease.is.platform.components.rate.limiter) @Import:FacadeHttpConfiguration→@Import({ServiceConfiguration, MapperConfiguration, CacheConfiguration, LangChainConfiguration}),validator()fail_fast=falsemain():无自定义;启动钩子:无;端口 8081;Apollo ns 含yidun-ai-agent-redis- 注意:pom 的
private-besprofile 可把spring-boot-starter-tomcat换成宝兰德 BES
scheduler
- 启动类:
com.netease.yidun.ai.agent.scheduler.SchedulerApplication(scheduler/src/main/java/.../SchedulerApplication.java) - 注解:
@SpringBootApplication+@EnableElasticJob+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig @Import:SchedulerConfiguration→@Import({ServiceConfiguration, MapperConfiguration, CacheConfiguration, LangChainConfiguration, ManagedWorkerClientConfiguration})+@Bean DhsRedisHelper()main():无自定义;启动钩子:configuration/YidunQosApplication(QoS 注册)- 任务(
tasks/,@ElasticJobConf):CmsDigitalHumanDispatchJob(数字人分配,cron0 0/1 * ? * *,但disabled=true)LlmRequestPreMinuteStatWorker(10 * * * * ?)LlmRequestPreHourStatWorker(0 10 * * * ?)SampleValidateTaskWorker(*/10 * * * * ?)
CmsDigitalHumanDispatchJob通过managedWorkerClient.getWorkers()取 ZK 中 worker 并选最小负载派发
ai-dhs-worker(无 Dockerfile,需自行打包)
- 启动类:
com.netease.yidun.ai.dhs.worker.WorkerApplication(ai-dhs-worker/src/main/java/.../WorkerApplication.java) - 注解:
@SpringBootApplication+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig+@EnableDubbo - 配置类:
config/WorkerConfiguration@EnableConfigurationProperties(MangedZookeeperConfig.class)@Import({ServiceConfiguration, MapperConfiguration, LangChainConfiguration, ZkConfigConfiguration, DhsNotifyConfiguration})@ComponentScan(basePackages={"com.netease.yidun.ai.agent.business.dhs"})@PostConstruct init()强校验:Assert.hasText(saasDomain/aiAgentDomain/aiAgentSk),任一为空即启动失败@Bean ManagedWorkerServerImpl(MangedZookeeperConfig, port, "dev".equals(activeProfile))(向 ZK 注册)@Bean ManagedWorkerOnlineFilter/ManagedWorkerOfflineFilter(implements BaseFilter,QoS 上下线回调)@Bean multiAgentExecutor():ThreadPoolExecutor(core=max(threadNum,5), max=2×core, 60s, LinkedBlockingQueue(100), CallerRunsPolicy),线程名ai-action-multi-agent-%d@Bean DhsRedisHelper()
- 另有
config/RedissonConfiguration建RedissonClient;WorkerController提供/snapshot main():无自定义;devserver.port=8085
mq(无 Dockerfile)
- 启动类:
MqApplication(mq/src/main/java/.../MqApplication.java)为裸@SpringBootApplication MqConfiguration扫描com.netease.is.antispam.yidun-ai-agent(外部包名,占位)ExampleConsumer监听topic-xxx(示例占位);KafkaConfiguration同 model-evaluation 的模板
五、启动前置依赖
| 依赖 | 配置键/地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| Apollo | console app.id=yidun-ai-agent_console,ns application,shenyu,yidun-ai-agent-datasource,yidun-ai-agent-model-providers,yidun-ai-agent-oss,log-record-client,dhs-common;worker app.id=yidun-ai-dhs,ns application,dhs-common,yidun-ai-agent-datasource,yidun-ai-agent-dubbo,yidun-ai-agent-model-providers;dev meta http://yd-apollo-config.nistest.netease.com,online http://yd-apollo-meta.service.163.org | 阻塞 | application.properties / application-*.properties |
| MySQL / GoldenDB | mysql-connector-java + com.goldendb:gdb-mysql-connector-java;driver com.mysql.cj.jdbc.Driver | 阻塞(console/scheduler/worker/dubbo) | application-*.properties |
| Redis Cluster | dev spring.redis.cluster.nodes=10.196.38.116:6301,10.196.38.115:6302,10.196.38.102:6303;online 10.196.38.180:6107,...(密码 188cf6da6f46) | 阻塞(缓存、限流) | application-*.properties |
| Redisson | RedissonConfiguration(worker 独有,建 RedissonClient) | 阻塞(worker) | application-*.properties |
| ZooKeeper | Dubbo registry group:dev /yidun/antispam/test/yidun-antispam-dubbo、online /yidun/jiande-online/dubbo;DHS worker yidun.ai.dhs.zk.config.rootPath(dev /yidun-ai-dhs-dev);ElasticJob elastic.job.zk.server-lists | 阻塞(Dubbo + ElasticJob + worker 注册) | application-*.properties / Apollo dhs-common |
| Kafka | console netease.kafka.consumer.cluster.[default];业务 topic DhsKafkaConstants.CMS_DIGITAL_HUMAN_ACCOUNT_TOPIC | 弱依赖(消费失败不阻断启动) | application.properties |
| OSS / TOS | @EnableOssClient(console);Apollo ns yidun-ai-agent-oss | 弱依赖 | Apollo |
| LLM 平台 | LangChainConfiguration + ProviderConfig(ns yidun-ai-agent-model-providers,qianfan / inner-ai 两 adapter)+ models/*;腾讯 / 百度 / 奇安信 SDK | 弱依赖(调用失败为运行时降级) | Apollo + models/* |
六、启动参数与 Profile
-Dspring.profiles.active:application.properties默认dev;各 Dockerfile 的JAVA_OPTS覆盖为private- Maven profile(根 pom):
default(activeByDefault,deploy.env=default)、test、online,根 pom 无private;console/api与facade/http-api另有private-bes(把 tomcat 换 BES,deploy.env=default) buildAll.sh:GLOBAL_ENV=private,遍历find . -name build.sh(仅console/api、facade/http-api、scheduler)build.sh默认BUILD_ENV=private,mvn clean install --pl <module> -am -T 1C -U -Dmaven.test.skip=true -P private,随后docker buildx build --platform linux/amd64,linux/arm64 --push+podupdate.shJAVA_OPTS:-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private- filter 资源:
ai-dhs-worker/src/main/filter/只有default.properties(空)、online.properties、test.properties(无private.properties) - base image / 仓库:
private-registry.nis.netease.com/library/base-image:jdk17(console/scheduler/http-api);轻舟harbor.nisp-qzbeta.service.163.org/bsd-public/yd-java-app:v3(dubbo-provider);构建仓库private-registry.nis.netease.com/yidun;tagbase-250409
七、启动期踩坑
ai-dhs-worker的WorkerConfiguration.@PostConstruct init()强校验saasDomain/aiAgentDomain/aiAgentSk,这些值来自 Apollo namespacedhs-common;该 namespace 未就绪或未开apollo.bootstrap.enabled=true时Assert立即失败、进程退出。- 根 pom 无
privatemaven profile,而build.sh默认-P private→deploy.env回退default;ai-dhs-worker又没有private.properties,私有机房需自行补 filter 或显式指定 profile。 ai-dhs-worker、mq、facade/dubbo-provider不在buildAll.sh构建范围(前两者无 Dockerfile,后者有 Dockerfile 但无build.sh);直接跑buildAll.sh不会产出这三个镜像。- 各环境
dubbo.registry.group不同(dev/yidun/antispam/test/...、online/yidun/jiande-online/...),group 误配会把服务注册到错误分组,消费方按同名 group 找不到 provider。 console/api的 Kafka 消费配置auto.offset.reset=earliest+enable.auto.commit=false,位点未提交会从头重放,误操作会重复处理数字人账号事件。CmsDigitalHumanDispatchJob默认disabled=true;即便开启,若 ZK 中没有任何ai-dhs-worker注册,getWorkers()返回空,任务只是空转不报错,易被误判为「调度正常」。console/api的DhsNotifyManager依赖ZkConfig,其 ZK rootPath 必须与 worker 注册用的 rootPath 一致,否则通知与注册对不上。dubbo-provider的ApiKeyProvider各方法带@ShenyuDubboClient(path=...),ShenYu 未注册时业务调用不可达,但服务本身启动正常。worker的multiAgentExecutor用LinkedBlockingQueue(100)+CallerRunsPolicy,队列满时任务落到提交线程(Dubbo/调度线程)执行,可能拖慢上游;观察线程名ai-action-multi-agent-*可定位。
八、跨模块前置
- 基础设施(硬前置):ZooKeeper(Dubbo registry + ElasticJob + worker 注册)、MySQL/GoldenDB、Redis Cluster(含 worker 的 Redisson)、Apollo(
yidun-ai-agent-*、dhs-common命名空间) antispam-cms:数字人账号事件由 CMS 发出到CMS_DIGITAL_HUMAN_ACCOUNT_TOPIC,CMS 未就绪则该链路无输入(弱依赖)- LLM 平台:
yidun-ai-agent-model-providers指向的 qianfan / inner-ai provider 未配置时,Agent 流程调用失败(弱依赖) - ShenYu 网关:
facade/dubbo-provider通过@ShenyuDubboClient暴露路由(弱依赖) - CMS Dubbo API:worker pom 依赖
antispam-cms-facade-dubbo-api,消费方需保证 CMS 侧接口可用(弱依赖)