Java后端开发面试题清单(50道) - 分布式基础

Java后端开发面试题清单(50道)

分布式基础(5题)

46. CAP定理与权衡
java 复制代码
// CAP定理实践示例
@Component
public class CAPTheoremExamples {
    
    // 1. CP系统(一致性+分区容错性)
    @Service
    public class CPDatabase {
        
        // 使用ZooKeeper实现CP
        @Autowired
        private CuratorFramework zkClient;
        
        public void writeData(String path, String data) throws Exception {
            // ZooKeeper保证强一致性
            Stat stat = zkClient.checkExists().forPath(path);
            
            if (stat == null) {
                zkClient.create().creatingParentsIfNeeded().forPath(path, 
                    data.getBytes());
            } else {
                zkClient.setData().forPath(path, data.getBytes());
            }
            
            // 写入需要多数节点确认,可能牺牲可用性
        }
        
        public String readData(String path) throws Exception {
            // 读取最新数据,保证一致性
            byte[] data = zkClient.getData().forPath(path);
            return new String(data);
        }
    }
    
    // 2. AP系统(可用性+分区容错性)
    @Service
    public class APCache {
        
        // 使用Redis集群实现AP
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
        
        public void writeData(String key, String value) {
            // Redis主从异步复制,优先保证可用性
            redisTemplate.opsForValue().set(key, value);
            
            // 数据可能延迟同步到从节点
        }
        
        public String readData(String key) {
            // 优先从主节点读取,保证可用性
            // 可能读到旧数据(最终一致性)
            return redisTemplate.opsForValue().get(key);
        }
    }
    
    // 3. 根据业务场景选择
    @Service
    public class TradeOffService {
        
        // 场景1:支付系统(需要CP)
        @Transactional
        public void processPayment(PaymentRequest request) {
            // 支付需要强一致性
            // 使用分布式事务保证ACID
            
            // 1. 扣减账户余额
            accountService.deductBalance(request.getUserId(), 
                request.getAmount());
            
            // 2. 增加商户余额
            merchantService.addBalance(request.getMerchantId(), 
                request.getAmount());
            
            // 3. 记录交易流水
            transactionService.recordTransaction(request);
            
            // 所有操作必须同时成功或失败
            // 牺牲一定可用性,保证数据一致性
        }
        
        // 场景2:社交网络点赞(可以AP)
        public void likePost(String userId, String postId) {
            // 点赞可以最终一致
            // 优先保证可用性
            
            // 1. 本地缓存点赞
            localCache.addLike(userId, postId);
            
            // 2. 异步同步到数据库
            asyncSaveLike(userId, postId);
            
            // 3. 返回成功,即使同步失败用户也无感知
            // 通过后台任务补偿
            
            // 保证高可用,接受短暂数据不一致
        }
        
        // 场景3:电商库存(需要权衡)
        public boolean deductInventory(String productId, int quantity) {
            // 方案1:CP模式(强一致性)
            // 使用分布式锁,保证不超卖
            // 可能影响并发性能
            
            // 方案2:AP模式(最终一致性)
            // 使用Redis预扣库存,异步同步
            // 可能超卖,但性能好
            
            // 实际方案:混合策略
            // 热点商品用CP,普通商品用AP
            
            if (isHotProduct(productId)) {
                return deductWithLock(productId, quantity);  // CP
            } else {
                return deductWithCache(productId, quantity);  // AP
            }
        }
    }
    
    // 4. BASE理论(Basically Available, Soft state, Eventually consistent)
    @Service
    public class BASEService {
        
        // 基本可用(Basic Availability)
        public Response getProductInfo(String productId) {
            try {
                // 尝试获取完整信息
                Product product = productService.getFullInfo(productId);
                return Response.success(product);
                
            } catch (Exception e) {
                // 降级:返回基本信息
                Product basicInfo = productService.getBasicInfo(productId);
                return Response.success(basicInfo);
            }
        }
        
        // 软状态(Soft State)
        public void updateUserProfile(UserProfile profile) {
            // 允许中间状态存在
            // 1. 标记为更新中
            profile.setStatus("UPDATING");
            profileRepository.save(profile);
            
            // 2. 异步处理复杂逻辑
            asyncProcessProfile(profile);
            
            // 3. 完成后更新状态
            profile.setStatus("ACTIVE");
            profileRepository.save(profile);
        }
        
        // 最终一致性(Eventual Consistency)
        public void syncData(String source, String target) {
            // 使用消息队列保证最终一致
            Message message = new Message(source, target);
            
            // 发送消息
            messageQueue.send(message);
            
            // 消费者异步处理
            // 1. 从source读取数据
            // 2. 写入target
            // 3. 重试机制保证最终成功
        }
    }
}
47. 分布式锁实现方案
java 复制代码
// 分布式锁实现对比
@Component
public class DistributedLockImplementations {
    
    // 1. 基于Redis的分布式锁
    @Service
    public class RedisDistributedLock {
        
        private static final String LOCK_PREFIX = "lock:";
        private static final long DEFAULT_EXPIRE = 30000;  // 30秒
        private static final long DEFAULT_WAIT = 10000;    // 10秒
        private static final long RETRY_INTERVAL = 100;    // 100毫秒
        
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
        
        // 简单实现(setnx)
        public boolean tryLockSimple(String key, String value, long expireMs) {
            Boolean success = redisTemplate.opsForValue()
                .setIfAbsent(LOCK_PREFIX + key, value, 
                    expireMs, TimeUnit.MILLISECONDS);
            return Boolean.TRUE.equals(success);
        }
        
        // RedLock算法(多节点)
        public boolean tryRedLock(String key, String value, long expireMs) {
            List<RedisNode> nodes = getRedisNodes();
            int successCount = 0;
            
            long startTime = System.currentTimeMillis();
            
            for (RedisNode node : nodes) {
                try {
                    if (tryLockOnNode(node, key, value, expireMs)) {
                        successCount++;
                    }
                } catch (Exception e) {
                    // 忽略节点异常
                }
            }
            
            long elapsed = System.currentTimeMillis() - startTime;
            
            // 检查是否在有效时间内获得多数锁
            boolean locked = successCount >= nodes.size() / 2 + 1;
            locked = locked && elapsed < expireMs;
            
            if (!locked) {
                // 释放已获得的锁
                unlockRedLock(key, value);
            }
            
            return locked;
        }
        
        // 可重入锁
        public boolean tryReentrantLock(String key, String value, 
                                       long expireMs) {
            String lockKey = LOCK_PREFIX + key;
            
            // 检查是否已持有锁
            String currentValue = redisTemplate.opsForValue().get(lockKey);
            if (value.equals(currentValue)) {
                // 重入,刷新过期时间
                redisTemplate.expire(lockKey, expireMs, TimeUnit.MILLISECONDS);
                return true;
            }
            
            // 尝试获取锁
            return tryLockSimple(key, value, expireMs);
        }
        
        // 看门狗机制(自动续期)
        public boolean tryLockWithWatchdog(String key, String value, 
                                          long expireMs) {
            if (tryLockSimple(key, value, expireMs)) {
                // 启动看门狗线程
                startWatchdog(key, value, expireMs);
                return true;
            }
            return false;
        }
        
        private void startWatchdog(String key, String value, long expireMs) {
            ScheduledExecutorService scheduler = 
                Executors.newSingleThreadScheduledExecutor();
            
            // 定期续期
            scheduler.scheduleAtFixedRate(() -> {
                String lockKey = LOCK_PREFIX + key;
                String currentValue = redisTemplate.opsForValue().get(lockKey);
                
                if (value.equals(currentValue)) {
                    // 续期
                    redisTemplate.expire(lockKey, expireMs, 
                        TimeUnit.MILLISECONDS);
                } else {
                    // 锁已丢失,停止续期
                    scheduler.shutdown();
                }
            }, expireMs / 3, expireMs / 3, TimeUnit.MILLISECONDS);
        }
    }
    
    // 2. 基于ZooKeeper的分布式锁
    @Service
    public class ZooKeeperDistributedLock {
        
        @Autowired
        private CuratorFramework zkClient;
        
        private static final String LOCK_PATH = "/locks/";
        
        // 互斥锁
        public boolean tryMutexLock(String lockName, long timeoutMs) 
            throws Exception {
            
            String lockPath = LOCK_PATH + lockName;
            
            // 创建临时节点
            String nodePath = zkClient.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL)
                .forPath(lockPath);
            
