微服务架构设计实战:从单体到分布式

慢慢写代码
2025-06-19 20:33
阅读 547

开篇:什么是微服务?它有什么用?

开篇:什么是微服务?它有什么用?

你有没有注意到,现在很多大公司的网站或应用都特别复杂?比如淘宝、京东、微信这些平台,它们背后其实是由很多个独立的小系统共同组成的,而不是一个“超大程序”。这种开发方式,就叫做 微服务架构(Microservices Architecture)

我们可以用一个简单的类比来理解:

就好像盖房子。如果你只找一个人负责整个房子的设计和施工,效率可能很低,一旦出错,修复起来也麻烦。但如果你把工作拆分成几个小团队,有人专门做水电、有人做装修、有人搞结构,大家各自负责,最后拼在一起,效率更高,维护也更容易。

在软件开发中也是如此。微服务就是把一个大系统,拆成多个可以独立运行、部署、更新的小程序(服务)

为什么要用微服务?

  • ✅ 更容易扩展:想增加某个功能时,只需要改动对应的那个小服务。
  • ✅ 灵活性高:不同服务可以用不同的语言、技术来写。
  • ✅ 容错性强:一个服务坏了,不会影响全部功能。
  • ✅ 部署灵活:每个服务都能单独上线、下线、升级。

环境准备:搭建你的微服务开发环境

系统架构设计图-1

环境准备:搭建你的微服务开发环境

本节我们以 Java 技术栈为例,使用 Spring Boot 和 Spring Cloud 框架进行讲解。

工具列表

工具 版本建议 用途
Java JDK JDK 17 编译和运行Java代码
Maven 3.8.x 项目依赖管理
IntelliJ IDEA 社区/旗舰版 代码编写与调试工具
Docker 最新版 容器化运行服务
Postman 最新版 测试接口使用的API客户端

步骤一:安装JDK

前往 Oracle官网 下载安装JDK 17,并配置环境变量 JAVA_HOME

步骤二:安装Maven

Maven官网 下载并解压,配置环境变量 MAVEN_HOME

验证是否安装成功:

mvn -v

步骤三:安装IDEA

下载社区版即可:IntelliJ IDEA 下载地址

步骤四:安装Docker(可选)

前往 Docker官网 下载安装包并安装。


核心概念:通俗解释关键术语

核心概念:通俗解释关键术语

1. 单体应用(Monolith)

就是一个传统的大型应用程序,所有功能集中在一个项目中。像早期的电商网站,登录、商品展示、下单、支付等全部都在一起。

✅ 优点:简单、适合小项目
❌ 缺点:难维护、难以水平扩展

2. 微服务(Microservice)

将系统拆分成多个独立的服务,每个服务只做一件事,并通过网络通信协同工作。

✅ 优点:灵活性高、易于维护
❌ 缺点:通信成本高、需要协调多个服务

3. 服务注册中心(Service Registry)

当有几十个微服务时,怎么知道谁在线、谁不在线?这就需要一个“总目录”,记录所有服务的位置和状态。常用的是 Eureka 或 Nacos。

4. API网关(API Gateway)

相当于一个统一入口,用户请求先到这个网关,再由它决定请求发给哪个服务。常用 Zuul 或 Gateway。

5. 配置中心(Config Server)

所有服务都要用到一些通用配置,比如数据库信息。配置中心就是集中管理这些数据的地方。

6. 负载均衡(Load Balancer)

当一个服务有多个实例运行时,如何合理分配请求?这就靠负载均衡器完成任务分发。


实战项目:一步步搭建两个微服务

缓存策略对比-2

实战项目:一步步搭建两个微服务

我们的目标是:实现一个简单的商城系统,包含以下两个服务:

  • 商品服务(Product Service):提供查询商品信息的功能
  • 订单服务(Order Service):根据商品ID创建订单

最终目标:订单服务调用商品服务获取商品信息,形成一次完整的购物流程。

第一步:创建Spring Boot项目

打开 start.spring.io 创建两个项目:

