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

Python摸鱼师
2025-06-15 22:59
阅读 653

开篇:什么是微服务?它能帮我们做什么?

开篇:什么是微服务?它能帮我们做什么?

你有没有遇到过这样一个问题:一个项目一开始很小,功能也少,代码结构清晰。可随着用户越来越多、功能越来越复杂,系统变得越来越难维护,部署慢、修改一个地方动不动就出bug……这就是**单体架构(Monolithic)**常遇到的痛点。

微服务(Microservices)就是为了解决这个问题而诞生的一种架构思想。

简单来说:

  • 微服务架构不是把所有东西都放在一起写成一个大程序。
  • 而是把整个系统拆分成一个个小的服务单元,每个服务都有自己的功能、数据库和接口。
  • 这些服务之间通过网络通信来协作完成任务。

打个比方,单体就像一家大型餐厅只有一个厨师做全部菜;微服务则是多个厨师分别负责不同的菜系——效率高、容易管理、出错时影响范围小。


环境准备:开发工具和环境搭建

环境准备:开发工具和环境搭建

在开始动手之前,我们需要准备好几个关键工具:

1. JDK 安装(Java Development Kit)

推荐版本:JDK 17
下载地址:https://jdk.java.net/archive/
安装完成后,在命令行输入:

java -version

看到输出说明安装成功。

2. Maven 构建工具

Maven是一个用来管理依赖和构建项目的工具。
下载地址:https://maven.apache.org/download.cgi
解压后配置环境变量,使用以下命令检查是否安装成功:

mvn -v

3. Spring Boot 开发框架

我们用Spring Boot快速创建微服务项目。
你可以使用Spring Initializr网站在线生成项目骨架:
访问 https://start.spring.io/

选择:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: 3.x
  • Dependencies: Spring Web, Spring Boot DevTools

下载后解压即可导入IDE(如IntelliJ IDEA或VS Code)。


核心概念讲解

核心概念讲解

一、微服务 vs 单体架构

特性 单体架构 微服务架构
项目结构 所有模块都在一个工程中 每个功能模块是一个独立服务
部署方式 整体部署 各自独立部署
可扩展性 扩展困难 可以单独扩缩容
维护成本 初期低,后期高 初期较高,长期更低

二、核心概念通俗解释

1. 服务间通信

微服务之间是靠“说话”协作的,这个“说话”主要是通过HTTP协议进行请求和响应。

比如,订单服务要调用库存服务查库存信息,就是向它的某个URL发送GET请求。

2. 注册中心 Eureka

微服务多了以后,怎么知道谁在哪里运行?这个时候就需要一个“电话簿”——Eureka注册中心。

每个微服务启动的时候都会去注册自己,并告诉Eureka自己的名字、地址和端口。其他服务要找它的时候,就去问Eureka。

3. 网关 Gateway

网关就像是系统的总入口。所有的请求先经过网关,由网关决定该转给哪个服务处理。这样做的好处是统一管理路由、权限、限流等。

4. 分布式配置 Config Server

微服务多了之后,配置文件也很多。Config Server可以把这些配置集中管理,服务启动时自动去拉取对应的配置信息。


实战项目:实现一个简单的电商系统(订单 + 商品)

实战项目:实现一个简单的电商系统(订单 + 商品)

我们将一步步实现两个微服务:商品服务 和 订单服务,并建立它们之间的通信机制。

第一步:创建注册中心(Eureka Server)

新建一个Spring Boot项目,加入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

启动类加注解:

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

缓存策略对比-1

配置文件 application.yml

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动后访问 http://localhost:8761 就能看到Eureka控制台界面了。


第二步:创建商品服务(Product Service)

依赖:

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

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

配置文件:

spring:
  application:
    name: product-service
server:
  port: 8081

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

提供一个简单的REST API:

@RestController
@RequestMapping("/products")
public class ProductController {

    @GetMapping("/{id}")
    public String getProduct(@PathVariable Long id) {
        return "产品ID:" + id + ",名称:商品A";
    }
}

启动后,你会在Eureka中看到“product-service”已经注册成功。


第三步:创建订单服务(Order Service)

同样引入Eureka客户端和Web支持。

配置文件:

spring:
  application:
    name: order-service
server:
  port: 8082

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

调用商品服务的方法:

@Service
public class OrderService {

    private final RestTemplate restTemplate;

    public OrderService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String getOrderWithProduct() {
        String url = "http://product-service/products/1";
        return restTemplate.getForObject(url, String.class);
    }
}

@Configuration
class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

Controller示例:

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

    private final OrderService orderService;

    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @GetMapping
    public String getOrder() {
        return orderService.getOrderWithProduct();
    }
}

访问:http://localhost:8082/orders,应该会返回商品信息。


第四步:加入网关(API Gateway)

创建一个新的Spring Boot项目,引入:

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

配置网关路由:

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: product-route
          uri: lb://product-service
          predicates:
            - Path=/products/**
        - id: order-route
          uri: lb://order-service
          predicates:
            - Path=/orders/**

现在你就可以通过网关来访问这两个服务了:

  • http://localhost:8080/products/1
  • http://localhost:8080/orders

常见问题解答

问题1:服务启动时报错找不到Eureka?

可能原因:Eureka还没启动,或者端口不对。请确保Eureka服务已经先于其他服务启动。

问题2:RestTemplate无法连接另一个服务?

确保服务都注册到了Eureka上,且正确使用服务名(如product-service),并确认RestTemplate被正确注入。

问题3:服务注册不上Eureka?

可能是配置中的defaultZone地址写错了,应指向正确的Eureka地址:http://localhost:8761/eureka

问题4:为什么一定要用网关?

不强制使用,但使用网关可以集中管理路由、鉴权、限流等功能,提高安全性与灵活性。


学习建议:下一步学什么?

当你掌握了本教程中的基础内容后,建议继续学习以下主题:

  1. 服务发现与负载均衡:学习Ribbon、LoadBalancer等
  2. 服务熔断器:学习Hystrix,提升系统容错能力
  3. 配置中心:深入Spring Cloud Config
  4. 分布式事务:了解Seata等解决方案
  5. 容器化部署:学习Docker和Kubernetes部署微服务
  6. 消息队列中间件:如Kafka、RabbitMQ,实现异步通信
  7. 日志和监控:使用ELK、Prometheus+Grafana监控系统状态

结语

微服务并不是万能钥匙,也不是一开始就要使用的方案,但它的确是应对大规模、高并发业务场景的重要手段。

希望你能从本教程中掌握基本的设计思路与实践技能,迈出成为合格后端工程师的第一步!

如果你觉得这篇文章对你有帮助,欢迎收藏、分享。有问题也可以留言讨论哦!

评论 0

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