2141 字
约 7 分钟
2
微服务架构
2026-09-19
无标签
第18章 微服务架构
学习 MyBatis 在微服务架构中的应用和最佳实践 代码演示按钮 💻 查看完整代码 - 在线IDE体验
🏗️ 微服务架构概述
微服务架构是一种将单一应用程序开发为一套小服务的方法,每个服务运行在自己的进程中,并使用轻量级机制(通常是HTTP资源API)进行通信。本章将深入探讨MyBatis在微服务架构中的应用。
🎯 学习目标掌握MyBatis在微服务架构中的应用学习服务发现与注册机制理解分布式事务在微服务中的处理掌握配置中心的使用学习服务间通信与熔断机制了解微服务监控与运维
🔧 微服务核心特性
🔍 服务发现
自动发现和注册服务实例,支持动态扩缩容
- Nacos服务注册与发现
- 健康检查机制
- 负载均衡策略
- 服务元数据管理
🌐 服务间通信
高效的服务间调用机制
- OpenFeign声明式调用
- HTTP客户端配置
- 请求响应拦截器
- 调用链路追踪
⚡ 熔断降级
保障系统稳定性的容错机制
- Hystrix熔断器
- 降级策略配置
- 超时控制
- 实时监控面板
⚙️ 配置中心
集中化配置管理
- Nacos配置中心
- 动态配置刷新
- 环境隔离
- 配置版本管理
🔍 服务发现与注册
Nacos配置
# application.yml
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: dev
group: DEFAULT_GROUP
metadata:
version: 1.0.0
region: beijing
config:
server-addr: localhost:8848
file-extension: yml
namespace: dev
group: DEFAULT_GROUP
refresh-enabled: true
服务注册示例
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity createUser(@RequestBody User user) {
User savedUser = userService.createUser(user);
return ResponseEntity.ok(savedUser);
}
}
🌐 服务间通信
OpenFeign客户端
@FeignClient(name = "order-service", fallback = OrderServiceFallback.class)
public interface OrderServiceClient {
@GetMapping("/orders/user/{userId}")
List getOrdersByUserId(@PathVariable("userId") Long userId);
@PostMapping("/orders")
Order createOrder(@RequestBody Order order);
@GetMapping("/orders/{id}")
Order getOrderById(@PathVariable("id") Long id);
}
@Component
public class OrderServiceFallback implements OrderServiceClient {
@Override
public List getOrdersByUserId(Long userId) {
return Collections.emptyList();
}
@Override
public Order createOrder(Order order) {
throw new ServiceUnavailableException("订单服务暂时不可用");
}
@Override
public Order getOrderById(Long id) {
return null;
}
}
Feign配置
feign:
hystrix:
enabled: true
client:
config:
default:
connectTimeout: 5000
readTimeout: 10000
loggerLevel: basic
order-service:
connectTimeout: 3000
readTimeout: 8000
requestInterceptors:
- com.example.interceptor.AuthInterceptor
🔄 分布式事务管理
Seata集成
# Seata配置
seata:
enabled: true
application-id: user-service
tx-service-group: my_tx_group
service:
vgroup-mapping:
my_tx_group: default
grouplist:
default: localhost:8091
config:
type: nacos
nacos:
server-addr: localhost:8848
namespace: seata
group: SEATA_GROUP
registry:
type: nacos
nacos:
server-addr: localhost:8848
namespace: seata
group: SEATA_GROUP
分布式事务示例
@Service
public class DistributedTransactionService {
@Autowired
private UserService userService;
@Autowired
private OrderServiceClient orderServiceClient;
@Autowired
private PaymentServiceClient paymentServiceClient;
@GlobalTransactional(name = "create-user-order", rollbackFor = Exception.class)
public void createUserAndOrder(String username, String email,
Integer age, BigDecimal amount,
boolean simulateError) {
// 1. 创建用户
User user = new User(username, email, age);
Long userId = userService.createUser(user);
// 2. 创建订单
Order order = new Order();
order.setUserId(userId);
order.setOrderNo("ORDER_" + System.currentTimeMillis());
order.setAmount(amount);
order.setStatus("PENDING");
Order savedOrder = orderServiceClient.createOrder(order);
// 3. 创建支付记录
Payment payment = new Payment();
payment.setOrderId(savedOrder.getId());
payment.setAmount(amount);
payment.setStatus("PENDING");
paymentServiceClient.createPayment(payment);
// 模拟异常,测试事务回滚
if (simulateError) {
throw new RuntimeException("模拟业务异常,触发分布式事务回滚");
}
}
}
⚙️ 配置中心应用
动态配置
@Component
@RefreshScope
public class DynamicConfig {
@Value("${app.feature.enabled:false}")
private boolean featureEnabled;
@Value("${app.cache.ttl:3600}")
private int cacheTtl;
@Value("${app.database.pool.max-size:20}")
private int maxPoolSize;
// getter methods...
}
@RestController
public class ConfigController {
@Autowired
private DynamicConfig dynamicConfig;
@GetMapping("/config")
public Map getConfig() {
Map config = new HashMap<>();
config.put("featureEnabled", dynamicConfig.isFeatureEnabled());
config.put("cacheTtl", dynamicConfig.getCacheTtl());
config.put("maxPoolSize", dynamicConfig.getMaxPoolSize());
return config;
}
}
配置监听
@Component
public class ConfigChangeListener {
private static final Logger logger = LoggerFactory.getLogger(ConfigChangeListener.class);
@NacosConfigListener(dataId = "user-service.yml", groupId = "DEFAULT_GROUP")
public void onConfigChange(String newContent) {
logger.info("配置发生变化: {}", newContent);
// 处理配置变化逻辑
}
@EventListener
public void handleRefreshEvent(RefreshEvent event) {
logger.info("配置刷新事件: {}", event.getEventDesc());
// 处理刷新事件
}
}
⚡ 熔断器机制
Hystrix配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
circuitBreaker:
enabled: true
requestVolumeThreshold: 20
sleepWindowInMilliseconds: 5000
errorThresholdPercentage: 50
metrics:
rollingStats:
timeInMilliseconds: 10000
OrderServiceClient#getOrdersByUserId(Long):
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
熔断器使用
@Service
public class UserService {
@Autowired
private OrderServiceClient orderServiceClient;
@HystrixCommand(
fallbackMethod = "getUserWithOrdersFallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10")
}
)
public UserWithOrders getUserWithOrders(Long userId) {
User user = getUserById(userId);
List orders = orderServiceClient.getOrdersByUserId(userId);
UserWithOrders result = new UserWithOrders();
result.setUser(user);
result.setOrders(orders);
return result;
}
public UserWithOrders getUserWithOrdersFallback(Long userId) {
User user = getUserById(userId);
UserWithOrders result = new UserWithOrders();
result.setUser(user);
result.setOrders(Collections.emptyList());
return result;
}
}
📨 异步处理
消息队列集成
# RabbitMQ配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
listener:
simple:
acknowledge-mode: manual
retry:
enabled: true
max-attempts: 3
initial-interval: 1000
异步消息处理
@Component
public class UserEventPublisher {
@Autowired
private RabbitTemplate rabbitTemplate;
public void publishUserCreatedEvent(User user) {
UserCreatedEvent event = new UserCreatedEvent();
event.setUserId(user.getId());
event.setUsername(user.getUsername());
event.setEmail(user.getEmail());
event.setTimestamp(LocalDateTime.now());
rabbitTemplate.convertAndSend("user.exchange", "user.created", event);
}
}
@RabbitListener(queues = "user.created.queue")
@Component
public class UserEventListener {
@Autowired
private NotificationService notificationService;
@RabbitHandler
public void handleUserCreatedEvent(UserCreatedEvent event, Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
try {
// 处理用户创建事件
notificationService.sendWelcomeEmail(event.getEmail());
// 手动确认消息
channel.basicAck(deliveryTag, false);
} catch (Exception e) {
// 处理失败,拒绝消息
channel.basicNack(deliveryTag, false, true);
}
}
}
📊 监控与运维
健康检查
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Autowired
private DataSource dataSource;
@Override
public Health health() {
try {
// 检查数据库连接
Connection connection = dataSource.getConnection();
connection.close();
return Health.up()
.withDetail("database", "Available")
.withDetail("timestamp", LocalDateTime.now())
.build();
} catch (Exception e) {
return Health.down()
.withDetail("database", "Unavailable")
.withDetail("error", e.getMessage())
.build();
}
}
}
Actuator配置
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus,hystrix.stream
endpoint:
health:
show-details: always
metrics:
enabled: true
metrics:
export:
prometheus:
enabled: true
distribution:
percentiles-histogram:
http.server.requests: true
🏆 最佳实践
🏗️ 服务设计
- 单一职责原则
- 数据库独立
- 无状态设计
- API版本管理
🔧 配置管理
- 环境隔离
- 敏感信息加密
- 配置版本控制
- 动态配置刷新
🛡️ 容错设计
- 熔断器模式
- 重试机制
- 降级策略
- 超时控制
📊 监控运维
- 链路追踪
- 指标监控
- 日志聚合
- 告警机制
❓ 常见问题与解决方案
❓ 服务调用超时
**问题:**服务间调用经常超时
解决方案:
- 调整Feign客户端超时配置
- 优化数据库查询性能
- 增加服务实例数量
- 实施熔断降级策略
❓ 分布式事务失败
**问题:**分布式事务回滚不完整
解决方案:
- 检查Seata配置是否正确
- 确保所有参与方都支持事务
- 合理设置事务超时时间
- 监控事务执行状态
❓ 配置不生效
**问题:**Nacos配置修改后不生效
解决方案:
- 检查@RefreshScope注解
- 确认配置文件格式正确
- 验证命名空间和分组
- 重启应用实例
🚀 实践练习
🚀 运行示例程序
1. 环境准备
# 启动Nacos
sh startup.sh -m standalone
# 启动Seata Server
sh seata-server.sh
# 启动RabbitMQ
rabbitmq-server
2. 编译运行
# 编译项目
mvn clean compile
# 运行用户服务
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# 访问服务
curl http://localhost:8080/users/1
3. 测试功能
- 测试服务发现与注册
- 验证服务间调用
- 测试分布式事务
- 验证熔断降级
- 测试配置动态刷新
📈 预期结果
=== MyBatis 微服务集成演示 ===
1. 服务发现演示
服务注册成功: user-service
发现服务实例: [192.168.1.100:8080]
负载均衡策略: RoundRobin
2. 服务间调用演示
调用订单服务成功: 获取到3个订单
调用支付服务成功: 支付状态已更新
Feign客户端响应时间: 150ms
3. 分布式事务演示
分布式事务执行成功
事务ID: 192.168.1.100:8091:2087229536
参与方: user-service, order-service, payment-service
4. 熔断器演示
正常调用成功率: 95%
熔断器状态: CLOSED
降级调用次数: 2
5. 配置中心演示
配置动态刷新成功
当前配置版本: v1.2.0
配置变更通知: 已接收
6. 异步处理演示
消息发送成功: user.created.event
消息消费成功: 欢迎邮件已发送
消息队列深度: 0
本章小结
📖 本章小结
本章我们学习了 微服务架构 的相关内容,包括:
- 核心概念和基本原理
- 配置方法和实践技巧
- 应用场景和最佳实践
- 常见问题和解决方案
下一章节 🎉
恭喜完成第18章学习!
您已经掌握了微服务架构的核心概念和实践技巧 第19章
Mapper接口进阶
深入学习Mapper接口的高级特性和最佳实践 ⏱️ 预计 30 分钟📊 中等难度开始学习 → ← 第17章 📚 课程目录 第19章 →
评论
0 条
还没有评论,先写一条吧。