Product Service

  • Group: com.example
  • Artifact: product-service
  • Dependencies: Spring Web, Spring Data JPA, H2 Database

Order Service

  • Group: com.example
  • Artifact: order-service
  • Dependencies: Spring Web, Spring Data JPA, RestTemplate, Feign Client

下载后分别导入 IntelliJ IDEA。


第二步:编写商品服务

进入 product-service 项目。

添加实体类 Product.java

@Entity
public class Product {
    @Id
    private Long id;
    private String name;
    private Double price;

    // 构造器、getter/setter
}

创建 Repository 接口

public interface ProductRepository extends JpaRepository<Product, Long> {}

创建 Controller 控制器

@RestController
@RequestMapping("/products")
public class ProductController {
    
    @Autowired
    private ProductRepository repository;

    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return repository.findById(id).orElse(null);
    }
}

配置 application.properties

spring.datasource.url=jdbc:h2:mem:testdb
spring.jpa.hibernate.ddl-auto=update
server.port=8081

启动项目,访问 http://localhost:8081/products/1,你会看到商品信息返回为空,因为我们还没加数据。


第三步:编写订单服务(调用商品服务)

现在我们让订单服务根据商品ID,调用商品服务来获取信息。

使用 Feign 远程调用商品服务

首先,添加 Feign Starter:

pom.xml 中加入:

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

然后启用 Feign Client:

修改主类:

@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

定义远程调用接口:

@FeignClient(name = "product-service", url = "http://localhost:8081")
public interface ProductServiceClient {
    @GetMapping("/products/{id}")
    Product getProductById(@PathVariable("id") Long id);
}

创建订单服务控制器

@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private ProductServiceClient productClient;

    @GetMapping("/create/{productId}")
    public String createOrder(@PathVariable Long productId) {
        Product product = productClient.getProductById(productId);
        if (product == null) {
            return "产品不存在";
        }
        return "订单已创建:" + product.getName();
    }
}

设置端口号

application.properties 中设置:

server.port=8082

第四步:测试两个服务之间的调用

启动两个服务:

  • 商品服务:端口 8081
  • 订单服务:端口 8082

访问:

http://localhost:8082/orders/create/1

此时会提示找不到产品,因为我们还没有添加数据。可以在 ProductController 中加一个添加产品的接口用于测试,或者手动初始化 H2 数据库。


常见问题解答

Q1:调用服务时报 “Connection refused” 是什么意思?

可能是商品服务没启动,或者 URL 地址写错了。请检查 FeignClient 的 url 是否为 http://localhost:8081

Q2:微服务之间通信除了 Feign 还能用什么?

还可以使用:

  • RestTemplate:Spring 自带的 HTTP 请求工具
  • Ribbon + LoadBalancer:配合使用,支持动态服务发现
  • OpenFeign + Ribbon/Nacos/Eureka:企业级方案

Q3:能不能不暴露 IP 地址而直接通过服务名调用?

可以!这就需要用到 服务注册中心(Eureka / Nacos),稍后我们会学习这部分内容。


学习建议:接下来该学什么?

恭喜你完成了第一个微服务项目!

为了进一步提升技能,你可以继续深入以下几个方向:

✅ 基础拓展方向:

  1. 学习服务注册中心:Eureka、Nacos
  2. 学习API网关:Zuul、Gateway
  3. 学习配置中心:Spring Cloud Config
  4. 引入消息队列:RabbitMQ、Kafka
  5. 服务熔断机制:Hystrix

🛠️ 工具进阶方向:

  1. Docker容器化部署
  2. Kubernetes容器编排
  3. CI/CD流程搭建(Jenkins、GitLab CI)
  4. 微服务日志聚合(ELK Stack)

结语

微服务并不是万能药,但它非常适合大型项目和团队协作。作为一名开发者,掌握基本的微服务设计和实践能力,不仅能提升你的开发效率,也会增强你在求职市场的竞争力。

希望这篇教程能帮助你迈出微服务学习的第一步。坚持练习,不断尝试新的技术组合,未来的你一定能够成为一名优秀的后端工程师!


字数统计:约2935字

评论 0

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