干货!用Spring Cloud+K8S搞定微服务项目实战!
前几天晚上加班到快十一点,我在公司楼下抽烟,跟我们组的小李聊起最近的项目,说实话那一刻我挺有感触的。我们这个系统啊,一开始是用传统的 Spring Boot 单体架构跑起来的,后来业务越来越多,接口调用越来越复杂,测试环境都能卡得半死。最后没办法,只能硬着头皮上 Spring Cloud 微服务,再用 Kubernetes(K8S) 去撑住。今天就把这个过程梳理一下,算是血泪经验吧。
为什么要上Spring Cloud
你想啊,一个单体项目,最早的时候就是 mvn clean package 打个 fat jar,扔到服务器上跑就行。但当服务动不动就十几个模块,甚至几十个模块的时候,问题就来了:
-
一个小改动都得全量打包,上线慢得要死。
-
部署全靠人肉,机器多了分分钟出错。
-
某个模块挂了,整站都得跟着遭殃。
这时候,Spring Cloud 就显得特别合适。它给我们带来的核心能力主要是这几个:服务注册发现、负载均衡、配置中心、链路追踪、熔断降级。比如我们用 Eureka 或者 Nacos 做注册中心,用 Feign 来做服务调用,用 Spring Cloud Config 或者 Nacos 配置中心 来管配置。
代码例子随便贴一个,大家能感受到就行:
@FeignClient(name = "order-service")
public interface OrderClient {
@GetMapping("/orders/{id}")
Order getOrder(@PathVariable("id") Long id);
}
像上面这样,你在用户服务里直接调 orderClient.getOrder(1L),它底层帮你去注册中心找可用的服务实例,还能做负载均衡,贼省心。
微服务带来的“坑”
不过别以为用 Spring Cloud 就完事了,我刚上手的时候踩了不少坑。比如服务之间相互依赖严重,A 调 B,B 又调 C,结果链路一长,问题就复杂得要死。这个时候我们就必须配合 链路追踪(像 Sleuth + Zipkin 或者 SkyWalking)。不然出问题的时候,日志翻到怀疑人生。
还有就是 配置管理。以前我们写 application.properties,结果几十个微服务一多,哪台机器的配置忘了改,生产就出 bug。后来都改成 Nacos 配置中心,一处改全局生效。
上K8S是转折点
Spring Cloud 解决了服务治理问题,但部署还是个麻烦事。以前我们还用过 Docker Compose,一台机器跑几个容器勉强能撑住。但真到线上流量一上来,机器调度、自动扩缩容完全搞不定。那时候运维天天骂我们。
后来,我们一咬牙就上了 K8S。不得不说,K8S 真的改变了我的工作方式。你把每个微服务都打成一个 Docker 镜像,写个 Deployment + Service 配置,交给 K8S 去调度。再配上 Ingress 做流量入口,整个集群就跑起来了。
举个我们常用的 Deployment 配置:
apiVersion: apps/v1
kind:Deployment
metadata:
name:user-service
spec:
replicas:3
selector:
matchLabels:
app:user-service
template:
metadata:
labels:
app:user-service
spec:
containers:
-name:user-service
image:my-registry/user-service:1.0.0
ports:
-containerPort:8080
这东西的妙处就在于:你不用再关心到底跑在哪台机器上,K8S 会自动分配节点、监控存活状态,挂了还能自动拉起来。
Spring Cloud + K8S怎么结合
有同学会问:Spring Cloud 不是已经有服务发现了吗?K8S 里不是也有 Service 吗?这俩会不会打架?
实际上,它们各有分工。K8S 自带的 Service + DNS 可以搞定服务发现,但 Spring Cloud 里的 Feign、Ribbon、Sentinel 这些生态能力还是得用。我们当时的做法是:用 Spring Cloud Alibaba + Nacos 做配置和注册,但底层容器编排完全交给 K8S。
这样有几个好处:
-
容器调度和扩缩容交给 K8S,我们只要写明副本数,剩下的不用管。
-
配置中心和熔断降级还是走 Spring Cloud,这样开发习惯不需要大改。
-
入口流量用 Ingress,再接上 Spring Cloud Gateway,既能做统一网关,也能利用 K8S 的流量管理。
一个真实的场景
我印象最深的一次是去年“618”,我们的订单系统被打爆了。当时用户量是平时的十倍以上。要是单体架构,早就跪了。那天晚上,我们只是在 K8S 控制台把 order-service 的副本数从 5 提到 20,集群自己把 Pod 分配到不同节点,几分钟流量就稳住了。整个过程开发几乎没动手,都是靠平台自动扩缩容。
这就是 K8S 的牛逼之处,它把“运维”这事儿做到了极致,开发只要关心业务代码。
CI/CD流水线的必要性
光有 K8S 还不够,你总不能每次改个代码都手动 docker build,然后再 kubectl apply 吧。我们后来接了 Jenkins + Harbor + K8S 一套流水线:
-
开发提交代码到 Git。
-
Jenkins 自动打包,生成 Docker 镜像,推到 Harbor。
-
Jenkins 再调用
kubectl apply,更新 Deployment。 -
K8S 检测到新镜像,滚动更新服务。
整个过程全自动化,谁上线都不用盯着,回滚也就一条命令的事。
Java代码和K8S探针结合
在 K8S 里,最常见的就是 livenessProbe 和 readinessProbe。这个要跟 Java 应用结合,不然会出大事。
比如我们在 Spring Boot 里加个健康检查接口:
@RestController
public class HealthController {
@GetMapping("/actuator/health")
public String health() {
return "OK";
}
}
然后在 Deployment 里这样写:
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
这样 K8S 就能定时探测你的服务,如果接口挂了,会自动重启容器。我们有一次就是靠这个救了命,要不然整个支付链路可能全崩。
监控和日志
Spring Cloud + K8S 要真正跑起来,监控和日志一定得跟上。不然线上出问题你连 Pod 都找不到。
我们后来用了这套:
-
日志收集:EFK(Elasticsearch + Fluentd + Kibana)
-
监控告警:Prometheus + Grafana
-
链路追踪:SkyWalking
有了这些东西,你就能从调用链、容器运行情况、日志里快速定位问题。比如某个服务 QPS 突然飙升,Prometheus 告警一响,我们就知道是哪个 Pod 出了问题。
总结下来一句话:Spring Cloud 解决的是微服务开发层面的问题,K8S 解决的是运维和部署层面的问题。两者配合起来,才能把微服务真正跑稳。
当然,这条路也不是一蹴而就的。我们一路踩过的坑数不清:配置同步失败、Pod 滚动更新失败、镜像版本混乱……这些问题都得慢慢解决。
不过现在回头看,Spring Cloud + K8S 确实是目前最靠谱的一套微服务落地方案。它不像一些“纯理论”的框架,是真正经历过大流量考验的。
更多推荐


所有评论(0)