目录
[💡 先说说我经历的微服务"车祸现场"](#💡 先说说我经历的微服务"车祸现场")
[✨ 摘要](#✨ 摘要)
[1. 为什么需要从单体转向微服务?](#1. 为什么需要从单体转向微服务?)
[1.1 单体的痛苦现实](#1.1 单体的痛苦现实)
[1.2 微服务的核心优势](#1.2 微服务的核心优势)
[2. 领域驱动设计(DDD)核心概念](#2. 领域驱动设计(DDD)核心概念)
[2.1 战略设计:划分业务边界](#2.1 战略设计:划分业务边界)
[2.2 战术设计:实现领域模型](#2.2 战术设计:实现领域模型)
[3. 微服务拆分策略与原则](#3. 微服务拆分策略与原则)
[3.1 三大演进策略](#3.1 三大演进策略)
[3.1.1 绞杀者策略(Strangler Pattern)](#3.1.1 绞杀者策略(Strangler Pattern))
[3.1.2 修缮者策略(Repairer Pattern)](#3.1.2 修缮者策略(Repairer Pattern))
[3.2 六大拆分原则](#3.2 六大拆分原则)
[4. 实战:电商系统微服务拆分](#4. 实战:电商系统微服务拆分)
[4.1 单体系统分析](#4.1 单体系统分析)
[4.2 DDD领域建模](#4.2 DDD领域建模)
[4.3 微服务拆分实施](#4.3 微服务拆分实施)
[4.4 服务间通信设计](#4.4 服务间通信设计)
[5. 常见问题与解决方案](#5. 常见问题与解决方案)
[5.1 分布式事务问题](#5.1 分布式事务问题)
[5.2 数据一致性挑战](#5.2 数据一致性挑战)
[6. 企业级最佳实践](#6. 企业级最佳实践)
[6.1 监控与可观测性](#6.1 监控与可观测性)
[6.2 安全设计](#6.2 安全设计)
[7. 性能优化实战](#7. 性能优化实战)
[7.1 缓存策略](#7.1 缓存策略)
[7.2 数据库优化](#7.2 数据库优化)
[8. 总结与建议](#8. 总结与建议)
[8.1 微服务拆分检查清单](#8.1 微服务拆分检查清单)
[8.2 何时不该用微服务](#8.2 何时不该用微服务)
[8.3 我的架构演进建议](#8.3 我的架构演进建议)
[📚 推荐阅读](#📚 推荐阅读)
💡 先说说我经历的微服务"车祸现场"
我之前参与了一个电商平台的重构项目。团队雄心勃勃地要把巨型单体拆分成微服务,结果因为缺乏规范,每个团队按自己理解拆分服务。最后出现了78个微服务,有的服务只有几个接口,而核心的商品服务因为承载了太多功能变成了新的单体。
更糟糕的是,服务间循环依赖严重,一个简单的查询需要穿越6个服务 。线上故障频发,却难以定位问题根源。这次经历让我深刻认识到:没有正确的拆分原则,微服务比单体更可怕。
去年辅导一个金融项目,团队另一个极端:过度设计。每个实体都做成独立服务,DB连接数爆炸,性能惨不忍睹。经过调优,从47个服务合并到23个,性能提升5倍,资源消耗降低60%。
这些教训告诉我:微服务成功的关键不在于拆得多细,而在于拆得有多合理。
✨ 摘要
微服务架构成功转型需要正确的拆分策略和领域驱动设计(DDD)方法论。本文深入解析单体到微服务的演进路径,详细讲解绞杀者策略、修缮者策略等渐进式迁移方法。通过完整电商案例,展示DDD战略设计(子域、限界上下文)和战术设计(实体、值对象、聚合)的实战应用。包含可落地的拆分原则、常见坑点解决方案以及企业级最佳实践。
1. 为什么需要从单体转向微服务?

1.1 单体的痛苦现实
先看一个典型单体的代码结构问题:
java
// 典型的单体结构问题示例
@Controller
public class MonolithicController {
// 问题1:上帝类,包含太多不相关功能
@RequestMapping("/api/*")
public Object handleAll(@RequestParam String action) {
if ("createOrder".equals(action)) {
// 订单创建逻辑(200行)
return createOrder();
} else if ("updateInventory".equals(action)) {
// 库存更新逻辑(150行)
return updateInventory();
} else if ("calculateSalary".equals(action)) {
// 薪资计算逻辑(100行)
return calculateSalary();
}
// ... 更多if-else
}
// 问题2:事务脚本模式,业务逻辑分散
@Transactional
public Order createOrder() {
// 验证用户(50行)
// 检查库存(60行)
// 计算价格(40行)
// 创建订单(30行)
// 扣减库存(25行)
// 发送消息(15行)
// ... 更多步骤
}
}
代码清单1:典型的单体代码问题
用图表示单体架构的问题:

图1:单体架构的核心问题
1.2 微服务的核心优势
代码清单2:微服务架构示例
性能对比数据(电商平台实测):
| 指标 | 单体架构 | 微服务架构 | 改善幅度 |
|---|---|---|---|
| 部署时间 | 45分钟 | 8分钟 | 82% |
| 构建失败影响范围 | 整个系统 | 单个服务 | 90% |
| 扩容成本 | 100% | 15-30% | 70-85% |
| 新功能上线速度 | 2周 | 3天 | 70% |
| 故障恢复时间 | 30+分钟 | 5分钟 | 83% |
2. 领域驱动设计(DDD)核心概念

2.1 战略设计:划分业务边界
DDD的战略设计帮助我们从业务视角理解系统:

图2:DDD战略设计层次
核心概念解析:
-
子域(Subdomain):业务领域的一部分,如订单、商品
-
限界上下文(Bounded Context):显式边界,领域模型在其中适用
-
通用语言(Ubiquitous Language):开发与业务共享的统一语言
2.2 战术设计:实现领域模型
java
// 实体(Entity)示例
public class Order implements Entity<Order> {
private OrderId id;
private CustomerId customerId;
private Money totalAmount;
private OrderStatus status;
private List<OrderItem> items;
// 实体标识
@Override
public boolean sameIdentityAs(Order other) {
return this.id.equals(other.id);
}
// 业务行为
public void addItem(Product product, int quantity) {
OrderItem item = new OrderItem(product, quantity);
this.items.add(item);
this.calculateTotal();
}
public void cancel() {
if (!status.canCancel()) {
throw new IllegalStateException("订单无法取消");
}
this.status = OrderStatus.CANCELLED;
this.addDomainEvent(new OrderCancelledEvent(this.id));
}
}
// 值对象(Value Object)示例
public class Money implements ValueObject {
private final BigDecimal amount;
private final Currency currency;
public Money(BigDecimal amount, Currency currency) {
this.amount = amount.setScale(2, RoundingMode.HALF_EVEN);
this.currency = currency;
}
public Money add(Money other) {
if (!this.currency.equals(other.currency)) {
throw new IllegalArgumentException("货币单位不一致");
}
return new Money(this.amount.add(other.amount), this.currency);
}
// 值对象相等性
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Money)) return false;
Money money = (Money) o;
return amount.compareTo(money.amount) == 0 &&
currency.equals(money.currency);
}
}
// 聚合根(Aggregate Root)示例
public class Order implements AggregateRoot<OrderId> {
private OrderId id;
private List<OrderItem> items;
private CustomerId customerId;
// 聚合内一致性
public void addItem(Product product, int quantity) {
// 验证业务规则
if (items.size() >= 100) {
throw new BusinessException("订单商品数量不能超过100");
}
OrderItem item = new OrderItem(product, quantity);
items.add(item);
calculateTotal();
}
// 工厂方法
public static Order create(CustomerId customerId, List<OrderItem> items) {
Order order = new Order();
order.id = OrderId.nextIdentity();
order.customerId = customerId;
order.items = new ArrayList<>(items);
order.status = OrderStatus.CREATED;
order.createdAt = Instant.now();
order.validate();
order.addDomainEvent(new OrderCreatedEvent(order.id));
return order;
}
}
代码清单3:DDD战术模式实现
3. 微服务拆分策略与原则
3.1 三大演进策略
根据实际经验,我总结出三种可靠的演进策略:

图3:微服务演进策略选择
3.1.1 绞杀者策略(Strangler Pattern)
java
// 1. 初始状态:单体应用
@RestController
public class MonolithicApp {
@GetMapping("/order/{id}")
public Order getOrder(@PathVariable String id) {
// 单体中的订单查询
return orderService.getOrder(id);
}
}
// 2. 引入绞杀者:代理层
@Component
public class StranglerProxy {
@Autowired
private MonolithicClient monolithicClient;
@Autowired
private OrderServiceClient orderServiceClient;
public Order getOrder(String id) {
// 先尝试新服务,失败则回退到单体
try {
return orderServiceClient.getOrder(id);
} catch (Exception e) {
return monolithicClient.getOrder(id);
}
}
}
// 3. 逐步迁移:先迁移读操作
@Service
public class OrderMigrationService {
// 双写策略
@Transactional
public void migrateOrder(String orderId) {
// 从单体读取
Order order = monolithicRepo.findById(orderId);
// 写入新服务
orderService.create(order);
// 验证数据一致性
validateDataConsistency(orderId);
// 标记已迁移
migrationTracker.markMigrated(orderId);
}
}
代码清单4:绞杀者策略实现
3.1.2 修缮者策略(Repairer Pattern)
java
// 1. 识别需要修缮的模块
@Service
public class PerformanceMonitor {
@Scheduled(fixedRate = 60000)
public void monitorPerformance() {
// 监控性能瓶颈
Map<String, Long> metrics = getPerformanceMetrics();
metrics.entrySet().stream()
.filter(entry -> entry.getValue() > 1000) // 超过1秒
.forEach(entry -> {
String module = entry.getKey();
if (shouldExtract(module)) {
extractionPlanner.planExtraction(module);
}
});
}
}
// 2. 提取高性能要求的模块
@Service
public class ImageProcessingExtractor {
public void extractImageProcessing() {
// 创建新的图片处理服务
Microservice imageService = new Microservice("image-service");
// 迁移相关代码
migrateCode("ImageProcessor", imageService);
migrateCode("ImageStorage", imageService);
// 更新调用关系
updateReferences("ImageProcessor", imageService.getEndpoint());
}
}
代码清单5:修缮者策略实现
3.2 六大拆分原则
基于多年经验,我总结了微服务拆分的六大原则:
原则1:单一职责原则(SRP)
java
// 错误示例:上帝服务
@Service
public class ProductService {
// 产品相关
public Product createProduct() { /* ... */ }
public Product updateProduct() { /* ... */ }
// 订单相关(不应该在这里)
public Order createOrder() { /* ... */ }
public Order updateOrder() { /* ... */ }
// 用户相关(不应该在这里)
public User createUser() { /* ... */ }
}
// 正确示例:职责单一的服务
@Service
public class ProductService {
// 只负责产品相关业务
public Product createProduct(CreateProductCommand command) { /* ... */ }
public Product updateProduct(UpdateProductCommand command) { /* ... */ }
}
@Service
public class OrderService {
// 只负责订单业务
public Order createOrder(CreateOrderCommand command) { /* ... */ }
}
代码清单6:单一职责原则示例
原则2:基于业务能力拆分

图4:按业务能力拆分
原则3:基于DDD限界上下文拆分
java
// 识别限界上下文
public class BoundedContextIdentifier {
public List<BoundedContext> identifyContexts(Monolith monolith) {
return monolith.getModules().stream()
.map(module -> {
// 分析模块间的依赖关系
Set<String> dependencies = analyzeDependencies(module);
// 分析业务概念一致性
boolean isCohesive = analyzeCohesion(module);
// 识别通用语言
UbiquitousLanguage language = extractLanguage(module);
return new BoundedContext(module.getName(), dependencies,
isCohesive, language);
})
.filter(BoundedContext::isValid)
.collect(Collectors.toList());
}
}
// 限界上下文映射
public class ContextMapper {
public Map<String, BoundedContext> mapContexts(System system) {
Map<String, BoundedContext> contexts = new HashMap<>();
// 核心域:投入最多资源
contexts.put("order", new BoundedContext("订单上下文", DOMAIN_TYPE.CORE));
// 支撑子域:业务必要但非核心
contexts.put("notification", new BoundedContext("通知上下文", DOMAIN_TYPE.SUPPORTING));
// 通用子域:通用功能
contexts.put("file", new BoundedContext("文件上下文", DOMAIN_TYPE.GENERIC));
return contexts;
}
}
代码清单7:限界上下文识别
4. 实战:电商系统微服务拆分
4.1 单体系统分析
首先分析现有的单体电商系统:
java
// 单体应用结构分析
@Entity
@Table(name = "ecommerce")
public class EcommerceMonolith {
// 混合了所有业务的实体
private Long id;
private String productName; // 产品相关
private BigDecimal price; // 价格相关
private Integer stock; // 库存相关
private Long customerId; // 用户相关
private String orderStatus; // 订单相关
private String paymentId; // 支付相关
// 上帝服务类
@Service
public class MonolithService {
public void processOrder(Order order) {
// 验证用户(用户域)
validateCustomer(order.getCustomerId());
// 检查库存(库存域)
checkInventory(order.getItems());
// 计算价格(产品域)
calculatePrice(order);
// 创建订单(订单域)
createOrder(order);
// 处理支付(支付域)
processPayment(order);
// 发送通知(通知域)
sendNotification(order);
}
}
}
代码清单8:单体系统问题分析
4.2 DDD领域建模
通过事件风暴进行领域建模:
java
// 事件风暴识别领域事件
public class EventStorming {
public DomainModel analyzeDomain() {
// 领域事件
List<DomainEvent> events = Arrays.asList(
new DomainEvent("OrderCreated", "订单已创建"),
new DomainEvent("PaymentProcessed", "支付已处理"),
new DomainEvent("InventoryReserved", "库存已预留"),
new DomainEvent("OrderShipped", "订单已发货")
);
// 聚合识别
List<Aggregate> aggregates = Arrays.asList(
new Aggregate("Order", "订单聚合根"),
new Aggregate("Product", "产品聚合根"),
new Aggregate("Customer", "用户聚合根")
);
// 限界上下文划分
List<BoundedContext> contexts = Arrays.asList(
new BoundedContext("OrderContext", aggregates.subList(0, 1)),
new BoundedContext("ProductContext", aggregates.subList(1, 2)),
new BoundedContext("CustomerContext", aggregates.subList(2, 3))
);
return new DomainModel(events, aggregates, contexts);
}
}
代码清单9:领域建模过程
4.3 微服务拆分实施
java
// 1. 定义服务边界
@Configuration
public class ServiceBoundaries {
@Bean
public ServiceBoundary orderServiceBoundary() {
return ServiceBoundary.builder()
.name("order-service")
.boundedContext("OrderContext")
.aggregates(Arrays.asList("Order", "OrderItem"))
.responsibilities(Arrays.asList(
"订单创建", "订单查询", "订单状态管理"
))
.build();
}
@Bean
public ServiceBoundary productServiceBoundary() {
return ServiceBoundary.builder()
.name("product-service")
.boundedContext("ProductContext")
.aggregates(Arrays.asList("Product", "Category", "Inventory"))
.responsibilities(Arrays.asList(
"产品管理", "库存管理", "品类管理"
))
.build();
}
}
// 2. 数据库拆分迁移
@Service
public class DatabaseMigrator {
@Transactional
public void migrateToMicroservices() {
// 第一阶段:数据库垂直拆分
verticalSplit();
// 第二阶段:数据迁移
migrateData();
// 第三阶段:双写过渡
enableDualWrite();
// 第四阶段:读流量迁移
migrateReadTraffic();
// 第五阶段:写流量迁移
migrateWriteTraffic();
}
private void verticalSplit() {
// 创建服务独立数据库
jdbcTemplate.execute("CREATE DATABASE order_db");
jdbcTemplate.execute("CREATE DATABASE product_db");
jdbcTemplate.execute("CREATE DATABASE customer_db");
// 迁移表结构
migrateTableSchema("orders", "order_db");
migrateTableSchema("products", "product_db");
migrateTableSchema("customers", "customer_db");
}
}
代码清单10:微服务拆分实施
4.4 服务间通信设计
java
// 1. 同步通信:Feign客户端
@FeignClient(name = "product-service", path = "/api/products")
public interface ProductClient {
@GetMapping("/{productId}")
Product getProduct(@PathVariable String productId);
@PostMapping("/{productId}/deduct-stock")
void deductStock(@PathVariable String productId,
@RequestBody DeductStockRequest request);
}
// 2. 异步通信:领域事件
@Component
public class OrderDomainEventPublisher {
@Autowired
private DomainEventPublisher eventPublisher;
@TransactionalEventListener
public void handleOrderCreated(OrderCreatedEvent event) {
// 发布领域事件
eventPublisher.publish("order.created", event);
}
}
@Component
public class InventoryEventHandler {
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
// 处理订单创建事件,预留库存
inventoryService.reserveStock(event.getOrder());
}
}
// 3. 事务一致性:Saga模式
@Service
public class CreateOrderSaga {
@Autowired
private SagaManager sagaManager;
public void createOrder(CreateOrderCommand command) {
SagaInstance saga = SagaManager.begin()
.step("validate-customer")
.invoke(() -> customerClient.validate(command.getCustomerId()))
.compensate(() -> customerClient.unlock(command.getCustomerId()))
.step("reserve-inventory")
.invoke(() -> inventoryClient.reserve(command.getItems()))
.compensate(() -> inventoryClient.release(command.getItems()))
.step("process-payment")
.invoke(() -> paymentClient.process(command.getPayment()))
.compensate(() -> paymentClient.refund(command.getPayment()))
.build();
saga.execute();
}
}
代码清单11:服务间通信模式
5. 常见问题与解决方案
5.1 分布式事务问题
java
// Saga模式实现分布式事务
public class CreateOrderSaga implements Saga<CreateOrderData> {
private final List<SagaStep> steps;
public CreateOrderSaga() {
this.steps = Arrays.asList(
new ValidateCustomerStep(),
new ReserveInventoryStep(),
new ProcessPaymentStep(),
new ConfirmOrderStep()
);
}
@Override
public void execute(CreateOrderData data) {
for (SagaStep step : steps) {
try {
step.execute(data);
} catch (Exception e) {
compensate(data, steps.indexOf(step));
throw new SagaAbortedException("Saga执行失败", e);
}
}
}
private void compensate(CreateOrderData data, int failedStepIndex) {
for (int i = failedStepIndex; i >= 0; i--) {
try {
steps.get(i).compensate(data);
} catch (Exception e) {
log.error("Saga补偿步骤失败", e);
}
}
}
}
// 使用Seata实现分布式事务
@GlobalTransactional
public void createOrderWithTransaction(CreateOrderCommand command) {
// 1. 扣减库存
inventoryFeignClient.deduct(command.getItems());
// 2. 创建订单
Order order = orderService.create(command);
// 3. 扣款
paymentFeignClient.charge(order);
return order;
}
代码清单12:分布式事务解决方案
5.2 数据一致性挑战
java
// 1. 最终一致性:事件驱动
@Component
public class EventDrivenConsistency {
@Autowired
private DomainEventRepository eventRepository;
@Transactional
public void updateProductPrice(String productId, BigDecimal newPrice) {
// 更新本服务数据
productRepository.updatePrice(productId, newPrice);
// 发布领域事件
ProductPriceChangedEvent event =
new ProductPriceChangedEvent(productId, newPrice);
eventRepository.save(event);
// 异步发送到消息队列
eventPublisher.publish("product.price.changed", event);
}
}
// 2. 数据同步:CDC模式
@Configuration
public class CdcConfiguration {
@Bean
public DebeziumChangeConsumer productChangeConsumer() {
return new DebeziumChangeConsumer() {
@Override
public void handle(List<ChangeEvent> events) {
events.forEach(event -> {
if ("products".equals(event.getTable())) {
// 同步到搜索服务
syncToSearchService(event);
// 同步到缓存
syncToCache(event);
}
});
}
};
}
}
代码清单13:数据一致性保障
6. 企业级最佳实践
6.1 监控与可观测性
java
// 1. 分布式追踪
@RestController
public class OrderController {
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable String id) {
// 添加业务标签
Span span = tracer.nextSpan().name("getOrder").start();
try (var ws = tracer.withSpanInScope(span)) {
span.tag("orderId", id);
span.tag("customerId", getCurrentCustomerId());
// 业务逻辑
return orderService.getOrder(id);
} finally {
span.finish();
}
}
}
// 2. 指标收集
@Component
public class OrderMetrics {
private final Counter orderCreatedCounter;
private final Timer orderCreationTimer;
public OrderMetrics(MeterRegistry registry) {
this.orderCreatedCounter = Counter.builder("order.created")
.description("创建的订单数量")
.register(registry);
this.orderCreationTimer = Timer.builder("order.creation.time")
.description("订单创建时间")
.register(registry);
}
public void recordOrderCreation(long duration) {
orderCreatedCounter.increment();
orderCreationTimer.record(duration, TimeUnit.MILLISECONDS);
}
}
代码清单14:监控与可观测性实现
6.2 安全设计
java
// 1. 服务间认证
@Configuration
public class SecurityConfig {
@Bean
public FeignRequestInterceptor requestInterceptor() {
return new FeignRequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
// 添加JWT token
template.header("Authorization", "Bearer " + getJwtToken());
}
};
}
}
// 2. 权限控制
@Service
public class PermissionService {
public void checkPermission(String service, String action) {
String permission = service + ":" + action;
if (!securityContext.hasPermission(permission)) {
throw new AccessDeniedException("无权访问服务: " + service);
}
}
}
// 3. 数据隔离
@Aspect
@Component
public class DataIsolationAspect {
@Around("@annotation(PreAuthorize)")
public Object checkDataAccess(ProceedingJoinPoint joinPoint) throws Throwable {
String tenantId = TenantContext.getCurrentTenant();
Object[] args = joinPoint.getArgs();
// 验证数据访问权限
for (Object arg : args) {
if (arg instanceof TenantAware) {
TenantAware entity = (TenantAware) arg;
if (!entity.getTenantId().equals(tenantId)) {
throw new AccessDeniedException("无权访问其他租户数据");
}
}
}
return joinPoint.proceed();
}
}
代码清单15:安全设计实现
7. 性能优化实战
7.1 缓存策略
java
// 多级缓存设计
@Service
public class MultiLevelCacheService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private CaffeineCache localCache;
@Cacheable(value = "orders", key = "#orderId")
public Order getOrderWithCache(String orderId) {
// 1. 检查本地缓存
Order order = localCache.get(orderId, Order.class);
if (order != null) {
return order;
}
// 2. 检查Redis缓存
order = redisTemplate.opsForValue().get("order:" + orderId);
if (order != null) {
localCache.put(orderId, order);
return order;
}
// 3. 查询数据库
order = orderRepository.findById(orderId);
if (order != null) {
// 写入缓存
redisTemplate.opsForValue().set("order:" + orderId, order,
Duration.ofMinutes(30));
localCache.put(orderId, order);
}
return order;
}
}
// 缓存穿透保护
@Service
public class CacheProtectionService {
public Order getOrderSafely(String orderId) {
// 布隆过滤器判断是否存在
if (!bloomFilter.mightContain(orderId)) {
return null;
}
// 缓存空值防止穿透
Order order = cache.get(orderId);
if (order == null) {
synchronized (this) {
order = cache.get(orderId);
if (order == null) {
order = orderRepository.findById(orderId);
if (order == null) {
// 缓存空值,短时间过期
cache.put(orderId, NULL_OBJECT, 60);
} else {
cache.put(orderId, order, 1800);
}
}
}
}
return order == NULL_OBJECT ? null : order;
}
}
代码清单16:缓存优化策略
7.2 数据库优化
java
// 1. 读写分离
@Configuration
public class ReadWriteSeparationConfig {
@Bean
@Primary
public DataSource dataSource() {
MasterSlaveRoutingDataSource dataSource =
new MasterSlaveRoutingDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("master", masterDataSource());
targetDataSources.put("slave", slaveDataSource());
dataSource.setTargetDataSources(targetDataSources);
dataSource.setDefaultTargetDataSource(masterDataSource());
return dataSource;
}
}
// 2. 分库分表
@Component
public class OrderShardingStrategy {
public String determineDataSource(String orderId) {
// 按订单ID分片
int hash = Math.abs(orderId.hashCode());
int index = hash % 4; // 4个数据源
return "order_db_" + index;
}
public String determineTable(String orderId) {
// 按月分表
LocalDateTime createTime = getOrderCreateTime(orderId);
return "orders_" + createTime.format(DateTimeFormatter.ofPattern("yyyy_MM"));
}
}
代码清单17:数据库优化策略
8. 总结与建议
8.1 微服务拆分检查清单
基于多年经验,我总结的微服务拆分检查清单:
java
// 拆分就绪检查
@Service
public class MigrationReadinessChecker {
public CheckResult checkReadiness(Module module) {
List<CheckItem> checks = Arrays.asList(
checkCodeCoupling(module),
checkDataDependency(module),
checkTeamReadiness(module),
checkInfrastructure(module)
);
long passedChecks = checks.stream()
.filter(CheckItem::isPassed)
.count();
double readiness = (double) passedChecks / checks.size();
return new CheckResult(checks, readiness);
}
private CheckItem checkCodeCoupling(Module module) {
// 检查代码耦合度
double coupling = calculateCoupling(module);
return new CheckItem("代码耦合度", coupling < 0.3,
"模块耦合度: " + coupling);
}
private CheckItem checkTeamReadiness(Module module) {
// 检查团队准备情况
boolean hasOwner = module.getOwner() != null;
boolean hasRunbook = module.getRunbook() != null;
return new CheckItem("团队准备", hasOwner && hasRunbook,
"有明确负责人和运维手册");
}
}
代码清单18:迁移就绪检查
8.2 何时不该用微服务
微服务不是银弹,以下情况建议谨慎:
-
团队规模小(10人以下):沟通成本低,单体更高效
-
业务复杂度低:没有明显的业务边界
-
快速原型阶段:需要快速验证产品想法
-
性能极度敏感:进程间调用有开销
-
数据强一致性要求高:分布式事务复杂度高
8.3 我的架构演进建议
初级阶段(团队<20人):
-
保持单体,做好模块化
-
建立清晰的包结构和接口规范
-
投资自动化部署和监控
中级阶段(团队20-50人):
-
识别核心域,优先拆分
-
采用绞杀者策略渐进式迁移
-
建立基础服务平台
高级阶段(团队>50人):
-
全面微服务化
-
建立平台工程团队
-
投资服务网格、可观测性
📚 推荐阅读
经典书籍
-
**《领域驱动设计:软件核心复杂性应对之道》** - Eric Evans,DDD开山之作
-
**《微服务架构设计模式》** - Chris Richardson,微服务实践宝典
-
**《实现领域驱动设计》** - Vaughn Vernon,DDD实战指南
官方文档
-
**Spring Cloud官方文档** - 微服务框架参考
-
**Microsoft微服务指南** - 企业级架构指导
实践社区
工具资源
- **微服务模式** - 微服务设计模式目录
最后建议 :从简单开始,持续演进。记住架构是生长出来的,而不是设计出来的。选择合适的时机做正确的事,比盲目追求技术潮流更重要。