从单体到微服务:Java开发者的第一步实战指南

萧娟
2025-12-23 16:45
阅读 1838

大家好,我是你们的老朋友,一名在大厂干了三年后端开发的工程师,平时也在B站做技术分享。最近收到不少粉丝私信:“微服务到底是什么?为什么面试官老爱问?”、“我连单体应用都没写明白,怎么搞分布式?”——这让我想起自己刚入行时的迷茫。今天这篇教程,就是为完全零基础的同学量身打造的:不用懂 Spring Cloud、不用会 Docker,只要会写基本的 Java,就能跟着动手做!

一、微服务到底是啥?能吃吗?

先别被“架构”两个字吓到。简单说:

  • 单体应用(Monolith):就像一家小饭馆,老板一个人又买菜、又炒菜、又收钱。
  • 微服务(Microservices):变成连锁餐厅,有人专门采购、有人负责厨房、有人管前台——各干各的,但通过内部流程协作。

我当初学的时候,以为微服务就是“把代码拆成多个项目”,结果上线后服务互相调不通,差点被主管“请喝茶”。

微服务的核心思想是:把一个大系统拆成多个小服务,每个服务独立开发、部署、扩展。好处很明显:

  • 某个服务挂了,不会拖垮整个系统
  • 团队可以并行开发不同模块
  • 技术栈可以灵活选择(比如用户服务用 Java,推荐服务用 Go)

但坏处也很痛:

  • 调试变复杂(原来查一个日志就行,现在要查 N 个)
  • 网络延迟、超时、重试等问题突然冒出来
  • 部署运维成本飙升

所以,不要为了微服务而微服务!如果你的项目就三个接口、十个用户,老老实实用单体吧。


二、环境准备:5 分钟搭好开发环境

我们用最主流的 Java 技术栈:Spring Boot + Spring Cloud。别慌,我会手把手带你装。

必装软件清单

工具 版本建议 作用
JDK 17 或 21 Java 运行环境
Maven 3.8+ 项目依赖管理
IntelliJ IDEA 社区版即可 代码编辑器
Postman 最新版 测试 API

💡 提示:如果你用的是 Windows,记得配置环境变量;Mac 用户推荐用 Homebrew 安装 JDK。

创建第一个 Spring Boot 项目

  1. 打开 start.spring.io
  2. 选择:
    • Project: Maven
    • Language: Java
    • Spring Boot: 3.2.x
    • Dependencies: Spring Web, Spring Boot DevTools
  3. 点击 “Generate” 下载 zip 包,解压后用 IDEA 打开

你的 pom.xml 应该包含:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

三、核心概念:用外卖订单理解微服务

假设我们要做一个“校园外卖平台”,初期用单体架构:

[用户下单] → [计算价格] → [通知骑手] → [更新订单状态]

所有逻辑都在一个 Java 项目里。

拆成微服务后:

服务名 功能 端口
user-service 用户注册/登录 8081
order-service 创建/查询订单 8082
notification-service 发短信/推送 8083

关键问题来了:order-service 怎么知道用户是否存在?

答案:服务间通过 HTTP 接口互相调用

实战:写两个服务互相调用

第一步:user-service(用户服务)

// UserController.java
@RestController
public class UserController {
    
    @GetMapping("/users/{id}")
    public Map<String, Object> getUser(@PathVariable Long id) {
        // 模拟数据库查询
        Map<String, Object> user = new HashMap<>();
        user.put("id", id);
        user.put("name", "张三");
        user.put("email", "zhangsan@example.com");
        return user;
    }
}

启动类加 @SpringBootApplication,配置 application.yml

server:
  port: 8081

启动后访问 http://localhost:8081/users/123,能看到 JSON 数据。

第二步:order-service(订单服务)

订单服务需要调用用户服务。这里用 Spring 的 RestTemplate

// OrderService.java
@Service
public class OrderService {
    
    private final RestTemplate restTemplate;
    
    public OrderService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    
    public Map<String, Object> createOrder(Long userId) {
        // 先查用户是否存在
        String url = "http://localhost:8081/users/" + userId;
        Map user = restTemplate.getForObject(url, Map.class);
        
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 创建订单逻辑(略)
        Map<String, Object> order = new HashMap<>();
        order.put("orderId", System.currentTimeMillis());
        order.put("userId", userId);
        order.put("status", "CREATED");
        return order;
    }
}

// 配置 RestTemplate Bean
@Configuration
public class AppConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

Controller 层:

@RestController
public class OrderController {
    private final OrderService orderService;
    
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }
    
    @PostMapping("/orders")
    public Map<String, Object> createOrder(@RequestParam Long userId) {
        return orderService.createOrder(userId);
    }
}

配置 application.yml

server:
  port: 8082

启动 order-service,用 Postman 发 POST 请求到 http://localhost:8082/orders?userId=123,如果看到返回订单信息,恭喜你!第一个微服务调用成功了!


四、新手必踩的坑 & 面试题解析

常见问题 1:服务挂了怎么办?

  • 现象:user-service 停了,order-service 调用直接报错。
  • 解决方案:引入服务注册与发现(如 Nacos、Eureka)。服务启动时自动注册,调用方通过服务名而非 IP 地址调用。
  • 面试题:“微服务中如何实现服务发现?”
    ✅ 答:通过注册中心(如 Nacos),服务提供者注册,消费者拉取列表并负载均衡调用。

常见问题 2:网络超时导致订单卡住

  • 现象:user-service 响应慢,order-service 一直等待。
  • 解决方案:设置超时时间 + 熔断降级(如 Sentinel、Hystrix)。
  • 面试题:“什么是服务雪崩?如何防止?”
    ✅ 答:一个服务故障引发连锁反应叫雪崩。可用熔断器在失败率高时快速失败,避免资源耗尽。

常见问题 3:本地能跑,部署后调不通

  • 原因:硬编码了 localhost:8081,实际部署 IP 会变。
  • 避坑指南:永远不要写死 IP!用服务名 + 注册中心动态获取地址。

五、下一步学习路线建议

你已经迈出了最难的第一步!接下来建议按顺序学习:

  1. 服务注册中心:搭建 Nacos,替换 localhost 为服务名
  2. 服务间通信:用 OpenFeign 替代 RestTemplate,更优雅
  3. 配置中心:把端口、数据库等配置抽到 Nacos 统一管理
  4. 网关:用 Spring Cloud Gateway 统一入口
  5. 分布式事务:了解 Seata 解决跨服务数据一致性

📌 我的 B 站频道每周更新“微服务实战系列”,从单体改造到生产部署全流程演示,欢迎关注!


六、总结:微服务不是银弹,而是工具

记住:架构是为业务服务的。如果你的项目还没到“一个 WAR 包超过 100MB”、“每次发布要全组停工等待”的地步,别急着上微服务。

但作为 Java 开发者,理解微服务思想、掌握基本拆分和调用能力,是面试和职业发展的必备技能。这篇文章里的代码,你完全可以复制粘贴运行起来——动手才是最好的学习

最后送大家一句话:我当初学微服务时,光是服务调用就调试了三天。但当你看到两个服务顺利对话的那一刻,那种成就感,绝对值得!

下期预告:《用 Nacos 实现服务自动发现,告别硬编码 IP》
如果你觉得这篇教程有帮助,欢迎点赞、收藏、转发——你们的支持是我持续更新的动力!

评论 0

最热最新
暂无评论
萧娟Lv.1
0
影响力
0
文章
0
粉丝