0赞
赞赏
更多好文
上周三凌晨2点,我被监控告警电话吵醒——支付系统全挂了。老板在群里吼:“再出问题我让你去机房睡!” 这不是第一次了。去年我们用Spring Cloud Netflix时,服务注册失败、熔断没配,一个接口崩了,整个系统雪崩。这次我们上Spring Cloud Alibaba,用Nacos+Sentinel,结果上线第一天就翻车。现在把踩过的坑全写出来,别再被坑了。
一、Nacos服务注册:别让服务“失踪”
问题现象:
服务启动后,日志全是No service instance found,调用其他服务时直接500错误。
1. 关键配置(必须写对!)
在application.yml里,别漏掉这行:
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.1.10:8848 # 服务地址
register-enabled: true # 重点!必须开启
血泪教训:
我同事在本地跑得好好的,一部署到测试环境就报错。查了三天才发现是register-enabled: true没写。现在公司强制所有项目必须加,否则不给上线。
2. 启动类加注解(别写错!)
@SpringBootApplication
@EnableDiscoveryClient // 不是@EnableEurekaClient!
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
避坑点:
@EnableDiscoveryClient是Spring Cloud的通用注解,Nacos用这个。- 用
@EnableEurekaClient?系统直接注册失败,日志报No service registered。
二、Sentinel熔断:别让一个接口拖垮全系统
问题现象:
用户下单接口突然超时,QPS从1000降到50,其他接口也卡住。
1. 添加依赖(pom.xml)
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2. 配置熔断规则(Nacos控制台操作)
- 访问
http://localhost:8848/nacos(Nacos控制台)。 - 点击“流控规则” → 新建规则:
- 资源名:
/api/order/create(对应Controller路径) - 阈值类型:QPS
- 阈值:500(超过500请求/秒触发熔断)
- 熔断策略:慢调用比例 → 慢调用比例阈值:0.5(50%请求慢于500ms触发熔断)
- 资源名:
真实效果:
当接口平均响应>500ms且占比超50%,自动返回{"code":503,"msg":"服务熔断"},其他请求不受影响。之前没配熔断,压测到300 QPS就全挂。
三、从零搭一个服务:用户服务示例(关键配置)
步骤1:创建Spring Boot项目
- 用Spring Initializr选:
Spring Web+Nacos Discovery+Nacos Config+Sentinel
步骤2:写个接口(UserController.java)
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
// 模拟慢请求(测试熔断用)
if (id % 2 == 0) {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
return new User(id, "user" + id);
}
}
步骤3:启动服务
- 先启动Nacos(下载地址)。
- 启动服务,访问
http://localhost:8080/api/user/1。 - 用JMeter压测:1000并发,QPS 500(看Nacos控制台服务列表,确认注册成功)。
高可用验证:
当接口响应超时,Sentinel自动弹出熔断页面,其他请求继续正常。之前没配熔断时,压测到200 QPS就卡死。
四、避坑指南(全是血的教训)
1. Spring Cloud版本冲突(最坑!)
- 问题:
spring-cloud-starter-alibaba-nacos-discovery用2.2.6.RELEASE,Spring Boot 3.0需要2.2.10+。 - 解决:在pom.xml统一管理版本:
<dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2022.0.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
2. Sentinel控制台不显示(90%人中招)
- 问题:访问
http://localhost:8080/sc404。 - 解决:在
application.yml加:
注意:Sentinel控制台单独下载(官网),不是Spring Boot自带。spring: cloud: sentinel: enabled: true transport: dashboard: localhost:8080 # Sentinel控制台地址
3. Nacos配置热更新失效(致命坑)
- 问题:改了Nacos配置,服务不刷新。
- 解决:必须加
@RefreshScope(Bean上)+@Value读取,别用@ConfigurationProperties(Spring Boot 3.0有兼容问题)。@RefreshScope @Component public class Config { @Value("${db.password}") private String dbPassword; }
4. 服务注册后无法访问(隐藏坑)
- 问题:服务注册成功,但调用时404。
- 原因:Nacos默认注册的是
服务名:端口,但调用时写成了服务名:8080(端口不对)。 - 解决:用
RestTemplate自动获取服务地址:@Autowired private LoadBalancerClient loadBalancerClient; public User getUser(Long id) { ServiceInstance instance = loadBalancerClient.choose("user-service"); String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/api/user/" + id; return restTemplate.getForObject(url, User.class); }
五、效果:从“一挂全挂”到“稳如老狗”
场景:订单服务,峰值QPS 5000,要求响应<300ms。
优化前:
- 服务注册失败率:30%(测试环境)
- 熔断未配置:压测到200 QPS直接崩
- 服务器:4台(2台备用)
优化后:
- 服务注册成功率:100%
- 熔断生效:压测1000 QPS,响应稳定在200ms内
- 服务器:3台(节省1台,年省$2000)
数据来源:JMeter压测(16核机器,JDK 17)。
关键点:Sentinel熔断让系统在高负载下自动降级,Nacos服务发现让集群自动扩容。
结语:别再等了
Spring Cloud Alibaba + Nacos + Sentinel这套组合,我们线上跑了半年,从原来的“一挂全挂”变成“稳如老狗”。去年被坑的团队,今年都成了老手。
现在就做:
- 升级Spring Boot 3.0(必须Java 17+)。
- 用Spring Initializr建新项目。
- 按着避坑指南配Nacos和Sentinel。
