1. 综合项目实战 - 电商系统完整实现
1.1 项目架构设计
项目整体架构:
java
// 项目结构
// com.example.ecommerce
// ├── domain // 领域层
// │ ├── order // 订单领域
// │ ├── product // 商品领域
// │ └── user // 用户领域
// ├── application // 应用层
// │ ├── service // 应用服务
// │ └── dto // 数据传输对象
// ├── infrastructure // 基础设施层
// │ ├── repository // 仓储实现
// │ ├── cache // 缓存
// │ └── mq // 消息队列
// └── presentation // 表现层
// └── controller // 控制器
// 领域模型 - 订单聚合根
@Entity
@Table(name = "t_order")
@Data
@Slf4j
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String orderNumber;
private Long userId;
private BigDecimal totalAmount;
private OrderStatus status;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
private List<OrderItem> items;
@Embedded
private Address shippingAddress;
private Date createTime;
private Date updateTime;
// 领域行为
public void confirm() {
if (this.status != OrderStatus.PENDING) {
throw new IllegalStateException("只有待确认订单才能确认");
}
this.status = OrderStatus.CONFIRMED;
this.updateTime = new Date();
}
public void pay(BigDecimal amount) {
if (this.status != OrderStatus.CONFIRMED) {
throw new IllegalStateException("只有已确认订单才能支付");
}
if (amount.compareTo(this.totalAmount) != 0) {
throw new IllegalArgumentException("支付金额不匹配");
}
this.status = OrderStatus.PAID;
this.updateTime = new Date();
}
public void cancel(String reason) {
if (this.status == OrderStatus.COMPLETED || this.status == OrderStatus.CANCELLED) {
throw new IllegalStateException("订单状态不允许取消");
}
this.status = OrderStatus.CANCELLED;
this.updateTime = new Date();
}
public BigDecimal calculateTotal() {
if (this.items == null || this.items.isEmpty()) {
return BigDecimal.ZERO;
}
return this.items.stream()
.map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
// 订单项实体
@Entity
@Table(name = "t_order_item")
@Data
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long orderId;
private Long productId;
private String productName;
private BigDecimal price;
private Integer quantity;
private BigDecimal subtotal;
}
// 订单状态枚举
public enum OrderStatus {
PENDING("待确认"),
CONFIRMED("已确认"),
PAID("已支付"),
SHIPPED("已发货"),
COMPLETED("已完成"),
CANCELLED("已取消");
private final String description;
OrderStatus(String description) {
this.description = description;
}
}
1.2 应用服务层实现
应用服务实现:
java
// 订单应用服务
@Service
@Slf4j
@Transactional
public class OrderApplicationService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private ProductService productService;
@Autowired
private UserService userService;
@Autowired
private InventoryService inventoryService;
@Autowired
private PaymentService paymentService;
@Autowired
private EventPublisher eventPublisher;
@Autowired
private RedisTemplate<String, String> redisTemplate;
// 创建订单
public OrderDTO createOrder(CreateOrderRequest request) {
// 1. 参数验证
validateCreateOrderRequest(request);
// 2. 获取用户信息
User user = userService.getUserById(request.getUserId());
if (user == null) {
throw new UserNotFoundException("用户不存在");
}
// 3. 验证商品和库存
List<OrderItem> items = new ArrayList<>();
for (CreateOrderItemRequest itemRequest : request.getItems()) {
Product product = productService.getProductById(itemRequest.getProductId());
if (product == null) {
throw new ProductNotFoundException("商品不存在: " + itemRequest.getProductId());
}
// 检查库存
boolean available = inventoryService.checkInventory(
itemRequest.getProductId(),
itemRequest.getQuantity()
);
if (!available) {
throw new InsufficientInventoryException("库存不足: " + product.getName());
}
// 创建订单项
OrderItem item = new OrderItem();
item.setProductId(product.getId());
item.setProductName(product.getName());
item.setPrice(product.getPrice());
item.setQuantity(itemRequest.getQuantity());
item.setSubtotal(product.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity())));
items.add(item);
}
// 4. 创建订单
Order order = new Order();
order.setOrderNumber(generateOrderNumber());
order.setUserId(request.getUserId());
order.setItems(items);
order.setTotalAmount(calculateTotal(items));
order.setShippingAddress(convertAddress(request.getShippingAddress()));
order.setStatus(OrderStatus.PENDING);
order.setCreateTime(new Date());
order.setUpdateTime(new Date());
// 5. 保存订单
order = orderRepository.save(order);
// 6. 扣减库存
for (OrderItem item : items) {
inventoryService.deductInventory(item.getProductId(), item.getQuantity());
}
// 7. 发布领域事件
eventPublisher.publish(new OrderCreatedEvent(order.getOrderNumber(), order.getUserId(), order.getTotalAmount()));
log.info("创建订单成功: orderNumber={}, userId={}", order.getOrderNumber(), order.getUserId());
return convertToDTO(order);
}
// 支付订单
public PaymentResult payOrder(String orderNumber, PaymentRequest paymentRequest) {
// 1. 获取订单
Order order = orderRepository.findByOrderNumber(orderNumber);
if (order == null) {
throw new OrderNotFoundException("订单不存在: " + orderNumber);
}
// 2. 验证订单状态
if (order.getStatus() != OrderStatus.CONFIRMED) {
throw new IllegalStateException("订单状态不允许支付");
}
// 3. 使用分布式锁防止重复支付
String lockKey = "order:pay:" + orderNumber;
DistributedLock lock = distributedLockService.acquireLock(lockKey, 10, TimeUnit.SECONDS);
try {
// 双重检查
order = orderRepository.findByOrderNumber(orderNumber);
if (order.getStatus() != OrderStatus.CONFIRMED) {
throw new IllegalStateException("订单状态已变更");
}
// 4. 调用支付服务
PaymentResult result = paymentService.processPayment(
order.getOrderNumber(),
order.getTotalAmount(),
paymentRequest
);
if (result.isSuccess()) {
// 5. 更新订单状态
order.pay(order.getTotalAmount());
orderRepository.save(order);
// 6. 发布支付成功事件
eventPublisher.publish(new OrderPaidEvent(order.getOrderNumber(), order.getUserId(), order.getTotalAmount()));
log.info("订单支付成功: orderNumber={}", orderNumber);
}
return result;
} finally {
lock.unlock();
}
}
// 取消订单
public void cancelOrder(String orderNumber, String reason) {
Order order = orderRepository.findByOrderNumber(orderNumber);
if (order == null) {
throw new OrderNotFoundException("订单不存在: " + orderNumber);
}
// 使用分布式锁
String lockKey = "order:cancel:" + orderNumber;
DistributedLock lock = distributedLockService.acquireLock(lockKey, 10, TimeUnit.SECONDS);
try {
order = orderRepository.findByOrderNumber(orderNumber);
order.cancel(reason);
orderRepository.save(order);
// 恢复库存
for (OrderItem item : order.getItems()) {
inventoryService.restoreInventory(item.getProductId(), item.getQuantity());
}
// 发布取消事件
eventPublisher.publish(new OrderCancelledEvent(orderNumber, order.getUserId(), reason));
log.info("订单取消成功: orderNumber={}, reason={}", orderNumber, reason);
} finally {
lock.unlock();
}
}
// 查询订单
public OrderDTO getOrder(String orderNumber) {
Order order = orderRepository.findByOrderNumber(orderNumber);
if (order == null) {
throw new OrderNotFoundException("订单不存在: " + orderNumber);
}
return convertToDTO(order);
}
// 分页查询用户订单
public Page<OrderDTO> getUserOrders(Long userId, int page, int size) {
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createTime"));
Page<Order> orders = orderRepository.findByUserId(userId, pageable);
return orders.map(this::convertToDTO);
}
// 工具方法
private String generateOrderNumber() {
return "ORD" + System.currentTimeMillis() + (int)(Math.random() * 1000);
}
private BigDecimal calculateTotal(List<OrderItem> items) {
return items.stream()
.map(OrderItem::getSubtotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
private Address convertAddress(AddressDTO dto) {
return new Address(dto.getProvince(), dto.getCity(), dto.getDistrict(),
dto.getStreet(), dto.getZipCode());
}
private OrderDTO convertToDTO(Order order) {
OrderDTO dto = new OrderDTO();
dto.setId(order.getId());
dto.setOrderNumber(order.getOrderNumber());
dto.setUserId(order.getUserId());
dto.setTotalAmount(order.getTotalAmount());
dto.setStatus(order.getStatus());
dto.setItems(order.getItems().stream()
.map(this::convertItemToDTO)
.collect(Collectors.toList()));
dto.setCreateTime(order.getCreateTime());
return dto;
}
private OrderItemDTO convertItemToDTO(OrderItem item) {
OrderItemDTO dto = new OrderItemDTO();
dto.setProductId(item.getProductId());
dto.setProductName(item.getProductName());
dto.setPrice(item.getPrice());
dto.setQuantity(item.getQuantity());
dto.setSubtotal(item.getSubtotal());
return dto;
}
private void validateCreateOrderRequest(CreateOrderRequest request) {
if (request.getUserId() == null) {
throw new IllegalArgumentException("用户ID不能为空");
}
if (request.getItems() == null || request.getItems().isEmpty()) {
throw new IllegalArgumentException("订单项不能为空");
}
if (request.getShippingAddress() == null) {
throw new IllegalArgumentException("收货地址不能为空");
}
}
}
1.3 控制器层实现
RESTful API实现:
java
// 订单控制器
@RestController
@RequestMapping("/api/orders")
@Slf4j
@Validated
public class OrderController {
@Autowired
private OrderApplicationService orderService;
// 创建订单
@PostMapping
@RateLimit(limit = 100, windowSize = 60000)
public ResponseEntity<ApiResponse<OrderDTO>> createOrder(
@Valid @RequestBody CreateOrderRequest request) {
try {
OrderDTO order = orderService.createOrder(request);
return ResponseEntity.ok(ApiResponse.success(order));
} catch (Exception e) {
log.error("创建订单失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error(e.getMessage()));
}
}
// 支付订单
@PostMapping("/{orderNumber}/pay")
public ResponseEntity<ApiResponse<PaymentResult>> payOrder(
@PathVariable String orderNumber,
@Valid @RequestBody PaymentRequest request) {
try {
PaymentResult result = orderService.payOrder(orderNumber, request);
return ResponseEntity.ok(ApiResponse.success(result));
} catch (Exception e) {
log.error("支付订单失败: orderNumber={}", orderNumber, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error(e.getMessage()));
}
}
// 取消订单
@PostMapping("/{orderNumber}/cancel")
public ResponseEntity<ApiResponse<Void>> cancelOrder(
@PathVariable String orderNumber,
@RequestBody CancelOrderRequest request) {
try {
orderService.cancelOrder(orderNumber, request.getReason());
return ResponseEntity.ok(ApiResponse.success(null));
} catch (Exception e) {
log.error("取消订单失败: orderNumber={}", orderNumber, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error(e.getMessage()));
}
}
// 查询订单
@GetMapping("/{orderNumber}")
public ResponseEntity<ApiResponse<OrderDTO>> getOrder(@PathVariable String orderNumber) {
try {
OrderDTO order = orderService.getOrder(orderNumber);
return ResponseEntity.ok(ApiResponse.success(order));
} catch (OrderNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(ApiResponse.error(e.getMessage()));
} catch (Exception e) {
log.error("查询订单失败: orderNumber={}", orderNumber, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error(e.getMessage()));
}
}
// 查询用户订单列表
@GetMapping("/user/{userId}")
public ResponseEntity<ApiResponse<Page<OrderDTO>>> getUserOrders(
@PathVariable Long userId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
try {
Page<OrderDTO> orders = orderService.getUserOrders(userId, page, size);
return ResponseEntity.ok(ApiResponse.success(orders));
} catch (Exception e) {
log.error("查询用户订单失败: userId={}", userId, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error(e.getMessage()));
}
}
}
// 统一响应格式
@Data
@AllArgsConstructor
public class ApiResponse<T> {
private int code;
private String message;
private T data;
private long timestamp;
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(200, "success", data, System.currentTimeMillis());
}
public static <T> ApiResponse<T> error(String message) {
return new ApiResponse<>(500, message, null, System.currentTimeMillis());
}
}
2. 系统设计实战 - 高并发秒杀系统
2.1 秒杀系统架构设计
秒杀系统核心实现:
java
// 秒杀服务
@Service
@Slf4j
public class SeckillService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private ProductService productService;
@Autowired
private OrderService orderService;
@Autowired
private RabbitTemplate rabbitTemplate;
private static final String SECKILL_STOCK_KEY = "seckill:stock:";
private static final String SECKILL_USER_KEY = "seckill:user:";
private static final String SECKILL_QUEUE = "seckill.queue";
// 初始化秒杀库存
public void initSeckillStock(Long productId, Integer stock) {
String key = SECKILL_STOCK_KEY + productId;
redisTemplate.opsForValue().set(key, String.valueOf(stock));
log.info("初始化秒杀库存: productId={}, stock={}", productId, stock);
}
// 秒杀下单(高并发优化)
public SeckillResult seckill(Long userId, Long productId) {
// 1. 参数验证
if (userId == null || productId == null) {
return SeckillResult.fail("参数错误");
}
// 2. 检查用户是否已参与(防刷)
String userKey = SECKILL_USER_KEY + productId + ":" + userId;
Boolean exists = redisTemplate.hasKey(userKey);
if (Boolean.TRUE.equals(exists)) {
return SeckillResult.fail("您已经参与过本次秒杀");
}
// 3. 预扣库存(Redis原子操作)
String stockKey = SECKILL_STOCK_KEY + productId;
Long stock = redisTemplate.opsForValue().decrement(stockKey);
if (stock == null || stock < 0) {
// 库存不足,恢复库存
redisTemplate.opsForValue().increment(stockKey);
return SeckillResult.fail("商品已抢完");
}
// 4. 标记用户已参与
redisTemplate.opsForValue().set(userKey, "1", 3600, TimeUnit.SECONDS);
// 5. 异步处理订单(消息队列)
SeckillMessage message = new SeckillMessage(userId, productId);
rabbitTemplate.convertAndSend(SECKILL_QUEUE, message);
log.info("秒杀请求已提交: userId={}, productId={}", userId, productId);
return SeckillResult.success("秒杀成功,订单处理中");
}
// 消息队列消费者处理订单
@RabbitListener(queues = "seckill.queue")
public void processSeckillOrder(SeckillMessage message) {
Long userId = message.getUserId();
Long productId = message.getProductId();
try {
// 1. 再次验证库存(数据库层面)
Product product = productService.getProductById(productId);
if (product == null || product.getStock() <= 0) {
log.warn("库存不足,取消订单: userId={}, productId={}", userId, productId);
// 恢复Redis库存
redisTemplate.opsForValue().increment(SECKILL_STOCK_KEY + productId);
return;
}
// 2. 创建订单
CreateOrderRequest request = new CreateOrderRequest();
request.setUserId(userId);
CreateOrderItemRequest itemRequest = new CreateOrderItemRequest();
itemRequest.setProductId(productId);
itemRequest.setQuantity(1);
request.setItems(Collections.singletonList(itemRequest));
OrderDTO order = orderService.createOrder(request);
log.info("秒杀订单创建成功: orderNumber={}, userId={}, productId={}",
order.getOrderNumber(), userId, productId);
} catch (Exception e) {
log.error("处理秒杀订单失败: userId={}, productId={}", userId, productId, e);
// 恢复Redis库存
redisTemplate.opsForValue().increment(SECKILL_STOCK_KEY + productId);
}
}
// 查询秒杀库存
public Integer getSeckillStock(Long productId) {
String stock = redisTemplate.opsForValue().get(SECKILL_STOCK_KEY + productId);
return stock != null ? Integer.parseInt(stock) : 0;
}
}
// 秒杀结果
@Data
@AllArgsConstructor
public class SeckillResult {
private boolean success;
private String message;
public static SeckillResult success(String message) {
return new SeckillResult(true, message);
}
public static SeckillResult fail(String message) {
return new SeckillResult(false, message);
}
}
// 秒杀消息
@Data
@AllArgsConstructor
public class SeckillMessage {
private Long userId;
private Long productId;
}
2.2 限流与防刷策略
防刷与限流实现:
java
// 秒杀限流服务
@Service
@Slf4j
public class SeckillRateLimitService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
// IP限流
public boolean checkIpLimit(String ip, Long productId) {
String key = "seckill:ip:" + productId + ":" + ip;
Long count = redisTemplate.opsForValue().increment(key);
if (count == 1) {
redisTemplate.expire(key, 60, TimeUnit.SECONDS);
}
// 每个IP每分钟最多10次请求
return count <= 10;
}
// 用户限流
public boolean checkUserLimit(Long userId, Long productId) {
String key = "seckill:user:limit:" + productId + ":" + userId;
Long count = redisTemplate.opsForValue().increment(key);
if (count == 1) {
redisTemplate.expire(key, 60, TimeUnit.SECONDS);
}
// 每个用户每分钟最多5次请求
return count <= 5;
}
// 总请求限流
public boolean checkTotalLimit(Long productId) {
String key = "seckill:total:" + productId;
Long count = redisTemplate.opsForValue().increment(key);
if (count == 1) {
redisTemplate.expire(key, 1, TimeUnit.SECONDS);
}
// 每秒最多1000个请求
return count <= 1000;
}
}
// 秒杀控制器(带限流)
@RestController
@RequestMapping("/api/seckill")
@Slf4j
public class SeckillController {
@Autowired
private SeckillService seckillService;
@Autowired
private SeckillRateLimitService rateLimitService;
@PostMapping("/{productId}")
public ResponseEntity<ApiResponse<SeckillResult>> seckill(
@PathVariable Long productId,
HttpServletRequest request) {
// 获取用户ID(从Token中解析)
Long userId = getUserIdFromToken(request);
if (userId == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(ApiResponse.error("未登录"));
}
// 获取IP
String ip = getClientIp(request);
// 1. IP限流
if (!rateLimitService.checkIpLimit(ip, productId)) {
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.body(ApiResponse.error("请求过于频繁,请稍后重试"));
}
// 2. 用户限流
if (!rateLimitService.checkUserLimit(userId, productId)) {
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.body(ApiResponse.error("您操作过于频繁,请稍后重试"));
}
// 3. 总请求限流
if (!rateLimitService.checkTotalLimit(productId)) {
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.body(ApiResponse.error("系统繁忙,请稍后重试"));
}
// 4. 执行秒杀
SeckillResult result = seckillService.seckill(userId, productId);
if (result.isSuccess()) {
return ResponseEntity.ok(ApiResponse.success(result));
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(ApiResponse.error(result.getMessage()));
}
}
@GetMapping("/stock/{productId}")
public ResponseEntity<ApiResponse<Integer>> getStock(@PathVariable Long productId) {
Integer stock = seckillService.getSeckillStock(productId);
return ResponseEntity.ok(ApiResponse.success(stock));
}
private Long getUserIdFromToken(HttpServletRequest request) {
// 从Token中解析用户ID
String token = request.getHeader("Authorization");
// 实现Token解析逻辑
return 1L; // 示例
}
private String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
3. 性能调优实战
3.1 JVM调优实战
JVM参数配置与监控:
java
// JVM监控服务
@Service
@Slf4j
public class JVMMonitorService {
// 获取JVM内存信息
public JVMMemoryInfo getMemoryInfo() {
Runtime runtime = Runtime.getRuntime();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory;
long maxMemory = runtime.maxMemory();
JVMMemoryInfo info = new JVMMemoryInfo();
info.setTotalMemory(totalMemory);
info.setUsedMemory(usedMemory);
info.setFreeMemory(freeMemory);
info.setMaxMemory(maxMemory);
info.setUsagePercent((double) usedMemory / maxMemory * 100);
return info;
}
// 获取GC信息
public List<GCInfo> getGCInfo() {
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
List<GCInfo> gcInfos = new ArrayList<>();
for (GarbageCollectorMXBean gcBean : gcBeans) {
GCInfo info = new GCInfo();
info.setName(gcBean.getName());
info.setCollectionCount(gcBean.getCollectionCount());
info.setCollectionTime(gcBean.getCollectionTime());
gcInfos.add(info);
}
return gcInfos;
}
// 手动触发GC(仅用于测试)
public void triggerGC() {
System.gc();
log.info("手动触发GC");
}
// 获取线程信息
public ThreadInfo getThreadInfo() {
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
ThreadInfo info = new ThreadInfo();
info.setThreadCount(threadBean.getThreadCount());
info.setPeakThreadCount(threadBean.getPeakThreadCount());
info.setTotalStartedThreadCount(threadBean.getTotalStartedThreadCount());
info.setDaemonThreadCount(threadBean.getDaemonThreadCount());
return info;
}
}
// JVM内存信息
@Data
public class JVMMemoryInfo {
private long totalMemory; // 总内存
private long usedMemory; // 已用内存
private long freeMemory; // 空闲内存
private long maxMemory; // 最大内存
private double usagePercent; // 使用率
}
// GC信息
@Data
public class GCInfo {
private String name;
private long collectionCount;
private long collectionTime;
}
// JVM监控控制器
@RestController
@RequestMapping("/api/monitor/jvm")
@Slf4j
public class JVMMonitorController {
@Autowired
private JVMMonitorService monitorService;
@GetMapping("/memory")
public ResponseEntity<ApiResponse<JVMMemoryInfo>> getMemoryInfo() {
JVMMemoryInfo info = monitorService.getMemoryInfo();
return ResponseEntity.ok(ApiResponse.success(info));
}
@GetMapping("/gc")
public ResponseEntity<ApiResponse<List<GCInfo>>> getGCInfo() {
List<GCInfo> infos = monitorService.getGCInfo();
return ResponseEntity.ok(ApiResponse.success(infos));
}
@GetMapping("/thread")
public ResponseEntity<ApiResponse<ThreadInfo>> getThreadInfo() {
ThreadInfo info = monitorService.getThreadInfo();
return ResponseEntity.ok(ApiResponse.success(info));
}
}
// JVM调优建议
@Component
@Slf4j
public class JVMTuningAdvisor {
public JVMTuningAdvice getTuningAdvice(JVMMemoryInfo memoryInfo) {
JVMTuningAdvice advice = new JVMTuningAdvice();
// 内存使用率过高
if (memoryInfo.getUsagePercent() > 80) {
advice.addWarning("内存使用率过高: " + String.format("%.2f%%", memoryInfo.getUsagePercent()));
advice.addSuggestion("建议增加堆内存: -Xmx4g -Xms4g");
}
// 检查GC频率
List<GCInfo> gcInfos = getGCInfo();
for (GCInfo gcInfo : gcInfos) {
if (gcInfo.getCollectionCount() > 1000) {
advice.addWarning("GC频率过高: " + gcInfo.getName() + " 执行了 " + gcInfo.getCollectionCount() + " 次");
advice.addSuggestion("建议使用G1GC: -XX:+UseG1GC -XX:MaxGCPauseMillis=200");
}
}
return advice;
}
private List<GCInfo> getGCInfo() {
// 实现获取GC信息
return Collections.emptyList();
}
}
3.2 数据库性能优化
数据库优化实践:
java
// 数据库性能监控
@Service
@Slf4j
public class DatabasePerformanceService {
@Autowired
private DataSource dataSource;
@Autowired
private JdbcTemplate jdbcTemplate;
// 获取慢查询
public List<SlowQuery> getSlowQueries() {
// MySQL慢查询日志分析
String sql = "SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 100";
// 实际实现需要根据数据库类型调整
return Collections.emptyList();
}
// 分析SQL执行计划
public ExecutionPlan analyzeExecutionPlan(String sql) {
ExecutionPlan plan = new ExecutionPlan();
try {
// 获取执行计划
String explainSql = "EXPLAIN " + sql;
List<Map<String, Object>> results = jdbcTemplate.queryForList(explainSql);
plan.setSql(sql);
plan.setPlans(results);
// 分析执行计划
for (Map<String, Object> result : results) {
String type = (String) result.get("type");
if ("ALL".equals(type)) {
plan.addWarning("全表扫描,建议添加索引");
}
if ("index".equals(type)) {
plan.addWarning("全索引扫描,考虑优化查询条件");
}
}
} catch (Exception e) {
log.error("分析执行计划失败", e);
plan.addError("分析失败: " + e.getMessage());
}
return plan;
}
// 索引优化建议
public List<IndexSuggestion> getIndexSuggestions() {
List<IndexSuggestion> suggestions = new ArrayList<>();
// 查询未使用索引的表
String sql = "SELECT table_name, index_name, seq_in_index, column_name " +
"FROM information_schema.statistics " +
"WHERE table_schema = DATABASE() " +
"ORDER BY table_name, index_name";
// 分析索引使用情况
// 实际实现需要查询数据库元数据
return suggestions;
}
}
// 执行计划
@Data
public class ExecutionPlan {
private String sql;
private List<Map<String, Object>> plans;
private List<String> warnings = new ArrayList<>();
private List<String> errors = new ArrayList<>();
public void addWarning(String warning) {
warnings.add(warning);
}
public void addError(String error) {
errors.add(error);
}
}
// 批量操作优化
@Service
@Slf4j
public class BatchOperationOptimizer {
@Autowired
private JdbcTemplate jdbcTemplate;
// 批量插入优化
public void batchInsert(List<Order> orders) {
String sql = "INSERT INTO t_order (order_number, user_id, total_amount, status, create_time) " +
"VALUES (?, ?, ?, ?, ?)";
int batchSize = 1000;
List<Object[]> batchArgs = new ArrayList<>();
for (Order order : orders) {
Object[] args = new Object[]{
order.getOrderNumber(),
order.getUserId(),
order.getTotalAmount(),
order.getStatus().name(),
order.getCreateTime()
};
batchArgs.add(args);
if (batchArgs.size() >= batchSize) {
jdbcTemplate.batchUpdate(sql, batchArgs);
batchArgs.clear();
}
}
if (!batchArgs.isEmpty()) {
jdbcTemplate.batchUpdate(sql, batchArgs);
}
}
// 使用MyBatis Plus批量插入
@Autowired
private OrderMapper orderMapper;
public void batchInsertWithMyBatisPlus(List<Order> orders) {
// MyBatis Plus批量插入
orderMapper.insertBatch(orders);
}
}
4. 故障排查与监控
4.1 日志分析与监控
日志监控与分析:
java
// 日志分析服务
@Service
@Slf4j
public class LogAnalysisService {
// 分析错误日志
public List<ErrorLog> analyzeErrorLogs(String logFile, Date startTime, Date endTime) {
List<ErrorLog> errorLogs = new ArrayList<>();
try {
Path path = Paths.get(logFile);
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
if (line.contains("ERROR") || line.contains("Exception")) {
ErrorLog errorLog = parseErrorLog(line);
if (errorLog != null && isInTimeRange(errorLog.getTimestamp(), startTime, endTime)) {
errorLogs.add(errorLog);
}
}
}
} catch (IOException e) {
log.error("读取日志文件失败", e);
}
return errorLogs;
}
// 统计错误类型
public Map<String, Integer> countErrorTypes(List<ErrorLog> errorLogs) {
return errorLogs.stream()
.collect(Collectors.groupingBy(
ErrorLog::getErrorType,
Collectors.collectingAndThen(Collectors.counting(), Long::intValue)
));
}
// 分析性能日志
public List<PerformanceLog> analyzePerformanceLogs(String logFile) {
List<PerformanceLog> performanceLogs = new ArrayList<>();
// 解析性能日志
// 实际实现需要根据日志格式解析
return performanceLogs;
}
private ErrorLog parseErrorLog(String line) {
// 解析错误日志
// 实际实现需要根据日志格式解析
return null;
}
private boolean isInTimeRange(Date timestamp, Date startTime, Date endTime) {
return timestamp.after(startTime) && timestamp.before(endTime);
}
}
// 错误日志
@Data
public class ErrorLog {
private Date timestamp;
private String level;
private String errorType;
private String message;
private String stackTrace;
}
// 性能日志
@Data
public class PerformanceLog {
private Date timestamp;
private String method;
private long executionTime;
private String parameters;
}
// APM监控
@Component
@Slf4j
public class APMMonitor {
// 方法执行时间监控
@Around("@annotation(MonitorPerformance)")
public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
String methodName = joinPoint.getSignature().toShortString();
try {
Object result = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - startTime;
// 记录性能日志
logPerformance(methodName, executionTime, true);
// 如果执行时间过长,记录警告
if (executionTime > 1000) {
log.warn("方法执行时间过长: method={}, time={}ms", methodName, executionTime);
}
return result;
} catch (Exception e) {
long executionTime = System.currentTimeMillis() - startTime;
logPerformance(methodName, executionTime, false);
throw e;
}
}
private void logPerformance(String methodName, long executionTime, boolean success) {
// 发送到监控系统
// 实际实现可以发送到Prometheus、InfluxDB等
}
}
// 性能监控注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MonitorPerformance {
String value() default "";
}
4.2 健康检查与告警
健康检查实现:
java
// 健康检查服务
@Component
@Slf4j
public class HealthCheckService {
@Autowired
private DataSource dataSource;
@Autowired
private RedisTemplate<String, String> redisTemplate;
// 数据库健康检查
public HealthStatus checkDatabase() {
try {
Connection connection = dataSource.getConnection();
boolean valid = connection.isValid(5);
connection.close();
if (valid) {
return HealthStatus.healthy("数据库连接正常");
} else {
return HealthStatus.unhealthy("数据库连接异常");
}
} catch (Exception e) {
return HealthStatus.unhealthy("数据库健康检查失败: " + e.getMessage());
}
}
// Redis健康检查
public HealthStatus checkRedis() {
try {
String result = redisTemplate.execute((RedisCallback<String>) connection -> {
return connection.ping();
});
if ("PONG".equals(result)) {
return HealthStatus.healthy("Redis连接正常");
} else {
return HealthStatus.unhealthy("Redis连接异常");
}
} catch (Exception e) {
return HealthStatus.unhealthy("Redis健康检查失败: " + e.getMessage());
}
}
// 综合健康检查
public Map<String, HealthStatus> checkAll() {
Map<String, HealthStatus> statuses = new HashMap<>();
statuses.put("database", checkDatabase());
statuses.put("redis", checkRedis());
// 添加其他检查项
return statuses;
}
}
// 健康状态
@Data
@AllArgsConstructor
public class HealthStatus {
private boolean healthy;
private String message;
private Date checkTime;
public static HealthStatus healthy(String message) {
return new HealthStatus(true, message, new Date());
}
public static HealthStatus unhealthy(String message) {
return new HealthStatus(false, message, new Date());
}
}
// 告警服务
@Service
@Slf4j
public class AlertService {
// 发送告警
public void sendAlert(AlertLevel level, String message) {
log.warn("告警: level={}, message={}", level, message);
// 根据告警级别发送通知
switch (level) {
case CRITICAL:
// 发送紧急通知(短信、电话等)
sendCriticalAlert(message);
break;
case WARNING:
// 发送警告通知(邮件、企业微信等)
sendWarningAlert(message);
break;
case INFO:
// 记录信息
log.info("告警信息: {}", message);
break;
}
}
private void sendCriticalAlert(String message) {
// 实现紧急告警逻辑
log.error("紧急告警: {}", message);
}
private void sendWarningAlert(String message) {
// 实现警告告警逻辑
log.warn("警告告警: {}", message);
}
}
enum AlertLevel {
INFO, WARNING, CRITICAL
}
5. 面试准备
5.1 常见面试题
核心面试题解答:
java
// 1. 如何实现线程安全的单例模式?
public class Singleton {
// 双重检查锁定
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
// 静态内部类方式(推荐)
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance2() {
return SingletonHolder.INSTANCE;
}
}
// 2. 如何实现生产者消费者模式?
@Component
@Slf4j
public class ProducerConsumerExample {
private final BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);
// 生产者
@Async
public void produce(String item) throws InterruptedException {
queue.put(item);
log.info("生产: {}", item);
}
// 消费者
@Async
public void consume() throws InterruptedException {
String item = queue.take();
log.info("消费: {}", item);
}
}
// 3. 如何实现LRU缓存?
public class LRUCache<K, V> {
private final int capacity;
private final LinkedHashMap<K, V> cache;
public LRUCache(int capacity) {
this.capacity = capacity;
this.cache = new LinkedHashMap<K, V>(capacity, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
};
}
public synchronized V get(K key) {
return cache.get(key);
}
public synchronized void put(K key, V value) {
cache.put(key, value);
}
}
// 4. 如何实现分布式锁?
// 见前面章节的Redis分布式锁实现
// 5. 如何设计一个高并发的秒杀系统?
// 见前面章节的秒杀系统实现
5.2 系统设计题
系统设计题解答框架:
java
// 系统设计:设计一个短链接系统
@Service
@Slf4j
public class ShortUrlService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private ShortUrlRepository shortUrlRepository;
private static final String SHORT_URL_PREFIX = "https://short.ly/";
private static final String BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 生成短链接
public String generateShortUrl(String longUrl) {
// 1. 检查是否已存在
String existingShortUrl = redisTemplate.opsForValue().get("long:" + longUrl);
if (existingShortUrl != null) {
return existingShortUrl;
}
// 2. 生成短链接
String shortCode = generateShortCode();
String shortUrl = SHORT_URL_PREFIX + shortCode;
// 3. 保存映射关系
ShortUrlMapping mapping = new ShortUrlMapping();
mapping.setShortCode(shortCode);
mapping.setLongUrl(longUrl);
mapping.setCreateTime(new Date());
shortUrlRepository.save(mapping);
// 4. 缓存
redisTemplate.opsForValue().set("short:" + shortCode, longUrl, 7, TimeUnit.DAYS);
redisTemplate.opsForValue().set("long:" + longUrl, shortUrl, 7, TimeUnit.DAYS);
return shortUrl;
}
// 获取原始链接
public String getLongUrl(String shortCode) {
// 1. 从缓存获取
String longUrl = redisTemplate.opsForValue().get("short:" + shortCode);
if (longUrl != null) {
return longUrl;
}
// 2. 从数据库获取
ShortUrlMapping mapping = shortUrlRepository.findByShortCode(shortCode);
if (mapping != null) {
// 更新缓存
redisTemplate.opsForValue().set("short:" + shortCode, mapping.getLongUrl(), 7, TimeUnit.DAYS);
return mapping.getLongUrl();
}
throw new ShortUrlNotFoundException("短链接不存在");
}
// 生成短码(Base62编码)
private String generateShortCode() {
// 使用雪花算法生成ID,然后Base62编码
long id = snowflakeIdGenerator.nextId();
return base62Encode(id);
}
private String base62Encode(long num) {
StringBuilder sb = new StringBuilder();
while (num > 0) {
sb.append(BASE62.charAt((int) (num % 62)));
num /= 62;
}
return sb.reverse().toString();
}
}
6. 学习路径总结
6.1 知识体系梳理
30天学习成果总结:
java
// 学习路径总结
/**
* Java学习30天知识体系
*
* 基础阶段(Day 1-10)
* - Java基础语法
* - 面向对象编程
* - 集合框架
* - 异常处理
* - I/O流
* - 多线程
*
* 进阶阶段(Day 11-20)
* - Spring框架
* - Spring Boot
* - 数据库操作(JDBC、MyBatis)
* - RESTful API
* - 事务管理
* - 缓存技术
*
* 高级阶段(Day 21-30)
* - 微服务架构
* - 分布式系统
* - 消息队列
* - 分布式事务
* - 性能优化
* - 系统设计
*
* 核心技能点:
* 1. Java基础扎实
* 2. Spring生态熟练
* 3. 数据库优化能力
* 4. 分布式系统设计
* 5. 性能调优经验
* 6. 系统架构能力
*/
6.2 后续学习建议
继续学习方向:
java
/**
* 后续学习建议
*
* 1. 深入学习
* - 深入理解JVM原理
* - 学习设计模式实战
* - 掌握更多中间件(Kafka、Elasticsearch等)
*
* 2. 实践项目
* - 参与开源项目
* - 构建个人项目
* - 解决实际问题
*
* 3. 技术拓展
* - 学习云原生技术(Kubernetes、Docker)
* - 了解前端技术(Vue、React)
* - 学习大数据技术(Hadoop、Spark)
*
* 4. 软技能
* - 提升代码质量
* - 学习系统设计
* - 加强沟通能力
*/