微服务基础

微服务架构是一种将单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中。

什么是微服务

微服务架构的特点:

  • 独立部署:每个服务可以独立部署和扩展
  • 技术多样性:不同服务可以使用不同的技术栈
  • 去中心化:服务之间通过 API 通信
  • 容错性:单个服务故障不会影响整个系统

微服务 vs 单体架构

单体架构

┌─────────────────────────┐
│   单体应用               │
│  ┌─────┐  ┌─────┐       │
│  │用户 │  │订单 │       │
│  └─────┘  └─────┘       │
│  ┌─────┐  ┌─────┐       │
│  │商品 │  │支付 │       │
│  └─────┘  └─────┘       │
└─────────────────────────┘

优点

  • 开发简单
  • 部署简单
  • 测试简单

缺点

  • 扩展困难
  • 技术栈单一
  • 单点故障

微服务架构

┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐
│ 用户服务 │  │ 订单服务 │  │ 商品服务 │  │ 支付服务 │
└────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘
     │            │            │            │
     └────────────┴────────────┴────────────┘
                    │
            ┌───────┴───────┐
            │   API 网关     │
            └───────────────┘

优点

  • 独立扩展
  • 技术栈灵活
  • 容错性好

缺点

  • 复杂度高
  • 分布式事务
  • 运维复杂

Spring Cloud 简介

Spring Cloud 是构建微服务架构的框架集合,提供:

  • 服务注册与发现:Eureka、Consul、Nacos
  • 配置管理:Config Server、Nacos
  • 服务调用:OpenFeign、RestTemplate
  • 负载均衡:Ribbon、LoadBalancer
  • 断路器:Hystrix、Resilience4j
  • API 网关:Gateway、Zuul

微服务基础组件

1. 服务注册与发现

使用 Nacos(推荐)

添加依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2022.0.0.0</version>
</dependency>
配置文件
# application.properties
spring.application.name=user-service
server.port=8081
 
# Nacos 配置
spring.cloud.nacos.discovery.server-addr=localhost:8848
启用服务发现
@SpringBootApplication
@EnableDiscoveryClient  // 启用服务发现
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

2. 服务调用

使用 OpenFeign

添加依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
创建 Feign 客户端
package com.example.feign;
 
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
 
/**
 * 用户服务 Feign 客户端
 * @FeignClient 指定要调用的服务名称
 */
@FeignClient(name = "user-service")
public interface UserFeignClient {
    
    /**
     * 调用用户服务的接口
     */
    @GetMapping("/api/users/{id}")
    User getUserById(@PathVariable("id") Integer id);
}
启用 Feign
@SpringBootApplication
@EnableFeignClients  // 启用 Feign
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}
使用 Feign 客户端
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    @Autowired
    private UserFeignClient userFeignClient;
    
    @GetMapping("/{orderId}")
    public Order getOrder(@PathVariable Integer orderId) {
        Order order = orderService.getOrderById(orderId);
        
        // 通过 Feign 调用用户服务
        User user = userFeignClient.getUserById(order.getUserId());
        order.setUser(user);
        
        return order;
    }
}

3. 负载均衡

使用 Spring Cloud LoadBalancer

@Configuration
public class LoadBalancerConfig {
    
    @Bean
    @LoadBalanced  // 启用负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
 
// 使用
@Autowired
private RestTemplate restTemplate;
 
public User getUser(Integer id) {
    // 使用服务名而不是 IP 地址
    return restTemplate.getForObject(
        "http://user-service/api/users/{id}", 
        User.class, 
        id
    );
}

4. 配置中心

使用 Nacos 配置中心

添加依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2022.0.0.0</version>
</dependency>
配置文件
# bootstrap.properties
spring.application.name=user-service
spring.cloud.nacos.config.server-addr=localhost:8848
spring.cloud.nacos.config.file-extension=yaml
使用配置
@RestController
@RefreshScope  // 支持动态刷新配置
public class ConfigController {
    
    @Value("${app.name:默认名称}")
    private String appName;
    
    @GetMapping("/config")
    public String getConfig() {
        return appName;
    }
}

5. API 网关

使用 Spring Cloud Gateway

添加依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
配置文件
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service  # lb 表示负载均衡
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1

微服务实践示例

项目结构

microservices-demo/
├── user-service/          # 用户服务
│   ├── pom.xml
│   └── src/
├── order-service/         # 订单服务
│   ├── pom.xml
│   └── src/
├── gateway-service/       # API 网关
│   ├── pom.xml
│   └── src/
└── pom.xml                # 父 POM

用户服务示例

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Integer id) {
        return userService.getUserById(id);
    }
    
    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }
}

订单服务示例

@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private UserFeignClient userFeignClient;
    
    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Integer id) {
        Order order = orderService.getOrderById(id);
        
        // 调用用户服务获取用户信息
        User user = userFeignClient.getUserById(order.getUserId());
        order.setUser(user);
        
        return order;
    }
}

微服务最佳实践

1. 服务拆分原则

  • 单一职责:每个服务只负责一个业务功能
  • 高内聚低耦合:服务内部高内聚,服务之间低耦合
  • 数据独立:每个服务有独立的数据库

2. API 设计

  • RESTful 风格:使用标准的 HTTP 方法
  • 版本控制:API 版本管理
  • 统一响应格式:统一的响应结构

3. 服务治理

  • 服务注册与发现:统一的服务注册中心
  • 配置管理:集中式配置管理
  • 监控和日志:统一的监控和日志系统

4. 容错处理

  • 断路器模式:防止服务雪崩
  • 重试机制:自动重试失败请求
  • 降级处理:服务不可用时的降级方案

总结

微服务架构要点:

  • 服务拆分:按业务功能拆分服务
  • 服务注册:使用注册中心管理服务
  • 服务调用:使用 Feign 或 RestTemplate
  • 负载均衡:自动负载均衡
  • 配置管理:集中式配置
  • API 网关:统一入口

微服务架构适合大型、复杂的系统,但需要更多的运维和治理工作。


相关链接


java 微服务 spring-cloud 分布式系统