微服务基础
微服务架构是一种将单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中。
什么是微服务
微服务架构的特点:
- 独立部署:每个服务可以独立部署和扩展
- 技术多样性:不同服务可以使用不同的技术栈
- 去中心化:服务之间通过 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 网关:统一入口
微服务架构适合大型、复杂的系统,但需要更多的运维和治理工作。
相关链接:
- Spring Cloud 入门 — Spring Cloud 详细教程
- Spring Boot 入门 — Spring Boot 基础