
Spring Boot 搭建微服务确实快——几个注解、一套配置服务就起来了。但“跑起来”和“跑得稳”之间隔着数不清的坑。很多项目上线后出问题不是架构选错了而是在一些看似不起眼的实践细节上翻了车。下面这五个坑是我见过最多人踩的。一、Controller里写业务逻辑——最常见也最致命新手最容易犯的错就是把Controller当成“万能入口”——HTTP处理、库存校验、实体创建、状态判断、持久化、响应映射全塞在一个方法里。代码能跑但问题在后面三个月后这个Controller涨到500行所有人都不敢碰它。正确的做法Controller只做一件事——把HTTP请求翻译成应用行为再把结果翻译回HTTP响应。业务逻辑应该下沉到Service层用Service类封装独立的用例。瘦Controller好测、好改、好理解而胖Controller就是一个“穿了HTTP外套的Service”。判断标准如果你的Controller里有业务规则、有数据库操作、有外部调用——它已经变味了赶紧重构。二、直接把Entity当API返回——图省事埋大雷“接口要返回数据直接return Entity多省事。”这是第二个高频坑。JPA Entity是持久化模型API响应是对外契约这两者根本不是一回事。直接返回Entity密码字段、内部标记可能就泄露了。更坑的是懒加载——序列化时触发额外查询或者直接报LazyInitializationException。正确做法定义独立的DTOData Transfer Object作为API的请求和响应对象在Service层完成Entity到DTO的转换。虽然多写几个类但换来的是接口契约的稳定和安全。三、依赖冲突视而不见——启动报错找不到北微服务项目依赖复杂Spring Boot全家桶、各种starter、第三方库堆在一起依赖冲突几乎是必然的。典型症状是NoSuchMethodException、ClassNotFoundException、NoClassDefFoundException——遇到这三种异常第一反应就该检查依赖冲突。比如整合gRPC时引入protobuf-java-util就和接口层的proto依赖发生冲突控制台不报明显错误只有在debug执行到相关代码时才提示类型转换失败。解决工具Maven Helper插件。安装后打开pom文件下方会显示依赖冲突爆红以及具体的依赖引用情况直接在冲突的依赖上exclude即可。别等到部署到生产环境才发现问题本地构建时就把依赖关系理清楚。四、Nacos注册IP错误——容器环境下的经典陷阱把Spring Boot微服务部署到Docker或K8s环境时服务注册到Nacos的IP往往是容器内网IP导致其他服务无法访问。原因是Docker默认使用bridge网络模式容器IP对宿主机不可见。解决方案在Nacos的discovery配置中强制指定宿主机IPyaml复制下载spring: cloud: nacos: discovery: ip: ${HOST_IP:127.0.0.1} prefer-among-ip: true或者在Docker Compose中通过环境变量传递HOST_IP。这个问题看似小但排查起来非常耗时——服务注册成功了调用却总是超时折腾半天才发现是IP地址的问题。五、线程池配置随意——生产环境无声的杀手微服务架构下一个服务里可能同时运行着Web容器线程、Feign调用线程、消息队列监听线程、Redis连接池线程、业务Async线程……如果不加管理线程数会不受控制地暴涨。我见过一个真实案例某微服务节点线程总数超过5000最终触发了“unable to create new native thread”的错误。排查发现Undertow的worker线程设置过大1000业务线程没有用线程池导致不停创建新线程Hystrix线程也没有合理配置。合理配置思路Web容器的IO线程数设为CPU核数worker线程设为IO线程数的8倍左右所有异步任务统一使用自定义线程池别依赖Async的默认行为Feign、Hystrix等组件的线程参数也要根据实际流量调优别用默认值。写在最后这五个坑的共性是代码能跑但经不起生产环境的考验。微服务开发不能只满足于“能跑起来”更要考虑“跑得稳、跑得久”。Controller分层、DTO隔离、依赖管理、容器网络配置、线程池治理——这些看似琐碎的实践细节恰恰是区分“能用”和“好用”的关键。别等到线上出P0故障了才回头补课。