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);
        }
    }
}

相关推荐
有什么东东10 小时前
java-枚举类、抽象类、接口、内部类
java·开发语言
bxlj_jcj10 小时前
使用 Arthas + Heapdump + MAT 三步定位 Java 内存泄漏
java·开发语言·python
大猫和小黄10 小时前
Java ID生成策略全面解析:从单机到分布式的最佳实践
java·开发语言·分布式·id
我命由我1234510 小时前
Android Jetpack Compose - Snackbar、Box
android·java·java-ee·kotlin·android studio·android jetpack·android-studio
一起养小猫10 小时前
LeetCode100天Day12-删除重复项与删除重复项II
java·数据结构·算法·leetcode
乘风归趣10 小时前
idea、maven问题
java·maven·intellij-idea
人道领域10 小时前
【零基础学java】(多线程)
java·开发语言
幽络源小助理10 小时前
springboot基于Java的教学辅助平台源码 – SpringBoot+Vue项目免费下载 | 幽络源
java·vue.js·spring boot
星辰烈龙10 小时前
黑马程序员JavaSE基础加强d6
java·开发语言