            return true;
        }
        
        // 顺序锁(公平锁)
        public String trySequentialLock(String lockName) throws Exception {
            String lockPath = LOCK_PATH + lockName;
            
            // 创建临时顺序节点
            String nodePath = zkClient.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                .forPath(lockPath + "/lock-");
            
            // 获取所有子节点
            List<String> children = zkClient.getChildren()
                .forPath(lockPath);
            
            Collections.sort(children);
            
            // 检查是否是最小节点
            String currentNode = nodePath.substring(nodePath.lastIndexOf("/") + 1);
            if (currentNode.equals(children.get(0))) {
                return nodePath;  // 获得锁
            }
            
            // 监听前一个节点
            String previousNode = children.get(children.indexOf(currentNode) - 1);
            CountDownLatch latch = new CountDownLatch(1);
            
            Watcher watcher = new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    if (event.getType() == Event.EventType.NodeDeleted) {
                        latch.countDown();
                    }
                }
            };
            
            zkClient.checkExists()
                .usingWatcher(watcher)
                .forPath(lockPath + "/" + previousNode);
            
            // 等待前一个节点释放
            latch.await();
            
            return nodePath;
        }
        
        // 读写锁
        public class ReadWriteLock {
            private final String basePath;
            
            public ReadWriteLock(String lockName) {
                this.basePath = LOCK_PATH + lockName;
            }
            
            public String readLock() throws Exception {
                // 创建读锁节点
                String nodePath = zkClient.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                    .forPath(basePath + "/read-");
                
                // 检查是否有写锁在前面
                if (!hasWriteLockBefore(nodePath)) {
                    return nodePath;
                }
                
                // 等待写锁释放
                waitForWriteLock(nodePath);
                return nodePath;
            }
            
            public String writeLock() throws Exception {
                // 创建写锁节点
                String nodePath = zkClient.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                    .forPath(basePath + "/write-");
                
                // 检查是否是最小节点
                if (isSmallestNode(nodePath)) {
                    return nodePath;
                }
                
                // 等待前面的锁释放
                waitForPreviousLocks(nodePath);
                return nodePath;
            }
        }
    }
    
    // 3. 基于数据库的分布式锁
    @Service
    public class DatabaseDistributedLock {
        
        @Autowired
        private JdbcTemplate jdbcTemplate;
        
        // 基于唯一索引
        public boolean tryLockWithUniqueIndex(String lockKey, 
                                             String owner, 
                                             long expireSeconds) {
            String sql = "INSERT INTO distributed_locks " +
                        "(lock_key, owner, expire_time) VALUES (?, ?, ?) " +
                        "ON DUPLICATE KEY UPDATE " +
                        "owner = IF(expire_time < NOW(), VALUES(owner), owner), " +
                        "expire_time = IF(expire_time < NOW(), VALUES(expire_time), expire_time)";
            
            Timestamp expireTime = new Timestamp(
                System.currentTimeMillis() + expireSeconds * 1000);
            
            try {
                int rows = jdbcTemplate.update(sql, 
                    lockKey, owner, expireTime);
                return rows > 0;
            } catch (DuplicateKeyException e) {
                return false;
            }
        }
        
        // 基于乐观锁
        public boolean tryLockWithOptimisticLock(String lockKey, 
                                                String owner) {
            // 先查询当前锁状态
            String querySql = "SELECT version FROM distributed_locks " +
                             "WHERE lock_key = ?";
            Integer version = jdbcTemplate.queryForObject(
                querySql, Integer.class, lockKey);
            
            if (version == null) {
                // 插入新记录
                String insertSql = "INSERT INTO distributed_locks " +
                                  "(lock_key, owner, version) VALUES (?, ?, 1)";
                return jdbcTemplate.update(insertSql, lockKey, owner) > 0;
            }
            
            // 尝试更新
            String updateSql = "UPDATE distributed_locks " +
                              "SET owner = ?, version = version + 1 " +
                              "WHERE lock_key = ? AND version = ?";
            return jdbcTemplate.update(updateSql, 
                owner, lockKey, version) > 0;
        }
        
        // 基于悲观锁(SELECT FOR UPDATE)
        @Transactional
        public boolean tryLockWithPessimisticLock(String lockKey, 
                                                 String owner) {
            String sql = "SELECT * FROM distributed_locks " +
                        "WHERE lock_key = ? FOR UPDATE";
            
            List<Map<String, Object>> results = jdbcTemplate
                .queryForList(sql, lockKey);
            
            if (results.isEmpty()) {
                // 插入新锁
                String insertSql = "INSERT INTO distributed_locks " +
                                  "(lock_key, owner) VALUES (?, ?)";
                return jdbcTemplate.update(insertSql, lockKey, owner) > 0;
            }
            
            Map<String, Object> lock = results.get(0);
            Timestamp expireTime = (Timestamp) lock.get("expire_time");
            
            if (expireTime != null && expireTime.before(new Date())) {
                // 锁已过期,可以获取
                String updateSql = "UPDATE distributed_locks " +
                                  "SET owner = ?, expire_time = NULL " +
                                  "WHERE lock_key = ?";
                return jdbcTemplate.update(updateSql, owner, lockKey) > 0;
            }
            
            return false;
        }
    }
    
    // 4. 对比分析
    @Service
    public class LockComparison {
        
        public void compareLocks() {
            // Redis分布式锁
            // 优点:性能高,实现简单
            // 缺点:可靠性依赖Redis,网络分区可能有问题
            // 适用场景:对性能要求高,可以接受偶发的锁失效
            
            // ZooKeeper分布式锁
            // 优点:可靠性高,原生支持顺序锁、读写锁
            // 缺点:性能较低,依赖ZooKeeper集群
            // 适用场景:对可靠性要求高,需要高级锁特性
            
            // 数据库分布式锁
            // 优点:实现简单,依赖现有数据库
            // 缺点:性能差,对数据库压力大
            // 适用场景:并发量低,已有数据库环境
            
            // 选择建议:
            // 1. 高并发场景:Redis(配合RedLock)
            // 2. 强一致场景:ZooKeeper
            // 3. 简单场景:数据库
            // 4. 混合使用:根据业务特点选择
        }
        
        // 锁抽象接口
        public interface DistributedLock {
            boolean tryLock(String key, long timeout, TimeUnit unit);
            void unlock(String key);
            boolean isLocked(String key);
        }
        
        // 锁工厂
        @Component
        public class LockFactory {
            
            @Autowired
            private RedisDistributedLock redisLock;
            
            @Autowired
            private ZooKeeperDistributedLock zkLock;
            
            @Autowired
            private DatabaseDistributedLock dbLock;
            
            public DistributedLock getLock(LockType type) {
                switch (type) {
                    case REDIS:
                        return new RedisLockAdapter(redisLock);
                    case ZOOKEEPER:
                        return new ZooKeeperLockAdapter(zkLock);
                    case DATABASE:
                        return new DatabaseLockAdapter(dbLock);
                    default:
                        throw new IllegalArgumentException();
                }
            }
            
            // 根据场景自动选择
            public DistributedLock getLockByScenario(String scenario) {
                if (isHighConcurrency(scenario)) {
                    return getLock(LockType.REDIS);
                } else if (requiresStrongConsistency(scenario)) {
                    return getLock(LockType.ZOOKEEPER);
                } else {
                    return getLock(LockType.DATABASE);
                }
            }
        }
    }
}
48. 服务注册与发现实现
java 复制代码
// 服务注册与发现系统
@Component
public class ServiceRegistryDiscovery {
    
    // 1. 服务注册中心
    @Service
    public class ServiceRegistry {
        
        // 注册表存储
        @Entity
        @Table(name = "service_instances")
        @Data
        public class ServiceInstance {
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            private Long id;
            
            @Column(name = "service_name", length = 100)
            private String serviceName;
            
            @Column(name = "instance_id", length = 100)
            private String instanceId;
            
            @Column(name = "host", length = 100)
            private String host;
            
            @Column(name = "port")
            private Integer port;
            
            @Column(name = "health_check_url", length = 500)
            private String healthCheckUrl;
            
            @Column(name = "metadata", columnDefinition = "TEXT")
            private String metadata;  // JSON格式
            
