外观
antispam-image — 图片检测执行与图库配置中枢
分层:检测引擎层 | 部署单元:2 个(另有 3 个有启动类但不构建) | 数据库:TiDB
antispam| base image:base-image:jdk17(构建 tagbase-250409-pg)
一、模块定位与架构
本模块是易盾图片检测(image-ai)能力的执行与配置中枢:接收上游图片/视频帧提交,调用 AI 检测平台完成色情、暴恐、涉政、广告、违禁、二维码等多模型识别,再用本地缓存的图片名单库(md5 库 / 相似库)与标签配置做二次裁决,输出「正常/嫌疑/确定」等级与命中详情供上游拦截或进入人工审核。
架构分层:
- 协议层:
facade/dubbo-check-api(ImageCheckFacade/CustomModelCheckFacade接口)+facade/dubbo-api、facade/dubbo-check-provider(检测执行)、facade/dubbo-provider(管理写接口)、facade/http-api - 逻辑层:
service/business(检测编排、handler 链、配置/图库同步)、service/base(DAO/Manager) - 数据层:
domain(实体/BO/DTO)、common(枚举/常量/工具) - 支撑:
scheduler、console/api(骨架)
关键数据流:
ImageCheckProvider.imageCheck→ImageCheckerManager.get(targetId)取检测器TargetImageChecker.check(URL / BASE64 分支)→ImageCheckServiceImpl.checkUrl/checkBase64(HTTP 调 AI v5 平台,携带 key/appCode/types/strategyAssembly)buildBoResponse组装命中 →ImageHandlerManager.handle- preHandlers → handlers 顺序处理 → afterHandlers(名单/动作/标签调整)
- 返回
ImageCheckResponse,上游据此拦截 / 人审 / 计费
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
facade/dubbo-check-provider | antispam-image-facade-dubbo-check-provider | antispam-image-dubbo-check-provider | Dubbo 随机(-1) | Dubbo Provider(检测执行) | 是 | 是(replicas=2) |
facade/dubbo-provider | antispam-image-facade-dubbo-provider | antispam-image-dubbo-provider | Dubbo 随机(-1) | Dubbo Provider(管理写接口) | 是 | 是(replicas=2) |
facade/http-api | antispam-image-facade-http | — | 未配置 | HTTP | 无(不构建) | 否 |
scheduler | antispam-image-scheduler | — | 无 | 定时任务 | 无(不构建) | 否 |
console/api | antispam-image-console-api | — | 未配置 | 控制台后端 | 无(不构建) | 否 |
k8s 镜像地址
private-registry.yidun.internal/yidun/<镜像名>:1.0.0.private;http-api/scheduler/console/api有启动类但无 Dockerfile,不参与buildAll.sh。
三、同模块启动顺序
facade/dubbo-provider— 管理写接口与策略数据同步接收(StrategyDataSyncSpi)先就绪。facade/dubbo-check-provider— 检测执行,启动期全量加载图库/配置,耗时较长,需在业务调用前完成。
理由:check-provider 的 @PostConstruct 全量扫表灌缓存,若与写接口同时上线,需先保证写侧与 DB 就绪,避免加载到半成品配置。其余为骨架,不参与线上顺序。
四、逐服务启动逻辑
单元目录 facade/dubbo-check-provider
- 启动类:
com.netease.is.antispam.image.facade.dubbo.CheckDubboApplication(src/main/java/.../image/facade/dubbo/CheckDubboApplication.java;包名无.check后缀) @SpringBootApplication:无 exclude。@Enable*:@EnableAspectJAutoProxy(exposeProxy = true)、@EnableFacadeAutoConfiguration、@EnableConfigurationProperties({ImageProperties.class})、@EnableBusinessClient、@EnableRateLimiter、@EnableRecoverComponent。@EnableFacadeAutoConfiguration→@Import(FacadeConfiguration.class):@ComponentScan({"com.netease.is.antispam.image.service","...image.manager","...image.facade.dubbo.monitor","...image.component","...image.monitor"})+@MapperScan("com.netease.is.antispam.image.dao"),并注册RedisComponentBean。- 同包另有
CheckConfiguration(@ComponentScan({"...image.service","...image.manager","...image.metric"}) + @MapperScan("...image.dao") + @EnableScheduling+SchedulingConfigurer设置app.task.pool-size线程池 + 注册RateLimitFileRecover)与ApplicationConfiguration。@EnableScheduling只挂在此类上,靠默认组件扫描生效。 main():JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask()后SpringApplication.run。- 启动钩子:
ImageConfigSyncService.@PostConstruct init():findMaxOpTime()取水位,按BATCH_SIZE=2000分页全量灌ImageConfigRegistry,带DELAY=2000ms时钟偏移保护;增量@Scheduled(fixedDelay=90000)。ImageLibSyncService:MD5 + SIMILAR 两类图库全量加载 + 增量@Scheduled(fixedDelay=120000)。ImageAdjustSyncService:@Scheduled(fixedDelay=60000)。ImageLibCacheRegistry、ImageGptCheckService、ImageCheckParamProvider的@PostConstruct、ContextRefreshedEventListener。
单元目录 facade/dubbo-provider
- 启动类:
com.netease.is.antispam.image.facade.dubbo.DubboApplication(.../image/facade/dubbo/DubboApplication.java,与 check-provider 同包) @SpringBootApplication:无 exclude。@Enable*:@EnableAspectJAutoProxy、@EnableFacadeAutoConfiguration、@EnableBusinessClient、@EnableConfigurationProperties({ImageProperties.class})、@EnableOssClient、@EnableElasticJob。main():同 fastjsonDisableCircularReferenceDetect处理。- 启动钩子:Elastic-Job 任务
libStatCountTask(cron0 0/10 * ? * *,分片 2)、libStat7dCountTask(cron0 0 10 * * ?)。另有ApplicationConfiguration。
单元目录 facade/http-api / scheduler / console/api
facade/http-api:com.netease.is.antispam.facade.http.HttpApplication,仅@SpringBootApplication + @EnableFacadeAutoConfiguration;无 Dockerfile。scheduler:com.netease.is.antispam.scheduler.SchedulerApplication,@SpringBootApplication + @EnableScheduling + @EnableSchedulerAutoConfiguration;无 Dockerfile。console/api:com.netease.is.antispam.console.api.ConsoleApplication;无 Dockerfile。
五、启动前置依赖
| 依赖 | 配置键/地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| TiDB | spring.datasource.url=jdbc:mysql://tidb-cluster0-tidb.tidb.svc:4000/antispam | 阻塞(否则全量加载失败) | application-private.properties |
| ZooKeeper(Dubbo 注册) | zookeeper://zk-*.zookeeper.yidun-infra:2181,group /yidun/antispam/online-new/yidun-antispam-dubbo | 阻塞 | application-private.properties |
| Redis(check-provider Sentinel) | spring.redis.sentinel.master=master01,nodes=redis0-redis-ha.yidun-infra.svc:26379 | 阻塞 | application-private.properties |
| Redis(dubbo-provider Cluster) | spring.redis.cluster.nodes=10.196.38.116:6301,... | 阻塞 | application-private.properties |
| Kafka(生产者) | netease.kafka.producer.cluster.new/log.bootstrap.servers | 弱依赖 | application-private.properties |
| Kafka(消费者,仅 dubbo-provider) | netease.kafka.consumer.enable=true,groupId=antispam-image_dubbo,concurrency=9 | 阻塞 | application-private.properties |
| Apollo | app.id=image-ai_dubbo-check / image-ai_dubbo,namespaces application | 阻塞 | application.properties |
| 业务配置缓存(antispam-business) | business.client.options.zookeeper.address,rootPath=/netease-antispam/online/config | 阻塞 | application-private.properties |
| netease-image(AI 平台) | app.image.check-url=http://imageapi-nis-gz.service.163.org | 弱依赖(不可达时进程正常但业务失败) | application-private.properties |
| gpt 检测 | gpt.image.check.url=http://yidun-ai-agent-jd.service.163.org、gpt.auth.token=sk-... | 弱依赖 | application.properties |
| Elastic-Job ZK | elastic.job.zk.server-lists=yidun-test-commonzk01...,namespace antispam-image-task-jobs-test | 弱依赖(仅 dubbo-provider) | application-private.properties |
六、启动参数与 Profile
- Spring profiles:默认
dev;容器JAVA_OPTS覆写-Dspring.profiles.active=private。 - Maven profile 极多:
private、dev、test、online、guizhou-online、jiande-online、virginia、xjp、beijing等。 - JAVA_OPTS(k8s):
-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private;ENABLE_SKYWALKING=true,collectorskywalking-skywalking-oap.yidun-infra.svc:11800。 - base image 与仓库:
private-registry.nis.netease.com/library/base-image:jdk17;推送private-registry.nis.netease.com/yidun,tagbase-250409-pg;k8s 拉private-registry.yidun.internal/yidun/...:1.0.0.private。 - 启动命令:
ENTRYPOINT ["bash","docker-entrypoint.sh"],APP_NAME形如antispam-image-facade-dubbo-check-provider。 - 构建:
buildAll.sh先mvn clean install -Pprivate,再遍历子模块build.sh。
七、启动期踩坑
@EnableScheduling只挂在与启动类同包的CheckConfiguration上,靠默认组件扫描生效;若给启动类加覆盖默认包的@ComponentScan,配置/图库的定时全量+增量同步会静默失效。ImageConfigSyncService/ImageLibSyncService的@PostConstruct各做一遍全量分页扫表(BATCH_SIZE=2000),大图库下启动慢,且启动期 DB 波动会直接失败。dubbo.protocol.threads=1000+dubbo.protocol.payload=83886080,单实例资源压力大。- properties 内明文密钥(DB 密码、Redis 密码、OSS AK/SK、
gpt.auth.token)。 app.image.check-url不可达时进程仍正常启动,仅业务调用失败,缺 fail-fast 告警。- 模块内 Redis 形态不一致:check-provider 用 Sentinel,dubbo-provider 用 Cluster(硬编码 IP + 密码),迁移/扩容时易漏配。
dubbo.protocol.register=false+dubbo.provider.filter=qos-access同时出现,注册行为依赖具体环境覆写。ImageLibSyncService.increaseSync依赖操作记录时间水位(DELAY=2000ms),跨机房时钟偏差会导致漏同步。CheckConfiguration通过SchedulingConfigurer用app.task.pool-size=4的固定线程池承载全部@Scheduled;图库增量(120s)+ 配置增量(90s)+ 调整同步(60s)并发时线程可能不足而排队。dubbo.scan.basePackages=com.netease.is.antispam.image.facade.dubbo.provider同时被 check-provider 与 dubbo-provider 引用,若两个 provider 同 ZK group 部署,接口暴露范围需按单元核对。dubbo.protocol.register=false与dubbo.application.qos-enable=false使 provider 不主动注册/不上 QoS 端口,运维下线只能靠重启,无法用 QoS offline 优雅摘除。
八、跨模块前置
antispam-business:ProductCache/TargetCache/TargetConfigCacheWithEnv/LabelInfoCache等 client-core 缓存为检测入参来源,须先启动。netease-image(必需):app.image.check-url指向的 AI 检测平台,图片检测的算法结果全部来自它;它未就绪时本模块能启动但检测不可用。yidun-ai-agent:gpt.image.check.url的 GPT 检测能力。antispam-cms:调用CustomModelCheckFacade做自训练模型验证。antispam-business-image/antispam-business-video/antispam-business-livevideo/antispam-livevideo-solution/netease-antispam-preonline:均通过ImageCheckFacade反向调用本模块。