最佳实践总结
1. 架构设计
1.1 服务拆分原则
| 原则 | 说明 |
|---|---|
| 单一职责 | 每个服务只负责一个业务领域 |
| 高内聚低耦合 | 服务内部高内聚,服务间低耦合 |
| 独立部署 | 服务可独立开发、测试、部署 |
| 数据独立 | 每个服务有独立的数据库 |
1.2 分层架构
┌─────────────────────────────────────┐
│ Controller 层 │
│ (请求处理、参数验证) │
├─────────────────────────────────────┤
│ Service 层 │
│ (业务逻辑、事务管理) │
├─────────────────────────────────────┤
│ Repository 层 │
│ (数据访问、缓存) │
├─────────────────────────────────────┤
│ Entity 层 │
│ (实体定义、领域模型) │
└─────────────────────────────────────┘1.3 API 设计规范
RESTful API 设计规范:
GET /api/v1/users # 获取用户列表
GET /api/v1/users/{id} # 获取单个用户
POST /api/v1/users # 创建用户
PUT /api/v1/users/{id} # 更新用户(全量)
PATCH /api/v1/users/{id} # 更新用户(部分)
DELETE /api/v1/users/{id} # 删除用户
响应格式:
{
"code": 200,
"message": "success",
"data": { ... },
"timestamp": 1234567890
}2. 代码规范
2.1 命名规范
| 类型 | 规范 | 示例 |
|---|---|---|
| 类名 | 大驼峰 | UserService, OrderController |
| 方法名 | 小驼峰 | findById, createUser |
| 变量名 | 小驼峰 | userId, orderList |
| 常量名 | 全大写下划线 | MAX_RETRY_COUNT |
| 包名 | 全小写 | com.example.service |
2.2 异常处理
java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ApiResponse<Void>> handleBusinessException(BusinessException ex) {
return ResponseEntity.status(ex.getCode())
.body(ApiResponse.error(ex.getCode(), ex.getMessage()));
}
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ApiResponse<Void>> handleResourceNotFoundException(
ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(ApiResponse.error(404, ex.getMessage()));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<Void>> handleException(Exception ex) {
log.error("系统异常", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error(500, "系统异常"));
}
}2.3 日志规范
java
@Slf4j
@Service
public class UserService {
public User createUser(UserRequest request) {
log.info("创建用户: username={}", request.username());
try {
User user = doCreateUser(request);
log.info("用户创建成功: id={}", user.getId());
return user;
} catch (Exception e) {
log.error("创建用户失败: username={}", request.username(), e);
throw e;
}
}
}3. 数据库规范
3.1 表设计规范
sql
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
username VARCHAR(50) NOT NULL COMMENT '用户名',
password VARCHAR(255) NOT NULL COMMENT '密码',
email VARCHAR(100) COMMENT '邮箱',
phone VARCHAR(20) COMMENT '手机号',
status VARCHAR(20) DEFAULT 'ACTIVE' COMMENT '状态',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
deleted TINYINT DEFAULT 0 COMMENT '逻辑删除标记',
UNIQUE KEY uk_username (username),
UNIQUE KEY uk_email (email),
KEY idx_phone (phone),
KEY idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';3.2 索引规范
| 规范 | 说明 |
|---|---|
| 主键索引 | 使用自增主键或雪花算法 |
| 唯一索引 | 唯一约束字段 |
| 普通索引 | 查询条件字段 |
| 组合索引 | 多字段组合查询 |
| 覆盖索引 | 避免回表查询 |
4. 缓存规范
4.1 缓存策略
java
@Service
public class ProductService {
private static final String CACHE_KEY_PREFIX = "product:";
private static final Duration CACHE_TTL = Duration.ofHours(1);
@Cacheable(value = "products", key = "#id", unless = "#result == null")
public Product findById(Long id) {
return productRepository.findById(id).orElse(null);
}
@CachePut(value = "products", key = "#product.id")
public Product update(Product product) {
return productRepository.save(product);
}
@CacheEvict(value = "products", key = "#id")
public void delete(Long id) {
productRepository.deleteById(id);
}
}4.2 缓存问题处理
| 问题 | 解决方案 |
|---|---|
| 缓存穿透 | 布隆过滤器、缓存空值 |
| 缓存击穿 | 分布式锁、热点数据永不过期 |
| 缓存雪崩 | 随机过期时间、多级缓存 |
| 缓存一致性 | 延迟双删、消息队列 |
5. 消息队列规范
5.1 消息设计
java
public record OrderMessage(
String messageId,
Long orderId,
String orderNo,
Long userId,
BigDecimal amount,
String eventType,
LocalDateTime timestamp
) {
public static OrderMessage of(Order order, String eventType) {
return new OrderMessage(
UUID.randomUUID().toString(),
order.getId(),
order.getOrderNo(),
order.getUserId(),
order.getTotalAmount(),
eventType,
LocalDateTime.now()
);
}
}5.2 消费者规范
java
@Component
public class OrderMessageConsumer {
@RabbitListener(queues = "order.queue")
public void handleOrder(OrderMessage message, Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
String messageId = message.messageId();
if (isProcessed(messageId)) {
log.warn("消息已处理: {}", messageId);
channel.basicAck(tag, false);
return;
}
try {
processOrder(message);
markAsProcessed(messageId);
channel.basicAck(tag, false);
} catch (Exception e) {
log.error("处理消息失败: {}", messageId, e);
channel.basicNack(tag, false, false);
}
}
}6. 安全规范
6.1 认证授权
| 规范 | 说明 |
|---|---|
| 密码存储 | BCrypt 加密 |
| Token 管理 | JWT + Redis 黑名单 |
| 权限控制 | RBAC 模型 |
| 敏感操作 | 二次验证 |
6.2 数据安全
| 规范 | 说明 |
|---|---|
| 传输加密 | HTTPS |
| 存储加密 | 敏感数据加密存储 |
| 日志脱敏 | 敏感信息脱敏 |
| SQL 注入 | 参数化查询 |
7. 运维规范
7.1 部署规范
yaml
# Kubernetes 部署规范
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 57.2 监控规范
| 监控项 | 说明 |
|---|---|
| 应用监控 | Actuator + Prometheus |
| 日志监控 | ELK Stack |
| 链路追踪 | Zipkin/Jaeger |
| 告警通知 | Prometheus Alertmanager |
8. 小结
本章总结了 Spring 生态开发的最佳实践:
| 领域 | 要点 |
|---|---|
| 架构设计 | 服务拆分、分层架构、API 规范 |
| 代码规范 | 命名规范、异常处理、日志规范 |
| 数据库 | 表设计、索引优化 |
| 缓存 | 缓存策略、问题处理 |
| 消息队列 | 消息设计、消费规范 |
| 安全 | 认证授权、数据安全 |
| 运维 | 部署规范、监控规范 |
下一章将学习学习路线图。