            @Column(name = "status")
            private Integer status = 1;  // 1:UP, 0:DOWN
            
            @Column(name = "last_heartbeat")
            private Date lastHeartbeat;
            
            @Column(name = "register_time")
            private Date registerTime;
        }
        
        // 服务注册
        @PostMapping("/register")
        public Response register(@RequestBody RegisterRequest request) {
            // 参数验证
            validateRegisterRequest(request);
            
            // 检查是否已注册
            ServiceInstance existing = instanceRepository
                .findByServiceAndInstance(
                    request.getServiceName(), 
                    request.getInstanceId());
            
            if (existing != null) {
                // 更新心跳时间
                existing.setLastHeartbeat(new Date());
                existing.setStatus(1);
                instanceRepository.save(existing);
                
                return Response.success("服务已存在,心跳更新");
            }
            
            // 创建新实例
            ServiceInstance instance = new ServiceInstance();
            instance.setServiceName(request.getServiceName());
            instance.setInstanceId(request.getInstanceId());
            instance.setHost(request.getHost());
            instance.setPort(request.getPort());
            instance.setHealthCheckUrl(request.getHealthCheckUrl());
            instance.setMetadata(request.getMetadata());
            instance.setLastHeartbeat(new Date());
            instance.setRegisterTime(new Date());
            
            instanceRepository.save(instance);
            
            // 发布服务变更事件
            eventPublisher.publishEvent(
                new ServiceRegisteredEvent(instance));
            
            return Response.success("注册成功");
        }
        
        // 服务下线
        @PostMapping("/deregister")
        public Response deregister(@RequestBody DeregisterRequest request) {
            ServiceInstance instance = instanceRepository
                .findByServiceAndInstance(
                    request.getServiceName(), 
                    request.getInstanceId());
            
            if (instance != null) {
                // 标记为下线
                instance.setStatus(0);
                instanceRepository.save(instance);
                
                // 发布服务下线事件
                eventPublisher.publishEvent(
                    new ServiceDeregisteredEvent(instance));
            }
            
            return Response.success("下线成功");
        }
        
        // 心跳机制
        @PostMapping("/heartbeat")
        public Response heartbeat(@RequestBody HeartbeatRequest request) {
            ServiceInstance instance = instanceRepository
                .findByServiceAndInstance(
                    request.getServiceName(), 
                    request.getInstanceId());
            
            if (instance != null) {
                instance.setLastHeartbeat(new Date());
                instance.setStatus(1);
                instanceRepository.save(instance);
                
                return Response.success("心跳接收");
            }
            
            return Response.error("服务实例不存在");
        }
        
        // 健康检查
        @Scheduled(fixedRate = 30000)  // 每30秒检查一次
        public void healthCheck() {
            List<ServiceInstance> instances = instanceRepository
                .findAllActiveInstances();
            
            for (ServiceInstance instance : instances) {
                try {
                    // 发送健康检查请求
                    ResponseEntity<String> response = restTemplate
                        .getForEntity(instance.getHealthCheckUrl(), String.class);
                    
                    if (!response.getStatusCode().is2xxSuccessful()) {
                        // 标记为不健康
                        instance.setStatus(0);
                        instanceRepository.save(instance);
                    }
                } catch (Exception e) {
                    // 健康检查失败
                    instance.setStatus(0);
                    instanceRepository.save(instance);
                    
                    // 发布服务故障事件
                    eventPublisher.publishEvent(
                        new ServiceUnhealthyEvent(instance));
                }
            }
        }
        
        // 实例过期清理
        @Scheduled(fixedRate = 60000)  // 每分钟清理一次
        public void cleanupExpiredInstances() {
            Date threshold = new Date(
                System.currentTimeMillis() - 90000);  // 90秒未心跳
            
            List<ServiceInstance> expired = instanceRepository
                .findExpiredInstances(threshold);
            
            for (ServiceInstance instance : expired) {
                // 标记为过期
                instance.setStatus(0);
                instanceRepository.save(instance);
                
                // 发布实例过期事件
                eventPublisher.publishEvent(
                    new InstanceExpiredEvent(instance));
            }
        }
    }
    
    // 2. 服务发现客户端
    @Service
    public class ServiceDiscoveryClient {
        
        // 服务缓存
        private final Map<String, List<ServiceInstance>> serviceCache = 
            new ConcurrentHashMap<>();
        
        private final ScheduledExecutorService scheduler = 
            Executors.newScheduledThreadPool(1);
        
        @PostConstruct
        public void init() {
            // 定期刷新服务缓存
            scheduler.scheduleAtFixedRate(this::refreshCache, 
                0, 30, TimeUnit.SECONDS);
        }
        
        // 服务发现
        public List<ServiceInstance> discover(String serviceName) {
            // 先从缓存获取
            List<ServiceInstance> instances = serviceCache.get(serviceName);
            
            if (instances == null || instances.isEmpty()) {
                // 从注册中心获取
                instances = fetchFromRegistry(serviceName);
                if (instances != null) {
                    serviceCache.put(serviceName, instances);
                }
            }
            
            // 过滤健康实例
            return instances.stream()
                .filter(instance -> instance.getStatus() == 1)
                .collect(Collectors.toList());
        }
        
        // 负载均衡
        public ServiceInstance chooseInstance(String serviceName, 
                                             LoadBalanceStrategy strategy) {
            List<ServiceInstance> instances = discover(serviceName);
            
            if (instances == null || instances.isEmpty()) {
                throw new RuntimeException("没有可用的服务实例: " + serviceName);
            }
            
            switch (strategy) {
                case RANDOM:
                    return randomChoose(instances);
                case ROUND_ROBIN:
                    return roundRobinChoose(serviceName, instances);
                case WEIGHTED:
                    return weightedChoose(instances);
                case LEAST_CONNECTION:
                    return leastConnectionChoose(instances);
                default:
                    return randomChoose(instances);
            }
        }
        
        // 随机选择
        private ServiceInstance randomChoose(List<ServiceInstance> instances) {
            int index = ThreadLocalRandom.current().nextInt(instances.size());
            return instances.get(index);
        }
        
        // 轮询选择
        private final Map<String, AtomicInteger> roundRobinIndex = 
            new ConcurrentHashMap<>();
        
        private ServiceInstance roundRobinChoose(String serviceName, 
                                                List<ServiceInstance> instances) {
            AtomicInteger index = roundRobinIndex.computeIfAbsent(
                serviceName, k -> new AtomicInteger(0));
            
            int current = index.getAndIncrement() % instances.size();
            return instances.get(current);
        }
        
        // 订阅服务变更
        public void subscribe(String serviceName, ServiceChangeListener listener) {
            // 监听服务变更事件
            eventListenerRegistry.register(serviceName, listener);
            
            // 获取初始服务列表
            List<ServiceInstance> instances = discover(serviceName);
            listener.onChange(instances);
        }
    }
    
    // 3. 客户端负载均衡
    @Configuration
    public class ClientLoadBalancer {
        
        @Bean
        @LoadBalanced  // 启用Ribbon负载均衡
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
        
        // 自定义负载均衡策略
        @Bean
        public IRule loadBalanceRule() {
            // 可用策略:
            // RoundRobinRule:轮询
            // RandomRule:随机
            // WeightedResponseTimeRule:加权响应时间
            // BestAvailableRule:跳过断路器跳闸的服务
            return new RoundRobinRule();
        }
        
        // 服务调用示例
        @Service
        public class ServiceInvoker {
            
            @Autowired
            private RestTemplate restTemplate;
            
            @HystrixCommand(fallbackMethod = "fallback")
            public String callService(String serviceName, String path) {
                // 自动负载均衡
                return restTemplate.getForObject(
                    "http://" + serviceName + path, String.class);
            }
            
            public String fallback(String serviceName, String path) {
                return "服务降级响应";
            }
        }
    }
    
    // 4. 服务网格(Service Mesh)
    @Configuration
    public class ServiceMeshConfig {
        
        // 使用Istio进行服务治理
        @Bean
        public IstioClient istioClient() {
            // 配置Istio客户端
            return new IstioClient();
        }
        
        // 服务间调用拦截
        @Component
        public class ServiceMeshInterceptor implements ClientHttpRequestInterceptor {
            
