Spring Cloud从零开始:微服务入门指南——一个外包仔跳槽甲方后的血泪实战

Prometheus小骑士
2025-12-12 21:18
阅读 369

作者:杭州某互联网公司Java开发,前外包三年,现房贷月供5200


去年十月的一个深夜,我坐在出租屋里,泡面汤都凉了,笔记本上还开着IDEA,屏幕右下角显示凌晨1:47。老婆在隔壁房间已经睡着了,我盯着一行报错日志发呆:

com.netflix.client.ClientException: Load balancer does not have available server for client: user-service

当时我差点把键盘砸了。

这不是我第一次接触微服务,但却是我第一次真正要自己搭一套能跑的Spring Cloud项目——因为就在一周前,我刚从外包公司跳槽进了现在的甲方公司,月薪从15k涨到22k,还凑首付在杭州余杭买了个68平的小房子。房贷5200一个月,压力山大,根本不敢犯错。

一、外包三年,我只会“调接口”

说来惭愧,在外包干了整整三年,做的项目清一色是给银行、政府做内部系统。技术栈?别提了——Spring Boot + MyBatis + 单体架构,部署就一个jar包丢服务器,连Docker都没正经用过。所谓“微服务”,在我脑子里就是PPT里的几个框图:服务注册、熔断、网关……听着高大上,实操?不存在的。

面试那天,HR问我:“你有Spring Cloud实战经验吗?”

我硬着头皮说:“做过一些demo,理解核心组件。”

其实心里慌得一批。但为了那22k的offer,为了能早点结束合租(房租3500,和人抢卫生间的日子我受够了),我咬牙接了。

入职第一天,组长老王(一个戴黑框眼镜、说话慢悠悠但眼神犀利的中年男人)递给我一个需求文档:“下周上线新模块,基于现有微服务架构扩展,你先熟悉下代码。”

我打开GitLab,看到十几个服务:user-serviceorder-servicepayment-servicegatewayconfig-server……每个都是独立仓库,Maven多模块结构,Nacos做注册中心,Feign调用,Sentinel限流。

我手心冒汗,表面镇定,内心OS:完了,这回真要露馅了。

二、从零搭项目:不是教程,是生存战

周末两天,我没敢出门。老婆看我盯着电脑发呆,问:“又加班?”

我说:“不是,我在补课。”

我翻遍了B站、掘金、GitHub,搜“Spring Cloud 入门 教程”,结果要么是十年前的老版本(Eureka+Zuul),要么是纯理论讲CAP、BASE,根本没法落地。有些教程甚至直接@EnableEurekaServer完事,连配置文件都不给全。

真正的生产环境哪有那么简单?

我决定自己动手,从零搭一个最小可运行的微服务项目。目标很明确:两个服务能互相调用,注册中心可用,配置中心能热更新。

第一步:选型(别被版本坑死)

Spring Cloud版本太乱了!Boot 2.7.x 对应 Cloud 2021.0.x,再往上就得用3.x。我司用的是Spring Boot 2.7.14 + Spring Cloud 2021.0.8,注册中心用Nacos 2.2.3(别用1.x,坑多)。

很多人栽在依赖版本不匹配上。我的建议:直接抄生产环境的pom.xml,别自己瞎配!

第二步:搭建Nacos注册中心

本地启动Nacos很简单:

# 下载nacos-server-2.2.3
unzip nacos-server-2.*.zip
cd nacos/bin
sh startup.sh -m standalone  # 单机模式

访问 http://localhost:8848/nacos,账号密码都是nacos。

然后在user-serviceapplication.yml里加:

spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

加上@EnableDiscoveryClient,启动!控制台看到注册成功,那一刻我差点哭出来——终于有一个服务活了!

第三步:服务间调用——Feign不是万能的

我想让order-service调用user-service的接口。按教程加了Feign Client:

@FeignClient(name = "user-service")
public interface UserClient {
    @GetMapping("/user/{id}")
    User getUser(@PathVariable("id") Long id);
}

结果一调就报错:Load balancer does not have available server

查了半天,发现user-service虽然注册了,但健康检查没过!原来Nacos默认用HTTP探活,路径是/actuator/health,但我没加Spring Boot Actuator依赖!

加上:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

并在application.yml暴露端点:

management:
  endpoints:
    web:
      exposure:
        include: '*'

重启,调用成功!那一刻,我激动得站起来转了两圈——这比当年拿到offer还爽。

三、别信教程,信日志

很多教程说“配置中心很简单,改个配置自动刷新”,结果我改了Nacos里的配置,代码里@Value的值纹丝不动。

后来才知道:必须加@RefreshScope注解!

@RestController
@RefreshScope  // 关键!
public class ConfigController {
    @Value("${app.message}")
    private String message;
}

而且,如果用的是@ConfigurationProperties绑定对象,还需要额外处理。

这些细节,90%的入门教程都不会提。它们只告诉你“怎么做”,但从不告诉你“为什么失败”。

真正的学习,是在报错日志里爬出来的。

四、从外包到甲方:技术只是入场券

现在回头看,那段熬夜搭项目的经历,其实不只是学技术,更是一次心态的蜕变。

在外包时,我只需要完成分配的任务,管它架构烂不烂,反正不是我的锅。但现在,每一行代码都可能影响线上用户,每一个服务宕机都可能让我半夜被叫起来。

上周五晚上,生产环境payment-service突然超时,我接到告警电话。老婆刚做好饭,我一边扒拉两口一边连VPN查日志,发现是Feign超时设置太短(默认1秒),而第三方支付回调慢了点。

我立刻在Nacos配置中心调整:

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 10000

热更新生效,问题解决。挂掉电话,老婆说:“你现在是不是特别有成就感?”

我说:“不,我只是怕背锅。”

她笑了:“但你确实比以前厉害了。”

五、给想入微服务坑的朋友几点真心话

  1. 别迷信教程:大多数教程都是理想化场景,生产环境充满脏数据、网络抖动、版本冲突。真正的技能,是在混乱中理清逻辑的能力。

  2. 从最小闭环开始:先让两个服务跑通,再加网关、配置中心、链路追踪。贪多嚼不烂。

  3. 学会看源码和日志:当教程失效时,日志是你唯一的朋友。DEBUG级别日志能救你命。

  4. 微服务不是银弹:我们公司现在也在反思,有些模块其实没必要拆。过度设计比单体更可怕。

  5. 技术之外,更重要的是责任:甲方和外包最大的区别,不是薪资,而是你对系统的“所有权”。你写的代码,你要负责到底。

六、写在最后:房贷还在还,但我不再害怕

今天,我已经能独立负责一个微服务模块的设计和上线。虽然偶尔还会遇到诡异的分布式事务问题,但至少不会在凌晨一点对着报错发呆了。

前几天和老婆散步,路过一个新开的楼盘,她说:“等再攒点钱,换个大点的。”

我笑了笑,没说话。心里想的是:只要技术不落伍,房贷总还得起;只要代码跑得稳,日子就能过下去。

如果你也正在从外包往甲方跳,或者刚接触微服务一脸懵,别慌。我们都一样,从复制粘贴开始,从报错崩溃中成长。

Spring Cloud不是魔法,它只是工具。真正的魔法,是你熬过无数个深夜后,依然愿意打开IDEA的那份坚持。


作者备注:本文所有代码和配置均来自真实项目脱敏,已在GitHub开源(私信可发链接)。欢迎交流,但别问“怎么学微服务速成”——这世上没有速成,只有死磕。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