外观
yidun-model-evaluation — 大模型评测平台
分层:平台/评测层 | 部署单元:7 个(4 个有
build.sh,3 个仅 Dockerfile) | 数据库:MySQL(库yidun_model_evaluation) | base image:private-registry.nis.netease.com/library/base-image:jdk17(console/scheduler/platform-api/database)·harbor.nisp-qzbeta.service.163.org/bsd-public/yd-java-app:v3(dubbo-provider/http-api/mq),tagbase-250409
一、模块定位与架构
模块承担易盾「大模型评测平台」的服务端职责:把待测大模型接入后,用题库批量发起评测、记录逐题明细、汇总出评测报表,并按分钟级节奏把待评测任务分发到执行线程池。
它同时对外暴露控制台后端、平台 HTTP 接口与 Dubbo 接口,属带前端入口的平台型服务;评测任务的并发分发与报表统计逻辑,直接决定评测吞吐和最终结果口径。
架构分层
- 协议层:
console/api(控制台后端,注册 ShenYu 网关)、facade/platform-api(外部平台 HTTP)、facade/http-api(HTTP 接口)、facade/dubbo-provider(Dubbo Provider)、mq(Kafka 生产/消费) - 逻辑层:
service/business(EvaluationTaskService、ModelAccessService、AntispamCheckService等评测编排与模型接入) - 数据层:
service/base(MyBatis-Flex DAO)、support/database(Flyway 一次性迁移 Job) - 调度层:
scheduler(ElasticJob 周期分发评测任务) - 公共/支撑:
common、domain、facade/dubbo-api、console/web、support/codegen、support/test、file
关键数据流(评测任务)
- 控制台 →
console/api(8080)提交评测请求;外部平台 →facade/platform-api(8081) service/business落库评测任务与题库,任务状态置为「进行中」scheduler的EvaluateDispatchWorker每分钟扫「进行中」任务- 按
id % shardingTotalCount == shardingItem分片,过滤掉EvaluationContextManager已标记isRunning的任务 - 命中的任务投入
poolSize=15的线程池执行EvaluateTask(重试用EvaluateRetryTask) EvaluateTask经 Apolloyidun-model-eval-model-providers取被测模型 provider,调用后写评测明细ReportGenerateWorker汇总明细生成报表;AiGenQuestionTaskDispatchWorker分发生成题目子任务- 结果经 HTTP/Dubbo 接口回读,或经
mq的主题流转
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml/Helm |
|---|---|---|---|---|---|---|
console/api | yidun-model-evaluation-console-api | yidun-model-evaluation-console-api | 8080(private/k8s)/8081(dev) | 控制台后端 HTTP | 有 | 是(file/charts/templates/console-api.yaml) |
scheduler | yidun-model-evaluation-scheduler | yidun-model-evaluation-scheduler | 61123(chart)/无业务端口 | ElasticJob 调度 | 有 | 是(file/charts/templates/scheduler.yaml) |
support/database | yidun-model-evaluation-support-database | yidun-model-evaluation-database | 无(Job,web-application-type=none) | Flyway 迁移 Job | 有 | 是(file/charts/templates/database-init-job.yaml) |
facade/platform-api | yidun-model-evaluation-facade-platform-api | yidun-model-evaluation-facade-platform-api | 8081 | 平台 HTTP | 有(无 build.sh) | 否 |
facade/http-api | yidun-model-evaluation-facade-http | 无(无 build.sh,轻舟构建) | 8081 | HTTP 接口 | 有(无 build.sh) | 否 |
facade/dubbo-provider | yidun-model-evaluation-facade-dubbo-provider | 无(无 build.sh,轻舟构建) | 无 HTTP(Dubbo 20880) | Dubbo Provider | 有(无 build.sh) | 否 |
mq | yidun-model-evaluation-mq | 无(无 build.sh,轻舟构建) | 无 HTTP | Kafka 生产/消费 | 有(无 build.sh) | 否 |
说明:
common、domain、service/base、service/business、facade/dubbo-api为非部署库模块;console/web(前端骨架)、support/codegen(代码生成工具)、support/test、file不部署、不参与镜像构建。
有 build.sh 的 4 个单元(buildAll.sh 的 find . -name build.sh 命中范围):
console/api/build.sh(MODEL_NAME=console/api)scheduler/build.sh(MODEL_NAME=scheduler)support/database/build.sh(MODEL_NAME=support/database)facade/platform-api/src/build.sh(MODEL_NAME=platform-api)
三、同模块启动顺序
support/database— Flyway 迁移建表;是其余所有单元读写yidun_model_evaluation的硬前置,必须最先跑完并退出facade/dubbo-provider— Dubbo 服务注册到 ZK,供控制台/外部调用;先于消费方注册console/api/facade/platform-api/facade/http-api— 三个入口互不依赖,可并行启动scheduler— ElasticJob 需要 ZK 与 DB 就绪;评测分发依赖任务表已被入口写入,晚于 HTTP 入口更安全mq— Kafka 消费单元,位点提交依赖 topic 与 DB 就绪,最后启动
理由:数据层 DDL 必须先于一切读写;Dubbo 提供方必须先于消费方注册;scheduler/mq 驱动或消费入口写入的数据,故排在入口层之后。
四、逐服务启动逻辑
console/api
- 启动类:
com.netease.yidun.model.evaluation.console.api.ConsoleApplication(console/api/src/main/java/.../ConsoleApplication.java) @SpringBootApplication:无 exclude@Enable*:@EnableAspectJAutoProxy、@EnableTransactionManagement、@EnableApolloConfig、@EnableOssClient(com.netease.is.antispam.components.oss.configuration.EnableOssClient)@Import的 Configuration:ConsoleConfiguration(同包configuration/)@Import({ServiceConfiguration, MapperConfiguration, CacheConfiguration, OkHttpConfiguration})- 自身
implements WebMvcConfigurer,@Bean validator():Hibernate Validator,hibernate.validator.fail_fast=false(校验全部字段) ServiceConfiguration:@ComponentScan("com.netease.yidun.model.evaluation.business.service")MapperConfiguration:@MapperScan("com.netease.yidun.model.evaluation.base.mapper")
main():仅SpringApplication.run(ConsoleApplication.class, args),无自定义逻辑- 启动钩子:无 Runner / Listener;
validator()随容器刷新装配 - 端口:
application.propertiesserver.port=8080,application-dev.properties覆盖为8081 - Apollo:
app.id=yidun-model-evaluation_console
facade/dubbo-provider
- 启动类:
com.netease.yidun.model.evaluation.facade.dubbo.DubboApplication(facade/dubbo-provider/src/main/java/.../DubboApplication.java) - 注解:
@SpringBootApplication(无 exclude)+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig+@EnableDubbo @Import:FacadeDubboConfiguration→@Import({ServiceConfiguration, MapperConfiguration})validator()用fail_fast=true(首个校验失败即返回,与其它单元不同)
- Dubbo 配置:
dubbo.scan.basePackages=com.netease.yidun.model.evaluation.facade.dubbo.provider、dubbo.protocol.port=20880、dubbo.application.qos-enable=false、dubbo.provider.payload=83886080 main():仅SpringApplication.run(...);启动钩子:无- 注意:源码中未发现
@DubboService实现类,provider 包当前为空壳,启动后不会注册任何 Dubbo 服务
facade/http-api
- 启动类:
com.netease.yidun.model.evaluation.facade.http.HttpApplication(facade/http-api/src/main/java/.../HttpApplication.java) - 注解:
@SpringBootApplication+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig @Import:FacadeHttpConfiguration→@Import({ServiceConfiguration, MapperConfiguration, CacheConfiguration}),validator()fail_fast=falsemain():无自定义;启动钩子:无;server.port=8081- Apollo ns:
application,yidun-model-eval-datasource,yidun-model-eval-common,yidun-model-evaluation-model-providers
facade/platform-api
- 启动类:
com.netease.yidun.model.evaluation.facade.platform.PlatformApiApplication(facade/platform-api/src/main/java/.../PlatformApiApplication.java) - 注解:
@SpringBootApplication+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig+@EnableOssClient @Import:FacadePlatformApiConfiguration→@Import({ServiceConfiguration, MapperConfiguration, CacheConfiguration}),validator()fail_fast=falsemain():无自定义;启动钩子:无;server.port=8081;Apollo ns 含shenyu
scheduler
- 启动类:
com.netease.yidun.model.evaluation.scheduler.SchedulerApplication(scheduler/src/main/java/.../SchedulerApplication.java) - 注解:
@SpringBootApplication+@EnableElasticJob(com.cxytiandi.elasticjob.annotation)+@EnableAspectJAutoProxy+@EnableTransactionManagement+@EnableApolloConfig @Import:SchedulerConfiguration→@Import({ServiceConfiguration, MapperConfiguration, CacheConfiguration, OkHttpConfiguration})main():无自定义;启动钩子:configuration/YidunQosApplication(@QosRegister+implements QosApplication,doOnline()/doOffline()仅打日志)- 任务(
tasks/,implements SimpleJob,@ElasticJobConf):EvaluateDispatchWorker(评测任务分发):@PostConstruct init()建ThreadPoolExecutor(poolSize, poolSize, 0ms, SynchronousQueue, AbortPolicy);doExecute先判getActiveCount()==poolSize则跳过本轮并记日志AiGenQuestionTaskDispatchWorker(AI 生成题目分发)ReportGenerateWorker(报表生成)
- Job 配置(
application.properties):三者 cron 均0 0/1 * ? * *、overwrite=true、disabled=false - Apollo:
app.id=yidun-model-evaluation_scheduler
support/database
- 启动类:
com.netease.yidun.model.evaluation.support.database.FlywayApplication(support/database/src/main/java/.../FlywayApplication.java) @SpringBootApplication,implements CommandLineRunner;main():SpringApplication.run(...)run()自定义逻辑:打日志 →Thread.sleep(5000)→context.close()→System.exit(0)(一次性 Job 语义,跑完主动退出)- 配置:
spring.main.web-application-type=none、spring.flyway.enabled=true、spring.flyway.locations=classpath:db/migration、spring.flyway.baseline-on-migrate=true、spring.datasource.driver-class-name=com.mysql.jdbc.Driver - 启动钩子:无(
CommandLineRunner即入口)
mq
- 启动类:
com.netease.yidun.model.evaluation.mq.MqApplication(mq/src/main/java/.../MqApplication.java) - 注解:裸
@SpringBootApplication(无任何@Enable*) @Import:MqConfiguration→@ComponentScan("com.netease.is.antispam.yidun-model-evaluation")(外部包名,骨架未改)+@MapperScan("com.netease.is.antispam.yidun-model-evaluation.dao")KafkaConfiguration:producerFactory、producerTemplate、consumerFactory、kafkaManualAckListenerContainerFactory(MANUAL_IMMEDIATE,并发 1)、kafkaBatchAckListenerContainerFactory(setBatchListener(true),BATCH)- 消费者:
consumer/ExampleConsumer(@Component+@EnableKafka+@KafkaListener(topics="topic-xxx", containerFactory="kafkaManualAckListenerContainerFactory"),示例占位) main():无自定义;启动钩子:无
五、启动前置依赖
| 依赖 | 配置键/地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| Apollo | apollo.meta(dev http://yd-apollo-config.nistest.service.163.org);ns application,shenyu,yidun-model-eval-datasource,yidun-model-eval-common,yidun-model-eval-log-record;apollo.bootstrap.enabled=false(dev/private 覆盖为 true)、apollo.cache-dir=./apollo/cache | 阻塞 | application.properties / application-{dev,private}.properties |
| MySQL | spring.datasource.url=jdbc:mysql://10.196.38.56:33066/yidun_model_evaluation(chart),驱动 com.mysql.cj.jdbc.Driver,Tomcat 池 max-active=10 | 阻塞(console/platform-api/http-api/scheduler/database) | application-*.properties / chart ConfigMap |
| Redis Cluster | dev spring.redis.cluster.nodes=10.196.38.116:6301,10.196.38.115:6302,10.196.38.102:6303;chart redis-cluster0-headless.yidun-infra.svc:6379 | 阻塞(本地缓存/限流相关组件) | application-*.properties / chart |
| ZooKeeper | chart zookeeper.yidun-infra.svc:2181;elastic.job.zk.server-lists、elastic.job.zk.namespace | 阻塞(Dubbo 注册、ElasticJob 分片) | application-*.properties / chart |
| Kafka | custom.log4j2.kafka.topic=Yidun_Antispam_Log、log-record.kafka-mq.topic=Union_Log_Record;kafka-yidun-0.kafka-yidun-headless.yidun-infra:9092 | 弱依赖(日志与 log-record 上报) | application-*.properties / chart |
| OSS | @EnableOssClient(console / platform-api) | 弱依赖 | application.properties |
| 被测模型 provider | Apollo namespace yidun-model-eval-model-providers | 弱依赖(缺失则评测无法取回结果) | Apollo |
| ShenYu 网关 | shenyu.register.serverLists=http://10.196.2.89:30892、shenyu.register.registerType=http | 弱依赖(仅 console/platform-api,外部路由) | chart ConfigMap |
六、启动参数与 Profile
-Dspring.profiles.active:application.properties默认dev;各 Dockerfile 的JAVA_OPTS覆盖为private;Helmglobal.profile=private,Deployment 用-Dspring.profiles.active={{ .Values.global.profile }}追加- Maven profile(根 pom 仅定义):
default(activeByDefault,deploy.env=default)、test(deploy.env=test)、online(deploy.env=online);无privateprofile,故-P private会回退到default,src/main/filter/${deploy.env}.properties实际取default.properties - Maven 构建命令:
mvn clean install --pl <module> -am -T 1C -U -Dmaven.test.skip=true -P ${BUILD_ENV} -Dcustom.finalName=<image>(console/scheduler/database/platform-api 的build.sh带-Dcustom.finalName) JAVA_OPTS:console/scheduler/platform-api/dubbo-provider/http-api/mq 为-Xmx1024m -Xms1024m -XX:+UseG1GC(轻舟单元走XMX_CONFIG=512);support/database为-Xmx64m -Xms64m -XX:+UseG1GC- base image 与仓库:
- 公共镜像
private-registry.nis.netease.com/library/base-image:jdk17(console/scheduler/platform-api/database),ENTRYPOINT ["bash","docker-entrypoint.sh"] - 轻舟镜像
harbor.nisp-qzbeta.service.163.org/bsd-public/yd-java-app:v3(dubbo-provider/http-api/mq),MAIN_CLASS=org.springframework.boot.loader.JarLauncher、JVM_EXTRA_CONFIG=-Dspring.profiles.active=privization - 构建仓库
private-registry.nis.netease.com/yidun,k8s 拉取private-registry.yidun.internal/yidun - tag:
base-250409(support/database为base-250409-0.0.4)
- 公共镜像
- 构建产物推送:
build.sh用docker buildx build --platform linux/amd64,linux/arm64 --push,末行source ~/.zsh_private && bash $k8s_script_path/podupdate.sh <image> <tag> buildAll.sh:GLOBAL_ENV=online,以find . -name "build.sh"遍历并以-c false -p false -e online逐个执行(即不再重复编译)
七、启动期踩坑
- 根 pom 未定义 maven
privateprofile,而 Dockerfile /build.sh默认-P private→deploy.env回退到default,resource filter 实际取default.properties;要打 private 资源需先确认 profile 是否被真正激活。 facade/http-api、facade/dubbo-provider、mq有 Dockerfile 但无build.sh,buildAll.sh用find . -name build.sh遍历,这三者不会被构建;它们 base image 是轻舟yd-java-app:v3,需外部流水线单独构建。facade/platform-api/Dockerfile的ENV APP_NAME=yidun-model-evaluation-facade/platform-api(含斜杠),且该 pom 未把<finalName>绑定custom.finalName(console/scheduler/database 才有),COPY ./target/${APP_NAME}.jar路径很可能对不上;另外facade/platform-api/src/build.sh位于src/下,cd ../..只到facade/,相对路径比其它单元多错一级。mq的MqConfiguration扫的是外部包名com.netease.is.antispam.yidun-model-evaluation,ExampleConsumer监听占位 topictopic-xxx——该单元目前不消费任何真实业务消息。scheduler三个 Job 的 cron 均为0 0/1 * ? * *(每分钟)、disabled=false;多副本时靠 ElasticJob 的 ZK 分片保证单实例执行,误删/改elastic.job.zk.namespace会导致重复执行。support/database依赖System.exit(0)结束进程,容器内必须配restartPolicy: Never(chartdatabase-init-job.yaml已设),否则会被反复拉起、重复迁移。facade/dubbo-provider虽@EnableDubbo且配了dubbo.scan.basePackages,但没有@DubboService实现类,启动后不会注册任何 Dubbo 服务;误以为它提供接口会扑空。console/api的server.portbase 为 8080、application-dev.properties覆盖为 8081;chart 的 Service/探针统一指 8080,本地用 dev profile 起服务会与探针口径不一致。EvaluateDispatchWorker用SynchronousQueue+AbortPolicy,且doExecute先判getActiveCount()==poolSize直接跳过;任务堆积时表现为「整轮不派发」而非报错,需看日志evaluate dispatch worker is busy才能发现。
八、跨模块前置
启动前须已就绪的其它模块/服务:
- 基础设施(硬前置):ZooKeeper(Dubbo registry + ElasticJob)、MySQL(库
yidun_model_evaluation)、Redis Cluster、Apollo(yidun-model-eval-*命名空间) yidun命名空间内的 Helm chart:本模块 唯一提供 Helm chart(file/charts/) 的单元,console-api.yaml/scheduler.yaml/database-init-job.yaml依赖common.mysql/redis/zookeeper/kafka/apollo/shenyu一组 values- ShenYu 网关:
console/api/platform-api经 HTTP 注册,网关未就绪则外部路由不可用(弱依赖) - 被测大模型服务:评测执行时经 Apollo
yidun-model-eval-model-providers指向的 provider 调用,未配置则评测任务全部失败(弱依赖) - Kafka:日志 topic
Yidun_Antispam_Log与 log-record topicUnion_Log_Record上报(弱依赖)