            @Override
            public ClientHttpResponse intercept(HttpRequest request, 
                                               byte[] body, 
                                               ClientHttpRequestExecution execution) 
                throws IOException {
                
                // 注入追踪头
                request.getHeaders().add("x-request-id", 
                    TraceContext.getCurrentTraceId());
                request.getHeaders().add("x-b3-traceid", 
                    TraceContext.getCurrentTraceId());
                request.getHeaders().add("x-b3-spanid", 
                    TraceContext.getCurrentSpanId());
                
                // 熔断器检查
                if (circuitBreaker.isOpen(request.getURI().getHost())) {
                    throw new CircuitBreakerOpenException();
                }
                
                // 限流检查
                if (!rateLimiter.tryAcquire(request.getURI().getHost())) {
                    throw new RateLimitExceededException();
                }
                
                // 执行请求
                ClientHttpResponse response = execution.execute(request, body);
                
                // 记录指标
                metricsCollector.recordRequest(
                    request.getURI().getHost(),
                    response.getStatusCode().value(),
                    System.currentTimeMillis() - startTime);
                
                return response;
            }
        }
        
        // 服务熔断
        @Component
        public class ServiceCircuitBreaker {
            
            private final Map<String, CircuitBreaker> breakers = 
                new ConcurrentHashMap<>();
            
            public boolean isOpen(String serviceName) {
                CircuitBreaker breaker = breakers.computeIfAbsent(
                    serviceName, k -> new CircuitBreaker());
                return breaker.isOpen();
            }
            
            public void recordSuccess(String serviceName) {
                CircuitBreaker breaker = breakers.get(serviceName);
                if (breaker != null) {
                    breaker.recordSuccess();
                }
            }
            
            public void recordFailure(String serviceName) {
                CircuitBreaker breaker = breakers.get(serviceName);
                if (breaker != null) {
                    breaker.recordFailure();
                }
            }
        }
    }
    
    // 5. 服务上下线完整流程
    @Service
    public class ServiceLifecycleManager {
        
        // 服务上线流程
        public void startupService(String serviceName, String instanceId) {
            // 1. 健康检查通过
            if (!healthCheck(serviceName, instanceId)) {
                throw new RuntimeException("健康检查失败");
            }
            
            // 2. 注册到服务中心
            registerToRegistry(serviceName, instanceId);
            
            // 3. 预热(如缓存预热)
            warmUp(serviceName, instanceId);
            
            // 4. 流量接入(逐步增加权重)
            gradualTrafficShift(serviceName, instanceId);
            
            // 5. 标记为就绪
            markAsReady(serviceName, instanceId);
            
            // 6. 通知监控系统
            notifyMonitor(serviceName, instanceId, "UP");
        }
        
        // 服务下线流程
        public void shutdownService(String serviceName, String instanceId) {
            // 1. 从负载均衡器移除
            removeFromLoadBalancer(serviceName, instanceId);
            
            // 2. 等待处理中的请求完成
            waitForInFlightRequests(serviceName, instanceId);
            
            // 3. 停止接收新请求
            stopAcceptingNewRequests(serviceName, instanceId);
            
            // 4. 执行清理操作
            cleanup(serviceName, instanceId);
            
            // 5. 从注册中心注销
            deregisterFromRegistry(serviceName, instanceId);
            
            // 6. 关闭进程
            shutdownProcess(serviceName, instanceId);
            
            // 7. 通知监控系统
            notifyMonitor(serviceName, instanceId, "DOWN");
        }
        
        // 优雅停机
        @PreDestroy
        public void gracefulShutdown() {
            // 接收关闭信号
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                // 1. 标记为关闭中
                status = "SHUTTING_DOWN";
                
                // 2. 从注册中心注销
                deregisterFromRegistry(serviceName, instanceId);
                
                // 3. 等待一段时间让流量迁移
                try {
                    Thread.sleep(30000);  // 等待30秒
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                // 4. 关闭资源
                closeResources();
            }));
        }
    }
}
49. 分布式追踪系统设计
java 复制代码
// 分布式追踪系统核心组件
@Component
public class DistributedTracingSystem {
    
    // 1. 追踪数据模型
    @Data
    public class Trace {
        private String traceId;           // 追踪ID
        private String parentSpanId;      // 父Span ID
        private String spanId;            // 当前Span ID
        private String serviceName;       // 服务名
        private String operationName;     // 操作名
        private Long startTime;           // 开始时间
        private Long duration;            // 持续时间
        private Map<String, String> tags; // 标签
        private List<Log> logs;           // 日志
        private List<Reference> references; // 引用关系
        private boolean error;            // 是否错误
    }
    
    @Data
    public class Span {
        private String spanId;
        private String traceId;
        private String parentSpanId;
        private String operationName;
        private Long startTime;
        private Long duration;
        private Map<String, String> tags;
        private List<Log> logs;
    }
    
    // 2. 追踪上下文传播
    @Component
    public class TraceContext {
        
        private static final ThreadLocal<Trace> currentTrace = 
            new ThreadLocal<>();
        
        // 创建新追踪
        public Trace createNewTrace(String serviceName, String operationName) {
            Trace trace = new Trace();
            trace.setTraceId(generateTraceId());
            trace.setSpanId(generateSpanId());
            trace.setServiceName(serviceName);
            trace.setOperationName(operationName);
            trace.setStartTime(System.currentTimeMillis());
            trace.setTags(new HashMap<>());
            trace.setLogs(new ArrayList<>());
            
            currentTrace.set(trace);
            return trace;
        }
        
        // 创建子Span
        public Span createChildSpan(String operationName) {
            Trace parent = currentTrace.get();
            if (parent == null) {
                return null;
            }
            
            Span span = new Span();
            span.setTraceId(parent.getTraceId());
            span.setParentSpanId(parent.getSpanId());
            span.setSpanId(generateSpanId());
            span.setOperationName(operationName);
            span.setStartTime(System.currentTimeMillis());
            
            return span;
        }
        
        // 注入追踪头(HTTP)
        public void injectHttpHeaders(HttpHeaders headers) {
            Trace trace = currentTrace.get();
            if (trace != null) {
                headers.add("X-Trace-Id", trace.getTraceId());
                headers.add("X-Span-Id", trace.getSpanId());
                headers.add("X-Parent-Span-Id", trace.getParentSpanId());
            }
        }
        
        // 提取追踪头(HTTP)
        public Trace extractFromHeaders(HttpHeaders headers) {
            String traceId = headers.getFirst("X-Trace-Id");
            String spanId = headers.getFirst("X-Span-Id");
            String parentSpanId = headers.getFirst("X-Parent-Span-Id");
            
            if (traceId == null) {
                return null;
            }
            
            Trace trace = new Trace();
            trace.setTraceId(traceId);
            trace.setSpanId(spanId != null ? spanId : generateSpanId());
            trace.setParentSpanId(parentSpanId);
            
            currentTrace.set(trace);
            return trace;
        }
        
        // 注入消息头(MQ)
        public void injectMessageHeaders(MessageProperties properties) {
            Trace trace = currentTrace.get();
            if (trace != null) {
                properties.setHeader("traceId", trace.getTraceId());
                properties.setHeader("spanId", trace.getSpanId());
                properties.setHeader("parentSpanId", trace.getParentSpanId());
            }
        }
    }
    
    // 3. 追踪数据收集
    @Component
    public class TraceCollector {
        
        // 内存缓冲区
        private final BlockingQueue<Trace> traceQueue = 
            new LinkedBlockingQueue<>(10000);
        
        private final ScheduledExecutorService scheduler = 
            Executors.newScheduledThreadPool(2);
        
        @PostConstruct
        public void init() {
            // 启动批量发送线程
            scheduler.scheduleAtFixedRate(this::batchSendTraces, 
                1, 1, TimeUnit.SECONDS);
            
            // 启动队列监控线程
            scheduler.scheduleAtFixedRate(this::monitorQueue, 
                5, 5, TimeUnit.SECONDS);
        }
        
        // 收集追踪数据
        public void collect(Trace trace) {
            if (trace == null) {
                return;
            }
            
            // 计算持续时间
            trace.setDuration(System.currentTimeMillis() - trace.getStartTime());
            
            // 加入队列
            if (!traceQueue.offer(trace)) {
                // 队列满,记录丢弃
                metricsCollector.recordDroppedTrace();
            }
        }
        
