我参与搭建这家中型企业AI能力中台的Java架构实录与踩坑总结上头刚给压下来一个活儿给一家中型制造企业搞AI能力中台。客户业务线挺杂客服、质检、运维都在喊话要接入大模型但各自为政算力浪费严重。项目规模中等偏上涉及几十微服务、多种模型接入要求两周内出MVP。说实话当时我觉得这工期有点紧但硬着头皮也得上。模型选型与API网关的那点事一开始内部吵得不可开交。方案A是统一走OpenAI兼容接口快速接入各种大模型方案B是自研模型路由层支持内部微调的私有模型优先调度。试了一圈发现客户要求数据不出域方案A直接被毙。我选了方案B但加了个降级策略——私有模型响应超时超过2秒自动切到云端备用。有意思的是我们用了Spring Cloud Gateway做统一入口。配置里有个坑route predicates里写错了正则导致部分请求被意外拦截排查了整整一下午。yamlspring:cloud:gateway:routes:id: ai-model-routeuri: lb://ai-model-servicepredicates:Path/api/v1/predict/**filters:StripPrefix2Retry3,500ms网关层还加了熔断器用Resilience4j。之前没用过这个以为和Hystrix差不多结果配置语法忘了一个逗号线上直接报错。缓存策略和异步调度的抉择高并发场景下模型推理延迟是个大问题。我决定引入多级缓存本地Caffeine 分布式Redis。本地缓存存高频小模型结果Redis存推理中间状态。这里踩过一个大坑Redis里存了推理任务的JSON结果序列化时用了Jackson没注册模块反序列化时遇到LocalDateTime直接炸。查了日志才发现是时间戳格式问题。javaConfigurationpublic class RedisConfig {Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory factory) {RedisTemplate template new RedisTemplate();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericJackson2JsonRedisSerializer());return template;}}异步调用这块我本来想用 CompletableFuture但考虑到任务量达到上千级别还是换成了基于RocketMQ的异步任务队列。客户那边消息积压时监控报警差点把我吓醒。后来加了消费者扩容才稳住。部署架构从单体到微服务的迭代我们没上来就搞k8s先用的Docker Compose跑在阿里云ECS上。MVP阶段这样最快。等流量起来再迁移到K8s集群。部署时踩了个坑容器里时区不对导致日志时间戳比实际晚8小时排查了半天。解决办法是在Dockerfile里加一行dockerfileENV TZAsia/ShanghaiRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone有意思的是我们内部模型训练用的是PyTorch推理服务用Java两边数据格式对不上最后用Protobuf做了个中间转换层。当时我觉得这样就行结果发现Protobuf的字段序号乱了反序列化结果全是null排查了一晚上。架构决策的取舍与反思回过头看这几个关键决策里最让我纠结的是模型路由策略。最终选择了动态优先级调度而不是固定权重。因为客户业务波动大高峰期客服咨询量是平时的十倍固定权重会导致资源浪费。说实话现在回头看有些设计还是过于理想化了。比如缓存失效策略本来想用地过期时间但实际业务数据更新频率不固定导致部分用户看到的数据是旧的。后来改成了主动失效定期清理的组合方案。这个项目上线后内部系统响应速度提升了约60%模型调用成功率稳定在99.5%以上。当然中间熬了不少夜掉了好几根头发。但看到业务方真的在用我们搭的中台提效还是觉得值。本文基于实际项目经验整理欢迎在评论区交流技术问题。
