我在成都卷完考研,转身用Spring Cloud搭了个微服务demo

延迟优化师
2026-01-14 08:59
阅读 456

去年12月走出考场那一刻,我就知道:研,大概是没上岸了。
今年3月查完成绩,果然——差了国家线8分。但生活总得继续,好在成都这地方节奏舒服,早上八点起床还能赶上楼下豆花饭刚出锅的热气。投了几份简历后,意外拿到了一家本地SaaS创业公司的offer,岗位是Java后端开发。

入职第一周,CTO拍着我肩膀说:“小张啊,咱们产品马上要重构,你先熟悉下Spring Cloud,下周开始搞微服务拆分。”
我当时心里一咯噔:微服务?面试题里倒是背过一堆,但实操?连Eureka长啥样都没见过!


为什么非得上微服务?

我们现在的“产品”是个企业培训平台,单体架构跑了三年,代码库已经膨胀到40万行。上周五晚上,产品经理提了个看似简单的需求:“加个学习进度实时同步功能”。结果改完之后,整个用户中心模块崩了,线上报错 java.lang.OutOfMemoryError: Metaspace,运维半夜打电话骂街。

老板急了,说再这么下去,双11大促(对,我们这种ToB平台也有“大促”)肯定扛不住。于是微服务成了政治任务。

我翻了翻招聘网站,发现几乎所有中高级Java岗JD都写着“熟悉Spring Cloud微服务架构”,甚至有些还要求“有Go语言经验优先”——虽然我们不用Go,但这也让我意识到:微服务不是选修课,是生存技能。


从零开干:注册中心选型踩坑记

第一步当然是选注册中心。面试题里常说ZooKeeper、Consul、Nacos、Eureka四选一,但真到生产环境,每个都有坑。

组件 优点 缺点 我们的结论
Eureka Spring全家桶亲儿子 停止维护,CAP只保证AP 学习用可以,别上产线
ZooKeeper 强一致性 运维复杂,临时节点机制易误判 放弃
Consul 多语言支持好 HTTP API性能一般 备选
Nacos 阿里开源,配置+注册一体 文档混乱,早期版本有内存泄漏 最终选择

我们选了Nacos,主要是它能同时管配置和服务,省掉一套Config Server。而且阿里系的组件,在国内社区活跃,遇到问题Stack Overflow搜不到,至少能翻中文博客。

启动Nacos很简单:

# 下载nacos-server
wget https://github.com/alibaba/nacos/releases/download/2.2.3/nacos-server-2.2.3.tar.gz
tar -zxvf nacos-server-2.2.3.tar.gz
cd nacos/bin
sh startup.sh -m standalone  # 单机模式跑起来先

访问 http://localhost:8848/nacos,默认账号密码都是 nacos,界面清爽,比Eureka那个复古风舒服多了。


拆!把单体切成微服务

我们决定先拆两个核心模块:user-servicecourse-service

user-service(用户服务)

# bootstrap.yml
spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:884ckage com.example.userservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient // 关键注解!让服务自动注册到Nacos
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

Controller就写个最简单的:

@RestController
public class UserController {

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id) {
        // 实际走MyBatis查DB,这里简化
        return new User(id, "张三", "zhangsan@example.com");
    }
}

启动后,刷新Nacos控制台,看到 user-service 出现在服务列表里,心跳正常——那一刻真的有点小激动,感觉自己像个架构师了(虽然只是幻觉)。

course-service(课程服务)

同样的套路,但这里有个坑:课程服务需要调用用户服务获取讲师信息。这时候就得上 OpenFeign 了。

先在 course-service 里加依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

然后定义Feign客户端:

@FeignClient(name = "user-service") // 指向Nacos里的服务名
public interface UserClient {
    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id") Long id);
}

在CourseController里注入使用:

@RestController
public class CourseController {

    @Autowired
    private UserClient userClient;

    @GetMapping("/course/{id}")
    public CourseWithTeacher getCourse(@PathVariable Long id) {
        Course course = courseMapper.selectById(id);
        User teacher = userClient.getUserById(course.getTeacherId()); // 远程调用!
        return new CourseWithTeacher(course, teacher);
    }
}

但是! 第一次跑直接500错误:

Load balancer does not contain an instance for the service user-service

查了半天,发现 user-service 虽然注册了,但IP是Docker内网地址(因为我们用Docker Compose跑),course-service 在宿主机上根本连不上。最后加了个配置解决:

spring:
  cloud:
    inetutils:
      preferred-networks: 192.168  # 强制注册局域网IP

这种细节,面试题可不会考,但生产环境天天见。


性能优化:别让微服务变成“龟速服务”

微服务最大的陷阱就是网络开销。每次调用都要走HTTP,加上序列化反序列化,延迟蹭蹭涨。

我们压测发现,一个课程详情接口(内部调用3次其他服务)平均响应时间从单体时的45ms飙到180ms。产品经理看了直摇头:“这用户体验,不如回石器时代。”

于是祭出几招:

  1. Feign + Ribbon 超时调优

    feign:
      client:
        config:
          default:
            connectTimeout: 2000
            readTimeout: 5000
    
  2. 启用Gzip压缩

    server:
      compression:
        enabled: true
        mime-types: application/json
    
  3. 缓存高频数据
    用户基本信息变动少,直接上Redis缓存:

    @Cacheable(value = "users", key = "#id")
    public User getUser(Long id) { ... }
    

优化后,P99延迟降到85ms,勉强能交差了。


面试题 vs 现实:那些没人告诉你的事

准备面试时,我背过无数道Spring Cloud题:

  • “说说服务雪崩怎么处理?” → 答:Hystrix熔断。
  • “配置中心怎么实现动态刷新?” → 答:@RefreshScope。

但现实是:

  • Hystrix官方已停更,我们改用 Sentinel(阿里开源),规则配置更直观;
  • @RefreshScope 在生产环境慎用!有一次刷新配置导致连接池泄露,差点引发雪崩;
  • 微服务拆分不是越细越好,我们一开始拆太狠,结果链路追踪日志爆炸,排查Bug像在玩“大家来找茬”。

上周还因为服务间循环依赖(A调B,B又调A),导致整个系统假死。最后靠Arthas在线诊断才定位出来——这种事故,简历上可不敢写。


最后一点碎碎念

现在回头看,Spring Cloud入门其实不难,难的是在真实业务场景里权衡取舍。微服务不是银弹,它带来弹性、独立部署的同时,也引入了分布式事务、链路追踪、配置管理等一系列新问题。

不过,作为一个考研失败转码的新人,能在成都这座安逸的城市里,每天早上八点坐在工位上,一边喝着盖碗茶,一边调试Feign超时参数,也挺踏实的。

毕竟,代码跑通那一刻的快乐,和考研上岸的快乐,其实差不多——都是“我做到了”的瞬间。

如果你也在从零学微服务,别怕踩坑。每一个500错误背后,都是通往高级工程师的垫脚石。
(当然,要是能顺便帮我内推个大厂就更好了,简历已更新,求捞!)

评论 0

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