        // 批量发送追踪数据
        private void batchSendTraces() {
            List<Trace> batch = new ArrayList<>(1000);
            traceQueue.drainTo(batch, 1000);
            
            if (!batch.isEmpty()) {
                try {
                    sendToCollector(batch);
                    metricsCollector.recordSentTraces(batch.size());
                } catch (Exception e) {
                    // 发送失败,重新加入队列
                    traceQueue.addAll(batch);
                    metricsCollector.recordSendError();
                }
            }
        }
        
        // 发送到收集器
        private void sendToCollector(List<Trace> traces) {
            // 发送到Jaeger、Zipkin等
            // 或存储到Kafka
            kafkaTemplate.send("traces", traces);
        }
        
        // 队列监控
        private void monitorQueue() {
            int size = traceQueue.size();
            metricsCollector.recordQueueSize(size);
            
            if (size > 8000) {
                // 队列接近满,告警
                alertService.sendAlert("Trace队列接近满: " + size);
            }
        }
    }
    
    // 4. 追踪拦截器
    @Component
    public class TracingInterceptor {
        
        @Autowired
        private TraceContext traceContext;
        
        @Autowired
        private TraceCollector traceCollector;
        
        // HTTP请求拦截
        @Component
        public class TracingClientInterceptor implements ClientHttpRequestInterceptor {
            
            @Override
            public ClientHttpResponse intercept(HttpRequest request, 
                                               byte[] body, 
                                               ClientHttpRequestExecution execution) 
                throws IOException {
                
                // 创建或获取当前追踪
                Trace trace = traceContext.currentTrace();
                if (trace == null) {
                    trace = traceContext.createNewTrace(
                        getServiceName(), 
                        request.getURI().getPath());
                }
                
                // 创建子Span
                Span span = traceContext.createChildSpan(
                    "HTTP-REQUEST:" + request.getMethod() + ":" + request.getURI());
                
                // 注入追踪头
                traceContext.injectHttpHeaders(request.getHeaders());
                
                // 记录请求开始
                span.getLogs().add(new Log("request.start", 
                    System.currentTimeMillis()));
                
                // 执行请求
                ClientHttpResponse response = null;
                try {
                    response = execution.execute(request, body);
                    
                    // 记录响应
                    span.getTags().put("http.status", 
                        String.valueOf(response.getStatusCode().value()));
                    span.getTags().put("http.url", request.getURI().toString());
                    span.getTags().put("http.method", request.getMethod().name());
                    
                    return response;
                    
                } catch (Exception e) {
                    // 记录异常
                    span.setError(true);
                    span.getTags().put("error", e.getMessage());
                    throw e;
                    
                } finally {
                    // 记录请求结束
                    span.getLogs().add(new Log("request.end", 
                        System.currentTimeMillis()));
                    
                    // 计算持续时间
                    span.setDuration(System.currentTimeMillis() - span.getStartTime());
                    
                    // 收集Span
                    traceCollector.collect(convertToTrace(span));
                }
            }
        }
        
        // Spring MVC拦截
        @Component
        public class TracingHandlerInterceptor implements HandlerInterceptor {
            
            @Override
            public boolean preHandle(HttpServletRequest request, 
                                    HttpServletResponse response, 
                                    Object handler) throws Exception {
                
                // 从请求头提取追踪信息
                Trace trace = traceContext.extractFromHeaders(
                    new ServletServerHttpRequest(request).getHeaders());
                
                if (trace == null) {
                    // 创建新追踪
                    trace = traceContext.createNewTrace(
                        getServiceName(), 
                        request.getRequestURI());
                }
                
                // 设置请求属性
                request.setAttribute("trace", trace);
                
                return true;
            }
            
            @Override
            public void afterCompletion(HttpServletRequest request, 
                                       HttpServletResponse response, 
                                       Object handler, Exception ex) {
                
                Trace trace = (Trace) request.getAttribute("trace");
                if (trace != null) {
                    // 记录响应状态
                    trace.getTags().put("http.status", 
                        String.valueOf(response.getStatus()));
                    trace.getTags().put("http.path", request.getRequestURI());
                    trace.getTags().put("http.method", request.getMethod());
                    
                    if (ex != null) {
                        trace.setError(true);
                        trace.getTags().put("error", ex.getMessage());
                    }
                    
                    // 收集追踪数据
                    traceCollector.collect(trace);
                    
                    // 清理ThreadLocal
                    traceContext.clear();
                }
            }
        }
        
        // 数据库操作追踪
        @Aspect
        @Component
        public class DatabaseTracingAspect {
            
            @Around("execution(* javax.sql.DataSource.getConnection(..))")
            public Object traceConnection(ProceedingJoinPoint joinPoint) 
                throws Throwable {
                
                Trace trace = traceContext.currentTrace();
                if (trace == null) {
                    return joinPoint.proceed();
                }
                
                Span span = traceContext.createChildSpan("DB:GET_CONNECTION");
                span.getTags().put("db.operation", "get_connection");
                
                try {
                    Object result = joinPoint.proceed();
                    
                    // 如果是Connection,创建代理
                    if (result instanceof Connection) {
                        return createTracedConnection((Connection) result, trace);
                    }
                    
                    return result;
                    
                } finally {
                    span.setDuration(System.currentTimeMillis() - span.getStartTime());
                    traceCollector.collect(convertToTrace(span));
                }
            }
            
            private Connection createTracedConnection(Connection connection, 
                                                     Trace trace) {
                return (Connection) Proxy.newProxyInstance(
                    connection.getClass().getClassLoader(),
                    new Class[]{Connection.class},
                    (proxy, method, args) -> {
                        
                        if (method.getName().equals("prepareStatement") || 
                            method.getName().equals("createStatement") ||
                            method.getName().equals("prepareCall")) {
                            
                            Span span = traceContext.createChildSpan("DB:" + method.getName());
                            span.getTags().put("db.operation", method.getName());
                            
                            long startTime = System.currentTimeMillis();
                            try {
                                Object result = method.invoke(connection, args);
                                
                                // 如果是Statement,创建代理
                                if (result instanceof Statement) {
                                    return createTracedStatement(
                                        (Statement) result, trace, span);
                                }
                                
                                return result;
                                
                            } finally {
                                span.setDuration(
                                    System.currentTimeMillis() - startTime);
                                traceCollector.collect(convertToTrace(span));
                            }
                        }
                        
                        return method.invoke(connection, args);
                    });
            }
            
            private Statement createTracedStatement(Statement statement, 
                                                   Trace trace, 
                                                   Span parentSpan) {
                return (Statement) Proxy.newProxyInstance(
                    statement.getClass().getClassLoader(),
                    new Class[]{Statement.class},
                    (proxy, method, args) -> {
                        
                        if (method.getName().equals("execute") || 
                            method.getName().equals("executeQuery") ||
                            method.getName().equals("executeUpdate")) {
                            
                            Span span = traceContext.createChildSpan("DB:EXECUTE");
                            span.setParentSpanId(parentSpan.getSpanId());
                            
                            // 记录SQL
                            String sql = args.length > 0 ? (String) args[0] : "";
                            span.getTags().put("db.sql", truncateSql(sql));
                            
                            long startTime = System.currentTimeMillis();
                            try {
                                Object result = method.invoke(statement, args);
                                
                                span.getTags().put("db.result.type", 
                                    result.getClass().getSimpleName());
                                
                                return result;
                                
                            } catch (Exception e) {
                                span.setError(true);
                                span.getTags().put("db.error", e.getMessage());
                                throw e;
                                
                            } finally {
                                span.setDuration(
                                    System.currentTimeMillis() - startTime);
                                traceCollector.collect(convertToTrace(span));
                            }
                        }
                        
                        return method.invoke(statement, args);
                    });
            }
        }
    }
    
    // 5. 追踪分析与可视化
    @Service
    public class TraceAnalysisService {
        
        // 存储设计
        @Entity
        @Table(name = "trace_spans",
               indexes = {
                   @Index(name = "idx_trace_id", columnList = "traceId"),
                   @Index(name = "idx_service_operation", columnList = "serviceName,operationName"),
                   @Index(name = "idx_start_time", columnList = "startTime")
               })
        @Data
        public class TraceSpanEntity {
            @Id
            private String id;
            
            @Column(name = "trace_id", length = 100)
            private String traceId;
            
            @Column(name = "span_id", length = 100)
            private String spanId;
            
            @Column(name = "parent_span_id", length = 100)
            private String parentSpanId;
            
