
1. 项目背景与核心挑战支付系统作为电商平台的核心模块对稳定性、性能和一致性的要求极高。去年我在参与某跨境电商平台支付系统重构时就遇到了一个典型的高并发支付场景在促销活动期间系统需要处理每秒超过5000笔的支付请求同时保证每笔交易的幂等性和数据一致性。这个场景下我们需要解决三个核心问题高并发下的Redis缓存穿透/雪崩分布式环境下的接口幂等性保障第三方支付渠道不稳定时的熔断降级2. 技术栈选型解析2.1 Spring Boot作为基础框架选择Spring Boot 2.7.x版本主要基于自动配置简化了Redis、Resilience4j等组件的集成内嵌Tomcat支持高并发请求处理Actuator提供完善的监控端点关键配置示例server: tomcat: max-threads: 800 accept-count: 10002.2 Redis缓存方案设计采用Redis 6.2集群实现支付订单缓存分布式锁接口幂等令牌存储防雪崩策略// 缓存空对象解决穿透问题 redisTemplate.opsForValue().set(key, NULL, 5, TimeUnit.MINUTES); // 互斥锁防止缓存击穿 Boolean locked redisTemplate.opsForValue().setIfAbsent(lockKey, 1, 30, TimeUnit.SECONDS);2.3 Resilience4j熔断配置针对第三方支付接口的配置参数CircuitBreakerConfig.custom() .failureRateThreshold(50) // 失败率阈值 .waitDurationInOpenState(Duration.ofMillis(1000)) // 熔断时间 .ringBufferSizeInHalfOpenState(10) // 半开状态探测请求数 .ringBufferSizeInClosedState(100) // 关闭状态样本数 .build();3. 支付核心流程实现3.1 幂等性设计采用tokenredis方案前端预获取幂等token有效期5分钟支付请求必须携带token服务端Redis原子性校验public boolean checkIdempotent(String token) { String redisKey pay:idempotent: token; Long result redisTemplate.opsForValue().increment(redisKey); if(result 1) { redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES); return true; } return false; }3.2 分布式锁实现Redisson实现的库存扣减RLock lock redissonClient.getLock(stock: productId); try { if(lock.tryLock(1, 10, TimeUnit.SECONDS)) { // 扣减库存逻辑 } } finally { lock.unlock(); }3.3 熔断降级策略支付失败时的降级方案本地队列重试最多3次记录到MySQL待补偿表返回友好提示页面4. 性能优化实战4.1 Redis管道批处理批量查询优化示例ListObject results redisTemplate.executePipelined((RedisCallbackObject) connection - { for(String orderNo : orderNos) { connection.get((order: orderNo).getBytes()); } return null; });4.2 热点数据分离将支付结果与支付日志分离存储Redis存储支付状态设置TTLMySQL存储完整支付流水Elasticsearch存储查询日志5. 踩坑实录与解决方案5.1 Redis连接池耗尽现象高峰期出现max number of clients reached错误解决方案调整连接池参数spring: redis: lettuce: pool: max-active: 200 max-idle: 50 min-idle: 20增加Redis集群节点引入连接池监控5.2 分布式锁误用错误案例锁过期时间小于业务执行时间导致并发问题正确做法// 使用看门狗自动续期 lock.lock(30, TimeUnit.SECONDS); // 业务代码... lock.unlock();5.3 熔断配置不当错误配置半开状态探测请求数设置过小优化方案.ringBufferSizeInHalfOpenState(20) // 根据实际QPS调整 .recordExceptions(TimeoutException.class) // 只针对超时熔断6. 监控与告警体系6.1 Prometheus监控指标关键监控项支付接口成功率Redis命中率熔断器状态变化线程池活跃度6.2 日志排查技巧使用MDC实现请求链路追踪MDC.put(traceId, UUID.randomUUID().toString()); try { // 业务逻辑 } finally { MDC.clear(); }日志配置示例pattern%d{yyyy-MM-dd HH:mm:ss} [%X{traceId}] %-5level %logger{36} - %msg%n/pattern7. 面试要点解析7.1 高频面试问题Redis持久化策略如何选择RDB适合备份恢复AOF保证数据安全生产环境建议混合使用如何设计分布式ID生成器雪花算法SnowflakeRedis原子自增数据库号段模式熔断与降级的区别熔断自动故障保护降级手动功能简化7.2 实战经验分享在压力测试中发现Redis集群在节点故障转移时会有200ms左右的抖动Resilience4j的熔断恢复时间需要根据业务特点调整Spring Boot的Tomcat参数需要根据服务器配置优化