微服务最佳实践与坑
工具会用只是第一步,怎么拆、怎么管才是真功夫。下面这十条,是从无数线上事故里攒出来的经验,踩过一次就懂了。
| 主题 | 建议 |
|---|---|
| 服务拆分 | 按业务域(DDD)拆,别按技术层拆。一个服务只负责一个业务能力,数据库归它自己,别跨库 join。 |
| API 版本管理 | 接口变更加版本号(/api/v1/user),老版本别随便删,灰度兼容。 |
| 同步 vs 异步 | 强一致的实时调用用 Feign;解耦、削峰、通知类用 MQ。别啥都同步。 |
| 配置管理 | 所有配置进 Nacos,敏感配置(密码、Key)加密或走配置中心鉴权,别写代码里。 |
| 日志规范 | 每个请求带 TraceId,日志级别、格式统一,生产别开 DEBUG。 |
| 安全 | 网关统一验 JWT/OAuth2 token,服务之间别裸调;内网通信也加鉴权。 |
| 容器化 | 每个服务打 Docker 镜像,K8s 编排;别把环境差异赌在"我电脑上能跑"。 |
服务怎么拆:别按技术层拆
新手最容易犯的错:把工程分成 controller、service、dao 三个"服务"——这不是微服务,这是把一个单体拆碎了重新粘回去。正确的拆法是按业务域拆:用户相关的归用户服务,订单相关的归订单服务,一个服务对应一个业务能力、一个数据库。
| 原则 | 意思 |
|---|---|
| 单一业务能力 | 一个服务只干一件事,能一句话说清它是干嘛的。 |
| 数据库独占 | 每个服务有自己的库,别跨库 join。要数据走接口。 |
| 独立部署 | 改这个服务不用动别的服务,能单独发版。 |
| 别拆太细 | 三个人维护 20 个微服务是灾难。先粗拆,业务跑起来再细拆。 |
服务间通信:什么时候同步、什么时候异步
这是设计微服务时最常纠结的问题。判断标准只有一条:这个调用的结果,需不需要立刻拿来返回给用户?
| 场景 | 选哪种 | 原因 |
|---|---|---|
| 下单查用户信息 | Feign 同步 | 下单响应里要带用户名,必须立刻拿到。 |
| 下单后发短信 | MQ 异步 | 用户不关心短信有没有发出去,别让下单接口等。 |
| 扣库存 | Feign 同步 | 库存够不够直接决定下单成不成。 |
| 下单后推 BI 报表 | MQ 异步 | 报表晚几秒没事,解耦最重要。 |
API 版本管理:别让老用户骂街
接口上线后总会改。直接改老接口,老版本 App 就崩了。行业做法是把版本号放进 URL(/api/v1/user、/api/v2/user),老版本接口留着给老 App 用,新版本新开一套。网关层可以按路径前缀路由到不同服务或不同 Controller。别随便删老版本,至少留到 95% 用户升级完。
同一个 Controller 里支持两个版本(思路示例)
容器化:一个服务一个 Docker 镜像
微服务动辄十几个,每台机器部署一个太浪费。Docker 把每个服务连同它的依赖打成一个镜像,丢到任何机器上都能跑。K8s 负责编排——挂了自动重启、流量大了自动扩容。学习阶段用 Docker Compose 一键起 Nacos + Redis + 你的服务,比本地一个个起省事。
一个 Spring Boot 服务的 Dockerfile(通用模板)
docker-compose.yml:一键起 Nacos + Redis + 三个业务服务
安全:JWT 统一鉴权
用户登录成功后,服务端发一个 JWT(JSON Web Token)字符串给前端。之后前端每次请求都把这个 token 放在 Authorization 头里。网关统一校验签名和有效期,通过了才放行;下游服务不用再查库,解析 token 就能拿到用户 ID。无状态、可扩展,是微服务鉴权的事实标准。
网关里校验 JWT 的思路(伪代码,实际用 spring-security 或 jjwt 库)
JWT 之上的 OAuth2:第三方登录那套
别把 JWT 和 OAuth2 混为一谈:JWT 是一种 token 格式,OAuth2 是一套授权协议("用微信/Google 账号登录这个网站")。企业内部服务间鉴权用 JWT 就够;要做"第三方授权登录""开放平台给合作伙伴发令牌"才上 OAuth2。
| OAuth2 角色 | 人话 |
|---|---|
| Resource Owner | 用户本人(同意把自己数据授权给第三方 App)。 |
| Client | 第三方应用(要拿用户数据的那个 App)。 |
| Authorization Server | 授权服务器,发 token(Spring Authorization Server 干这个)。 |
| Resource Server | 存用户数据的服务,拿着 token 来验,验对了才给数据。 |
论一句话选型
内部微服务鉴权 → JWT 就够,网关验签。要"让别的公司/应用接入你的开放平台、用户点同意授权" → 上 OAuth2 授权码模式,配合 Spring Authorization Server。别一上来就 OAuth2,内部场景它是杀鸡用牛刀。
六大常见坑(面试也常问)
Spring Cloud、Spring Boot、Spring Cloud Alibaba 三者版本不对应,启动时 NoSuchMethodError 满天飞。去官方 Wiki 查 Release Train 表,照抄。
报 connect timed out。先看 Nacos 起没起、端口对不对、防火墙/安全组放没放 8848。本地连公司 Nacos 要走 VPN 的话,确认 VPN 连上了。
调慢接口必超时,显式配 connectTimeout 和 readTimeout,别用默认值赌。
查 uri 里服务名拼写、StripPrefix 数、有没有误引 spring-boot-starter-web。
控制台规则默认在内存,必须持久化到 Nacos。
AT 模式回滚失败多是脏写或隔离级别问题,TC 必须集群 + 持久化。