            @Column(name = "service_name", length = 100)
            private String serviceName;
            
            @Column(name = "operation_name", length = 500)
            private String operationName;
            
            @Column(name = "start_time")
            private Long startTime;
            
            @Column(name = "duration")
            private Long duration;
            
            @Column(name = "tags", columnDefinition = "TEXT")
            private String tags;  // JSON格式
            
            @Column(name = "error")
            private Boolean error;
            
            @Column(name = "create_time")
            private Date createTime;
        }
        
        // 查询追踪链
        public List<TraceSpan> getTraceSpans(String traceId) {
            return traceSpanRepository.findByTraceIdOrderByStartTime(traceId);
        }
        
        // 服务依赖分析
        public Map<String, List<ServiceDependency>> analyzeServiceDependencies(
                Date startTime, Date endTime) {
            
            // 分析服务调用关系
            List<Object[]> results = traceSpanRepository
                .findServiceDependencies(startTime, endTime);
            
            Map<String, List<ServiceDependency>> dependencies = new HashMap<>();
            
            for (Object[] result : results) {
                String caller = (String) result[0];
                String callee = (String) result[1];
                Long count = (Long) result[2];
                Double avgDuration = (Double) result[3];
                Double errorRate = (Double) result[4];
                
                ServiceDependency dep = new ServiceDependency();
                dep.setCallee(callee);
                dep.setCallCount(count);
                dep.setAvgDuration(avgDuration);
                dep.setErrorRate(errorRate);
                
                dependencies.computeIfAbsent(caller, k -> new ArrayList<>())
                    .add(dep);
            }
            
            return dependencies;
        }
        
        // 性能分析
        public PerformanceReport analyzePerformance(String serviceName, 
                                                   Date startTime, 
                                                   Date endTime) {
            
            PerformanceReport report = new PerformanceReport();
            
            // P99延迟
            Long p99Latency = traceSpanRepository
                .getPercentileLatency(serviceName, startTime, endTime, 99);
            report.setP99Latency(p99Latency);
            
            // 平均延迟
            Double avgLatency = traceSpanRepository
                .getAvgLatency(serviceName, startTime, endTime);
            report.setAvgLatency(avgLatency);
            
            // 错误率
            Double errorRate = traceSpanRepository
                .getErrorRate(serviceName, startTime, endTime);
            report.setErrorRate(errorRate);
            
            // 吞吐量
            Long throughput = traceSpanRepository
                .getThroughput(serviceName, startTime, endTime);
            report.setThroughput(throughput);
            
            // 慢查询分析
            List<TraceSpan> slowSpans = traceSpanRepository
                .findSlowSpans(serviceName, startTime, endTime, 1000);  // >1秒
            
            report.setSlowSpans(slowSpans);
            
            return report;
        }
        
        // 根因分析
        public RootCauseAnalysis analyzeRootCause(String traceId) {
            List<TraceSpan> spans = getTraceSpans(traceId);
            
            RootCauseAnalysis analysis = new RootCauseAnalysis();
            analysis.setTraceId(traceId);
            
            // 查找错误Span
            List<TraceSpan> errorSpans = spans.stream()
                .filter(TraceSpan::isError)
                .collect(Collectors.toList());
            
            analysis.setErrorSpans(errorSpans);
            
            // 查找最慢的Span
            TraceSpan slowestSpan = spans.stream()
                .max(Comparator.comparingLong(TraceSpan::getDuration))
                .orElse(null);
            
            analysis.setSlowestSpan(slowestSpan);
            
            // 分析关键路径
            List<TraceSpan> criticalPath = findCriticalPath(spans);
            analysis.setCriticalPath(criticalPath);
            
            return analysis;
        }
        
        // 查找关键路径
        private List<TraceSpan> findCriticalPath(List<TraceSpan> spans) {
            // 构建Span树
            Map<String, TraceSpan> spanMap = spans.stream()
                .collect(Collectors.toMap(TraceSpan::getSpanId, s -> s));
            
            Map<String, List<TraceSpan>> childrenMap = new HashMap<>();
            
            for (TraceSpan span : spans) {
                if (span.getParentSpanId() != null) {
                    childrenMap.computeIfAbsent(span.getParentSpanId(), 
                        k -> new ArrayList<>()).add(span);
                }
            }
            
            // 计算每个Span的关键路径长度
            Map<String, Long> criticalLength = new HashMap<>();
            
            for (TraceSpan span : spans) {
                calculateCriticalLength(span, childrenMap, criticalLength);
            }
            
            // 从根节点开始构建关键路径
            TraceSpan root = spans.stream()
                .filter(s -> s.getParentSpanId() == null)
                .findFirst()
                .orElse(null);
            
            List<TraceSpan> criticalPath = new ArrayList<>();
            TraceSpan current = root;
            
            while (current != null) {
                criticalPath.add(current);
                
                List<TraceSpan> children = childrenMap.get(current.getSpanId());
                if (children == null || children.isEmpty()) {
                    break;
                }
                
                // 选择关键路径上的子节点
                current = children.stream()
                    .max(Comparator.comparing(
                        c -> criticalLength.getOrDefault(c.getSpanId(), 0L) + c.getDuration()))
                    .orElse(null);
            }
            
            return criticalPath;
        }
    }
}
50. 分布式事务一致性方案
java 复制代码
// 分布式事务解决方案对比
@Component
public class DistributedTransactionSolutions {
    
    // 1. 两阶段提交(2PC)
    @Service
    public class TwoPhaseCommit {
        
        // 协调者
        @Component
        public class Coordinator {
            
            private final List<Participant> participants = new ArrayList<>();
            
            // 第一阶段:准备阶段
            public boolean prepare(Transaction transaction) {
                List<Future<Boolean>> futures = new ArrayList<>();
                
                // 向所有参与者发送准备请求
                for (Participant participant : participants) {
                    futures.add(executor.submit(() -> 
                        participant.prepare(transaction)));
                }
                
                // 收集所有参与者的响应
                boolean allPrepared = true;
                for (Future<Boolean> future : futures) {
                    try {
                        if (!future.get()) {
                            allPrepared = false;
                            break;
                        }
                    } catch (Exception e) {
                        allPrepared = false;
                        break;
                    }
                }
                
                return allPrepared;
            }
            
            // 第二阶段:提交/回滚
            public void commitOrRollback(Transaction transaction, boolean prepared) {
                if (prepared) {
                    // 所有参与者都准备成功,提交
                    for (Participant participant : participants) {
                        executor.submit(() -> participant.commit(transaction));
                    }
                } else {
                    // 有参与者准备失败,回滚
                    for (Participant participant : participants) {
                        executor.submit(() -> participant.rollback(transaction));
                    }
                }
            }
            
            // 执行分布式事务
            public boolean executeDistributedTransaction(Transaction transaction) {
                // 第一阶段:准备
                boolean prepared = prepare(transaction);
                
                // 第二阶段:提交或回滚
                commitOrRollback(transaction, prepared);
                
                return prepared;
            }
        }
        
        // 参与者
        @Component
        public class Participant {
            
            // 准备阶段
            public boolean prepare(Transaction transaction) {
                // 1. 写入redo log
                writeRedoLog(transaction);
                
                // 2. 锁定资源
                lockResources(transaction);
                
                // 3. 返回准备结果
                return canCommit(transaction);
            }
            
            // 提交
            public void commit(Transaction transaction) {
                try {
                    // 1. 执行提交
                    executeCommit(transaction);
                    
                    // 2. 释放锁
                    releaseLocks(transaction);
                    
                    // 3. 清理日志
                    cleanLogs(transaction);
                    
                } catch (Exception e) {
                    // 提交失败,需要人工干预
                    log.error("提交失败: {}", transaction.getId(), e);
                }
            }
            
            // 回滚
            public void rollback(Transaction transaction) {
                try {
                    // 1. 执行回滚
                    executeRollback(transaction);
                    
                    // 2. 释放锁
                    releaseLocks(transaction);
                    
                    // 3. 清理日志
                    cleanLogs(transaction);
                    
                } catch (Exception e) {
                    log.error("回滚失败: {}", transaction.getId(), e);
                }
            }
        }
    }
    
    // 2. TCC(Try-Confirm-Cancel)
    @Service
    public class TCCService {
        
        // 订单服务TCC实现
        @Component
        public class OrderTCCService {
            
            // Try阶段:预创建订单
            @Transactional
            public boolean tryCreateOrder(OrderDTO orderDTO) {
                // 1. 检查参数
                validateOrder(orderDTO);
                
                // 2. 检查库存(预留)
                if (!inventoryService.tryReserve(orderDTO.getProductId(), 
                        orderDTO.getQuantity())) {
                    throw new RuntimeException("库存不足");
                }
                
                // 3. 检查用户余额(冻结)
                if (!accountService.tryFreeze(orderDTO.getUserId(), 
                        orderDTO.getAmount())) {
                    // 释放预留的库存
                    inventoryService.cancelReserve(orderDTO.getProductId(), 
                        orderDTO.getQuantity());
                    throw new RuntimeException("余额不足");
                }
                
                // 4. 创建订单(待确认状态)
                Order order = new Order();
                order.setStatus(OrderStatus.TRY_SUCCESS);
                order.setAmount(orderDTO.getAmount());
                order.setUserId(orderDTO.getUserId());
                orderRepository.save(order);
                
                return true;
            }
            
            // Confirm阶段:确认订单
            @Transactional
            public boolean confirmCreateOrder(Long orderId) {
                Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在"));
                
                // 1. 确认订单状态
                order.setStatus(OrderStatus.CONFIRMED);
                orderRepository.save(order);
                
                // 2. 扣减库存
                inventoryService.confirmReserve(order.getProductId(), 
                    order.getQuantity());
                
                // 3. 扣减余额
                accountService.confirmFreeze(order.getUserId(), order.getAmount());
                
                // 4. 发送订单创建事件
                eventPublisher.publishEvent(new OrderConfirmedEvent(order));
                
                return true;
            }
            
            // Cancel阶段:取消订单
            @Transactional
            public boolean cancelCreateOrder(Long orderId) {
                Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在"));
                
                // 1. 取消订单
                order.setStatus(OrderStatus.CANCELLED);
                orderRepository.save(order);
                
                // 2. 释放库存
                inventoryService.cancelReserve(order.getProductId(), 
                    order.getQuantity());
                
                // 3. 解冻余额
                accountService.cancelFreeze(order.getUserId(), order.getAmount());
                
                return true;
            }
        }
        
        // TCC协调器
        @Component
        public class TCCCoordinator {
            
            // 执行TCC事务
            @Transactional
            public boolean executeTCCTransaction(TCCTransaction transaction) {
                List<TCCAction> actions = transaction.getActions();
                
                try {
                    // Try阶段
                    for (TCCAction action : actions) {
                        if (!action.try()) {
                            throw new RuntimeException("Try阶段失败: " + action.getName());
                        }
                    }
                    
                    // Confirm阶段
                    for (TCCAction action : actions) {
                        action.confirm();
                    }
                    
                    return true;
                    
                } catch (Exception e) {
                    // Cancel阶段
                    for (TCCAction action : actions) {
                        try {
                            action.cancel();
                        } catch (Exception ex) {
                            // 记录日志,继续取消其他操作
                            log.error("Cancel阶段失败: {}", action.getName(), ex);
                        }
                    }
                    
                    throw e;
                }
            }
            
            // TCC恢复(处理悬挂事务)
            @Scheduled(fixedDelay = 60000)
            public void recoverTCCTransactions() {
                // 查找超时的Try操作
                List<TCCTransaction> hangingTransactions = 
                    tccTransactionRepository.findHangingTransactions();
                
                for (TCCTransaction transaction : hangingTransactions) {
                    try {
                        // 尝试Confirm或Cancel
                        if (canConfirm(transaction)) {
                            confirmTransaction(transaction);
                        } else {
                            cancelTransaction(transaction);
                        }
                    } catch (Exception e) {
                        log.error("恢复TCC事务失败: {}", transaction.getId(), e);
                    }
                }
            }
        }
    }
    
    // 3. 消息队列最终一致性
    @Service
    public class MessageQueueConsistency {
        
        // 本地消息表方案
        @Component
        public class LocalMessageTable {
            
            @Entity
            @Table(name = "local_messages")
            @Data
            public class LocalMessage {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private Long id;
                
                @Column(name = "biz_id", length = 100)
                private String bizId;  // 业务ID
                
                @Column(name = "biz_type", length = 50)
                private String bizType;  // 业务类型
                
                @Column(name = "message_content", columnDefinition = "TEXT")
                private String messageContent;  // 消息内容
                
                @Column(name = "status")
                private Integer status;  // 0:待发送, 1:已发送, 2:已完成
                
                @Column(name = "retry_count")
                private Integer retryCount = 0;
                
                @Column(name = "next_retry_time")
                private Date nextRetryTime;
                
                @Column(name = "create_time")
                private Date createTime;
                
                @Column(name = "update_time")
                private Date updateTime;
            }
            
            // 下单业务:保证订单创建和库存扣减的最终一致
            @Transactional
            public void createOrder(OrderDTO orderDTO) {
                // 1. 创建订单(本地事务)
                Order order = orderService.createOrder(orderDTO);
                
                // 2. 写入本地消息表(同一个事务)
                LocalMessage message = new LocalMessage();
                message.setBizId(order.getId().toString());
                message.setBizType("ORDER_CREATED");
                message.setMessageContent(objectMapper.writeValueAsString(order));
                message.setStatus(0);
                message.setCreateTime(new Date());
                
                localMessageRepository.save(message);
                
                // 事务提交后,消息会被异步发送
            }
            
            // 消息发送服务
            @Scheduled(fixedDelay = 5000)
            public void sendPendingMessages() {
                // 查找待发送的消息
                List<LocalMessage> pendingMessages = 
                    localMessageRepository.findPendingMessages(100);
                
                for (LocalMessage message : pendingMessages) {
                    try {
                        // 发送消息到MQ
                        boolean sent = messageQueue.send(
                            message.getBizType(), 
                            message.getMessageContent());
                        
                        if (sent) {
                            // 更新状态为已发送
                            message.setStatus(1);
                            message.setUpdateTime(new Date());
                            localMessageRepository.save(message);
                        } else {
                            // 发送失败,增加重试次数
                            handleSendFailure(message);
                        }
                    } catch (Exception e) {
                        handleSendFailure(message);
                    }
                }
            }
            
            // 消息消费端
            @RabbitListener(queues = "order.created")
            public void handleOrderCreated(String messageJson) {
                try {
                    OrderMessage message = objectMapper.readValue(
                        messageJson, OrderMessage.class);
                    
                    // 扣减库存(幂等操作)
                    inventoryService.deductStock(
                        message.getProductId(), 
                        message.getQuantity());
                    
                    // 发送确认消息
                    sendAckMessage(message.getBizId());
                    
                } catch (Exception e) {
                    // 消费失败,进入死信队列重试
                    log.error("消费订单消息失败", e);
                    throw new AmqpRejectAndDontRequeueException(e.getMessage());
                }
            }
            
            // 消息确认
            @Transactional
            public void confirmMessageProcessed(String bizId) {
                LocalMessage message = localMessageRepository
                    .findByBizIdAndBizType(bizId, "ORDER_CREATED");
                
                if (message != null) {
                    message.setStatus(2);  // 已完成
                    message.setUpdateTime(new Date());
                    localMessageRepository.save(message);
                }
            }
        }
        
        // RocketMQ事务消息方案
        @Component
        public class RocketMQTransaction {
            
            // 事务消息生产者
            public class OrderTransactionProducer {
                
                // 发送事务消息
                public void sendTransactionMessage(OrderDTO orderDTO) {
                    // 创建消息
                    Message message = new Message("order_topic", "create", 
                        objectMapper.writeValueAsBytes(orderDTO));
                    
                    // 发送事务消息
                    TransactionSendResult result = transactionMQProducer
                        .sendMessageInTransaction(message, orderDTO);
                    
                    if (result.getLocalTransactionState() == 
                        LocalTransactionState.COMMIT_MESSAGE) {
                        log.info("事务消息发送成功");
                    } else {
                        log.error("事务消息发送失败");
                    }
                }
            }
            
            // 事务消息监听器
            public class OrderTransactionListener implements 
                TransactionListener {
                
                // 执行本地事务
                @Override
                public LocalTransactionState executeLocalTransaction(
                    Message msg, Object arg) {
                    
                    OrderDTO orderDTO = (OrderDTO) arg;
                    
                    try {
                        // 执行本地事务:创建订单
                        orderService.createOrder(orderDTO);
                        
                        // 返回COMMIT,让消息对消费者可见
                        return LocalTransactionState.COMMIT_MESSAGE;
                        
                    } catch (Exception e) {
                        // 返回ROLLBACK,消息会被丢弃
                        return LocalTransactionState.ROLLBACK_MESSAGE;
                    }
                }
                
                // 本地事务状态回查
                @Override
                public LocalTransactionState checkLocalTransaction(
                    MessageExt msg) {
                    
                    // 根据消息内容检查本地事务状态
                    String orderId = extractOrderId(msg);
                    
                    Order order = orderRepository.findById(orderId);
                    if (order != null && order.getStatus() == OrderStatus.CREATED) {
                        return LocalTransactionState.COMMIT_MESSAGE;
                    } else {
                        return LocalTransactionState.ROLLBACK_MESSAGE;
                    }
                }
            }
            
            // 消息消费者
            @RocketMQMessageListener(
                topic = "order_topic",
                consumerGroup = "order_consumer_group")
            public class OrderConsumer implements RocketMQListener<MessageExt> {
                
                @Override
                public void onMessage(MessageExt message) {
                    try {
                        OrderDTO orderDTO = objectMapper.readValue(
                            message.getBody(), OrderDTO.class);
                        
                        // 扣减库存(幂等操作)
                        inventoryService.deductStock(
                            orderDTO.getProductId(), 
                            orderDTO.getQuantity());
                        
                        log.info("订单消息消费成功: {}", orderDTO);
                        
                    } catch (Exception e) {
                        // 消费失败,重试16次后进入死信队列
                        throw new RuntimeException("消费失败", e);
                    }
                }
            }
        }
    }
    
    // 4. Saga模式
    @Service
    public class SagaPattern {
        
        // Saga协调器
        @Component
        public class SagaCoordinator {
            
            // 执行Saga事务
            public void executeSaga(Saga saga) {
                SagaContext context = new SagaContext();
                
                try {
                    // 顺序执行正向操作
                    for (SagaStep step : saga.getSteps()) {
                        boolean success = step.execute(context);
                        if (!success) {
                            // 执行失败,开始补偿
                            compensate(saga, step, context);
                            break;
                        }
                    }
                    
                } catch (Exception e) {
                    // 异常时补偿
                    compensate(saga, currentStep, context);
                }
            }
            
            // 补偿操作
            private void compensate(Saga saga, SagaStep failedStep, 
                                   SagaContext context) {
                // 逆向补偿已完成的步骤
                List<SagaStep> completedSteps = getCompletedSteps(saga, failedStep);
                
                for (int i = completedSteps.size() - 1; i >= 0; i--) {
                    SagaStep step = completedSteps.get(i);
                    try {
                        step.compensate(context);
                    } catch (Exception e) {
                        // 记录补偿失败,可能需要人工干预
                        log.error("Saga补偿失败: {}", step.getName(), e);
                    }
                }
            }
        }
        
        // 订单Saga示例
        @Component
        public class OrderSaga {
            
            private final List<SagaStep> steps = Arrays.asList(
                new ValidateOrderStep(),
                new ReserveInventoryStep(),
                new FreezeBalanceStep(),
                new CreateOrderStep(),
                new ConfirmInventoryStep(),
                new ConfirmBalanceStep()
            );
            
            // 验证订单步骤
            public class ValidateOrderStep implements SagaStep {
                @Override
                public boolean execute(SagaContext context) {
                    OrderDTO orderDTO = (OrderDTO) context.get("orderDTO");
                    return orderService.validate(orderDTO);
                }
                
                @Override
                public boolean compensate(SagaContext context) {
                    // 验证不需要补偿
                    return true;
                }
            }
            
            // 预留库存步骤
            public class ReserveInventoryStep implements SagaStep {
                @Override
                public boolean execute(SagaContext context) {
                    OrderDTO orderDTO = (OrderDTO) context.get("orderDTO");
                    return inventoryService.reserve(
                        orderDTO.getProductId(), 
                        orderDTO.getQuantity());
                }
                
                @Override
                public boolean compensate(SagaContext context) {
                    OrderDTO orderDTO = (OrderDTO) context.get("orderDTO");
                    return inventoryService.cancelReserve(
                        orderDTO.getProductId(), 
                        orderDTO.getQuantity());
                }
            }
            
            // 创建订单步骤
            public class CreateOrderStep implements SagaStep {
                @Override
                public boolean execute(SagaContext context) {
                    OrderDTO orderDTO = (OrderDTO) context.get("orderDTO");
                    Order order = orderService.createOrder(orderDTO);
                    context.put("order", order);
                    return true;
                }
                
                @Override
                public boolean compensate(SagaContext context) {
                    Order order = (Order) context.get("order");
                    return orderService.cancelOrder(order.getId());
                }
            }
        }
    }
    
    // 5. 方案对比与选择
    @Service
    public class SolutionComparison {
        
        public void compareSolutions() {
            // 两阶段提交(2PC)
            // 优点:强一致性
            // 缺点:同步阻塞、性能差、协调者单点
            // 适用:数据库层分布式事务
            
            // TCC
            // 优点:性能较好、可保证最终一致
            // 缺点:实现复杂、需要预留资源
            // 适用:金融、电商等对一致性要求高的场景
            
            // 消息队列最终一致
            // 优点:性能好、实现相对简单
            // 缺点:只能保证最终一致、有延迟
            // 适用:大多数互联网业务场景
            
            // Saga
            // 优点:长事务支持好、无锁
            // 缺点:补偿逻辑复杂、可能脏读
            // 适用:跨多个服务的业务流程
            
            // 选择建议:
            // 1. 强一致性要求:2PC或TCC
            // 2. 最终一致即可:消息队列
            // 3. 长业务流程:Saga
            // 4. 混合使用:核心业务用TCC,非核心用消息队列
        }
        
        // 混合方案示例:电商下单
        @Transactional
        public void placeOrder(OrderRequest request) {
            // 核心步骤:库存扣减和支付(强一致)
            boolean coreSuccess = tccService.executeTCC(() -> {
                // 1. 预留库存
                inventoryService.tryReserve(request.getProductId(), 
                    request.getQuantity());
                
                // 2. 冻结余额
                accountService.tryFreeze(request.getUserId(), 
                    request.getAmount());
                
                return true;
            }, () -> {
                // Confirm:实际扣减
                inventoryService.confirmReserve(request.getProductId(), 
                    request.getQuantity());
                accountService.confirmFreeze(request.getUserId(), 
                    request.getAmount());
                
            }, () -> {
                // Cancel:释放预留
                inventoryService.cancelReserve(request.getProductId(), 
                    request.getQuantity());
                accountService.cancelFreeze(request.getUserId(), 
                    request.getAmount());
            });
            
            if (!coreSuccess) {
                throw new RuntimeException("核心业务失败");
            }
            
            // 非核心步骤:发送通知、更新统计等(最终一致)
            localMessageTable.saveMessage("ORDER_PLACED", request);
            
            // 返回成功
            return createOrderResponse(request);
        }
    }
}

相关推荐
Survivor0017 小时前
高并发系统流量治理的底层算法
java·开发语言
凡人叶枫7 小时前
Effective C++ 条款35:考虑 virtual 函数以外的其他选择
java·c++·spring
garmin Chen7 小时前
从 Transformer 到 Agent:大模型技术全景解析
java·人工智能·python·深度学习·transformer
愚公移码7 小时前
蓝凌EKP18产品:流程引擎技术篇之流程核心概念模型
java·人工智能·流程引擎·蓝凌
Full Stack Developme7 小时前
Apache Tika 教程
java·开发语言·python·apache
鹅城剑仙7 小时前
Java线程池完全指南
java
李白的天不白7 小时前
SmartAdmin(基于 Spring Boot 框架)中配置跨域请求 VUE3 设置请求头
java·前端
橙子进阶之路8 小时前
Java线程(CompletableFuture)
java·开发语言
鹅城剑仙8 小时前
Java CompletableFuture 异步编程完全指南
java
2601_961875248 小时前
法考备考计划表|学习计划|资料已整理
java·开发语言·学习·eclipse·tomcat·c#·hibernate