架构之水平扩展

水平扩展架构核心解析

架构之水平扩展

引言

在垂直扩展达到单节点物理极限后,水平扩展(Scale Out)成为了支撑业务持续增长的唯一选择。水平扩展架构的核心思想是:通过增加服务器数量,线性扩充系统性能,将原本集中在单节点的负载分散到多个节点上,从而实现系统处理能力的无限扩展。

然而,水平扩展并非简单的"加机器",它对系统架构设计有着严格的要求。如何在架构的各个层次进行可水平扩展的设计,如何处理好数据一致性、服务发现、负载均衡等分布式系统的核心问题,这些都是水平扩展架构必须面对的挑战。

水平扩展架构的核心理念

水平扩展 vs 垂直扩展

扩展策略选择
垂直扩展
水平扩展
提升单机性能
硬件升级
存在物理极限
成本递增
增加节点数量
分布式架构
理论上无极限
线性成本增长

水平扩展和垂直扩展各有其适用场景:

  • 垂直扩展:适合业务初期,简单快速,但受限于单节点物理极限
  • 水平扩展:适合大规模系统,可扩展性强,但技术复杂度高

水平扩展的价值定位

业务发展
性能需求增长
垂直扩展
单节点极限
水平扩展
分布式架构
弹性伸缩
无限扩展

水平扩展在架构演进中扮演着关键角色:

  1. 突破单节点限制:通过分布式架构突破单节点的物理极限
  2. 线性扩展能力:理论上可以实现无限的线性扩展
  3. 高可用保障:多节点部署提供天然的高可用能力
  4. 成本可控:通过标准化硬件实现成本的可预测增长

数据库层的水平扩展

数据分片策略

数据库水平扩展
数据分片
读写分离
分布式事务
数据一致性
水平分片
垂直分片
混合分片
分片键选择
主从复制
读写路由
延迟处理
负载均衡
实践案例:用户数据水平分片
// 分片策略管理器
@Component
public class ShardingStrategyManager {
    
    private static final Logger log = LoggerFactory.getLogger(ShardingStrategyManager.class);
    
    // 分片算法配置
    private final Map<String, ShardingAlgorithm> shardingAlgorithms = new ConcurrentHashMap<>();
    
    @PostConstruct
    public void init() {
        // 初始化分片算法
        shardingAlgorithms.put("user_id_mod", new ModuloShardingAlgorithm(4)); // 4个分片
        shardingAlgorithms.put("order_date_range", new RangeShardingAlgorithm());
        shardingAlgorithms.put("hash_consistent", new ConsistentHashShardingAlgorithm());
    }
    
    /**
     * 根据分片键计算目标数据库
     */
    public String determineTargetDatabase(String shardingKey, String algorithmType) {
        ShardingAlgorithm algorithm = shardingAlgorithms.get(algorithmType);
        if (algorithm == null) {
            throw new IllegalArgumentException("未知的分片算法: " + algorithmType);
        }
        
        String targetDatabase = algorithm.doSharding(shardingKey);
        log.debug("分片键: {}, 算法: {}, 目标数据库: {}", shardingKey, algorithmType, targetDatabase);
        
        return targetDatabase;
    }
    
    /**
     * 用户ID取模分片算法
     */
    public static class ModuloShardingAlgorithm implements ShardingAlgorithm {
        private final int shardCount;
        
        public ModuloShardingAlgorithm(int shardCount) {
            this.shardCount = shardCount;
        }
        
        @Override
        public String doSharding(String shardingKey) {
            try {
                long userId = Long.parseLong(shardingKey);
                int shardIndex = (int) (userId % shardCount);
                return "db_user_" + shardIndex;
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("无效的用户ID: " + shardingKey);
            }
        }
    }
    
    /**
     * 范围分片算法(按时间)
     */
    public static class RangeShardingAlgorithm implements ShardingAlgorithm {
        private final Map<String, String> rangeMap = new LinkedHashMap<>();
        
        public RangeShardingAlgorithm() {
            // 按年份分片
            rangeMap.put("2023", "db_order_2023");
            rangeMap.put("2024", "db_order_2024");
            rangeMap.put("2025", "db_order_2025");
        }
        
        @Override
        public String doSharding(String shardingKey) {
            // 假设shardingKey格式为: 2024-01-15
            String year = shardingKey.substring(0, 4);
            return rangeMap.getOrDefault(year, "db_order_current");
        }
    }
    
    /**
     * 一致性Hash分片算法
     */
    public static class ConsistentHashShardingAlgorithm implements ShardingAlgorithm {
        private final TreeMap<Long, String> virtualNodes = new TreeMap<>();
        private static final int VIRTUAL_NODE_COUNT = 150;
        
        public ConsistentHashShardingAlgorithm() {
            // 初始化虚拟节点
            String[] databases = {"db_node_0", "db_node_1", "db_node_2", "db_node_3"};
            for (String database : databases) {
                for (int i = 0; i < VIRTUAL_NODE_COUNT; i++) {
                    String virtualNode = database + "#" + i;
                    long hash = hash(virtualNode);
                    virtualNodes.put(hash, database);
                }
            }
        }
        
        @Override
        public String doSharding(String shardingKey) {
            long hash = hash(shardingKey);
            SortedMap<Long, String> tailMap = virtualNodes.tailMap(hash);
            Long targetHash = tailMap.isEmpty() ? virtualNodes.firstKey() : tailMap.firstKey();
            return virtualNodes.get(targetHash);
        }
        
        private long hash(String key) {
            return Math.abs(key.hashCode());
        }
    }
}

// 分片数据源路由
@Component
public class ShardingDataSourceRouter {
    
    @Autowired
    private ShardingStrategyManager shardingStrategyManager;
    
    // 数据源配置
    private final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>();
    
    @PostConstruct
    public void initDataSources() {
        // 初始化多个数据源
        for (int i = 0; i < 4; i++) {
            String dbName = "db_user_" + i;
            DataSource dataSource = createDataSource(dbName);
            dataSourceMap.put(dbName, dataSource);
        }
    }
    
    /**
     * 获取用户数据源
     */
    public DataSource getUserDataSource(Long userId) {
        String targetDatabase = shardingStrategyManager.determineTargetDatabase(
                String.valueOf(userId), "user_id_mod");
        return dataSourceMap.get(targetDatabase);
    }
    
    /**
     * 获取订单数据源
     */
    public DataSource getOrderDataSource(String orderDate) {
        String targetDatabase = shardingStrategyManager.determineTargetDatabase(
                orderDate, "order_date_range");
        return dataSourceMap.get(targetDatabase);
    }
    
    private DataSource createDataSource(String databaseName) {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/" + databaseName);
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        return new HikariDataSource(config);
    }
}

// 分片用户服务
@Service
public class ShardedUserService {
    
    private static final Logger log = LoggerFactory.getLogger(ShardedUserService.class);
    
    @Autowired
    private ShardingDataSourceRouter dataSourceRouter;
    
    /**
     * 根据用户ID查询用户信息
     */
    public User getUserById(Long userId) {
        DataSource dataSource = dataSourceRouter.getUserDataSource(userId);
        
        try (Connection connection = dataSource.getConnection()) {
            String sql = "SELECT * FROM users WHERE user_id = ?";
            try (PreparedStatement stmt = connection.prepareStatement(sql)) {
                stmt.setLong(1, userId);
                try (ResultSet rs = stmt.executeQuery()) {
                    if (rs.next()) {
                        return mapResultSetToUser(rs);
                    }
                }
            }
        } catch (SQLException e) {
            log.error("查询用户信息失败, userId: {}", userId, e);
            throw new RuntimeException("查询用户信息失败", e);
        }
        
        return null;
    }
    
    /**
     * 创建用户(自动路由到正确分片)
     */
    public User createUser(User user) {
        DataSource dataSource = dataSourceRouter.getUserDataSource(user.getUserId());
        
        try (Connection connection = dataSource.getConnection()) {
            String sql = "INSERT INTO users (user_id, username, email, created_time) VALUES (?, ?, ?, ?)";
            try (PreparedStatement stmt = connection.prepareStatement(sql)) {
                stmt.setLong(1, user.getUserId());
                stmt.setString(2, user.getUsername());
                stmt.setString(3, user.getEmail());
                stmt.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
                
                int affectedRows = stmt.executeUpdate();
                if (affectedRows > 0) {
                    log.info("用户创建成功, userId: {}, 目标数据库: {}", 
                            user.getUserId(), dataSource);
                    return user;
                }
            }
        } catch (SQLException e) {
            log.error("创建用户失败, userId: {}", user.getUserId(), e);
            throw new RuntimeException("创建用户失败", e);
        }
        
        return null;
    }
    
    /**
     * 跨分片查询(聚合查询)
     */
    public List<User> searchUsersAcrossShards(String username) {
        List<User> allUsers = new ArrayList<>();
        
        // 并行查询所有分片
        List<CompletableFuture<List<User>>> futures = new ArrayList<>();
        
        for (int i = 0; i < 4; i++) {
            final int shardIndex = i;
            CompletableFuture<List<User>> future = CompletableFuture.supplyAsync(() -> {
                return searchUsersInShard(shardIndex, username);
            });
            futures.add(future);
        }
        
        // 聚合结果
        for (CompletableFuture<List<User>> future : futures) {
            try {
                List<User> users = future.get(5, TimeUnit.SECONDS);
                allUsers.addAll(users);
            } catch (Exception e) {
                log.error("分片查询失败", e);
            }
        }
        
        return allUsers;
    }
    
    private List<User> searchUsersInShard(int shardIndex, String username) {
        List<User> users = new ArrayList<>();
        String dbName = "db_user_" + shardIndex;
        DataSource dataSource = dataSourceRouter.getDataSourceMap().get(dbName);
        
        try (Connection connection = dataSource.getConnection()) {
            String sql = "SELECT * FROM users WHERE username LIKE ?";
            try (PreparedStatement stmt = connection.prepareStatement(sql)) {
                stmt.setString(1, "%" + username + "%");
                try (ResultSet rs = stmt.executeQuery()) {
                    while (rs.next()) {
                        users.add(mapResultSetToUser(rs));
                    }
                }
            }
        } catch (SQLException e) {
            log.error("分片查询失败, shard: {}, username: {}", shardIndex, username, e);
        }
        
        return users;
    }
    
    private User mapResultSetToUser(ResultSet rs) throws SQLException {
        User user = new User();
        user.setUserId(rs.getLong("user_id"));
        user.setUsername(rs.getString("username"));
        user.setEmail(rs.getString("email"));
        user.setCreatedTime(rs.getTimestamp("created_time"));
        return user;
    }
}

读写分离与负载均衡

// 读写分离数据源配置
@Configuration
public class ReadWriteSplittingConfig {
    
    @Bean
    public DataSource masterDataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://master-db:3306/main_db");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(30);
        return new HikariDataSource(config);
    }
    
    @Bean
    public List<DataSource> slaveDataSources() {
        List<DataSource> slaves = new ArrayList<>();
        
        // 配置多个从库
        String[] slaveUrls = {
            "jdbc:mysql://slave1-db:3306/main_db",
            "jdbc:mysql://slave2-db:3306/main_db",
            "jdbc:mysql://slave3-db:3306/main_db"
        };
        
        for (String url : slaveUrls) {
            HikariConfig config = new HikariConfig();
            config.setJdbcUrl(url);
            config.setUsername("root");
            config.setPassword("password");
            config.setMaximumPoolSize(20);
            slaves.add(new HikariDataSource(config));
        }
        
        return slaves;
    }
    
    @Bean
    public ReadWriteSplittingDataSource readWriteDataSource() {
        return new ReadWriteSplittingDataSource(masterDataSource(), slaveDataSources());
    }
}

// 读写分离数据源实现
public class ReadWriteSplittingDataSource implements DataSource {
    
    private final DataSource masterDataSource;
    private final List<DataSource> slaveDataSources;
    private final AtomicInteger counter = new AtomicInteger(0);
    
    public ReadWriteSplittingDataSource(DataSource masterDataSource, List<DataSource> slaveDataSources) {
        this.masterDataSource = masterDataSource;
        this.slaveDataSources = slaveDataSources;
    }
    
    @Override
    public Connection getConnection() throws SQLException {
        if (isCurrentThreadReadOnly()) {
            return getSlaveConnection();
        } else {
            return masterDataSource.getConnection();
        }
    }
    
    /**
     * 轮询算法选择从库
     */
    private Connection getSlaveConnection() throws SQLException {
        int index = counter.getAndIncrement() % slaveDataSources.size();
        DataSource selectedSlave = slaveDataSources.get(index);
        
        // 健康检查
        if (!isHealthy(selectedSlave)) {
            // 选择下一个可用的从库
            for (int i = 0; i < slaveDataSources.size(); i++) {
                int nextIndex = (index + i + 1) % slaveDataSources.size();
                DataSource candidate = slaveDataSources.get(nextIndex);
                if (isHealthy(candidate)) {
                    return candidate.getConnection();
                }
            }
            // 如果没有可用的从库,使用主库
            return masterDataSource.getConnection();
        }
        
        return selectedSlave.getConnection();
    }
    
    private boolean isCurrentThreadReadOnly() {
        // 通过ThreadLocal或事务上下文判断是否为只读操作
        return ReadWriteContextHolder.isReadOnly();
    }
    
    private boolean isHealthy(DataSource dataSource) {
        try (Connection conn = dataSource.getConnection()) {
            return conn.isValid(1);
        } catch (SQLException e) {
            return false;
        }
    }
    
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return getConnection();
    }
    
    // 其他DataSource方法实现...
}

// 读写分离注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadWriteSplitting {
    String value() default "SLAVE"; // MASTER, SLAVE, AUTO
}

// 读写分离AOP切面
@Aspect
@Component
public class ReadWriteSplittingAspect {
    
    @Before("@annotation(readWriteSplitting)")
    public void setReadWriteContext(ReadWriteSplitting readWriteSplitting) {
        String route = readWriteSplitting.value();
        
        switch (route) {
            case "MASTER":
                ReadWriteContextHolder.setMaster();
                break;
            case "SLAVE":
                ReadWriteContextHolder.setSlave();
                break;
            case "AUTO":
                // 根据方法名自动判断
                String methodName = getCurrentMethodName();
                if (methodName.startsWith("get") || methodName.startsWith("find") || methodName.startsWith("query")) {
                    ReadWriteContextHolder.setSlave();
                } else {
                    ReadWriteContextHolder.setMaster();
                }
                break;
        }
    }
    
    @After("@annotation(readWriteSplitting)")
    public void clearReadWriteContext() {
        ReadWriteContextHolder.clear();
    }
    
    private String getCurrentMethodName() {
        return Thread.currentThread().getStackTrace()[3].getMethodName();
    }
}

// 读写上下文持有者
public class ReadWriteContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    
    public static void setMaster() {
        contextHolder.set("MASTER");
    }
    
    public static void setSlave() {
        contextHolder.set("SLAVE");
    }
    
    public static boolean isReadOnly() {
        return "SLAVE".equals(contextHolder.get());
    }
    
    public static void clear() {
        contextHolder.remove();
    }
}

Redis的水平扩展

Redis Cluster架构

Redis水平扩展
Redis Cluster
Redis Sentinel
代理模式
客户端分片
自动分片
故障转移
在线扩容
数据迁移
主从复制
监控告警
自动切换
高可用
实践案例:Redis Cluster实现
// Redis Cluster配置
@Configuration
public class RedisClusterConfig {
    
    @Bean
    public RedisClusterConfiguration redisClusterConfiguration() {
        RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration();
        
        // 配置集群节点
        clusterConfig.clusterNode("redis-node1", 6379);
        clusterConfig.clusterNode("redis-node2", 6379);
        clusterConfig.clusterNode("redis-node3", 6379);
        clusterConfig.clusterNode("redis-node4", 6379);
        clusterConfig.clusterNode("redis-node5", 6379);
        clusterConfig.clusterNode("redis-node6", 6379);
        
        // 配置密码
        clusterConfig.setPassword(RedisPassword.of("cluster-password"));
        
        return clusterConfig;
    }
    
    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(100);
        poolConfig.setMaxIdle(50);
        poolConfig.setMinIdle(10);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        
        return new JedisConnectionFactory(redisClusterConfiguration(), poolConfig);
    }
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        
        // 配置序列化
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        
        template.setValueSerializer(serializer);
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        
        return template;
    }
}

// Redis集群操作服务
@Service
public class RedisClusterService {
    
    private static final Logger log = LoggerFactory.getLogger(RedisClusterService.class);
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private RedisClusterConfiguration clusterConfig;
    
    /**
     * 集群信息监控
     */
    public ClusterInfo getClusterInfo() {
        return redisTemplate.execute(connection -> {
            String clusterNodes = connection.clusterGetNodes();
            ClusterInfo info = parseClusterInfo(clusterNodes);
            log.info("Redis集群信息: {}", info);
            return info;
        }, true);
    }
    
    /**
     * 数据分布分析
     */
    public Map<String, Long> analyzeDataDistribution() {
        Map<String, Long> distribution = new HashMap<>();
        
        // 获取每个节点的key数量
        List<RedisClusterNode> nodes = getClusterNodes();
        for (RedisClusterNode node : nodes) {
            if (node.isMaster()) {
                Long keyCount = getKeyCountForNode(node);
                distribution.put(node.getHost() + ":" + node.getPort(), keyCount);
            }
        }
        
        return distribution;
    }
    
    /**
     * 集群性能监控
     */
    public ClusterPerformanceMetrics getPerformanceMetrics() {
        ClusterPerformanceMetrics metrics = new ClusterPerformanceMetrics();
        
        // 获取集群节点信息
        List<RedisClusterNode> nodes = getClusterNodes();
        
        for (RedisClusterNode node : nodes) {
            NodeMetrics nodeMetrics = collectNodeMetrics(node);
            metrics.addNodeMetrics(nodeMetrics);
        }
        
        // 计算集群整体指标
        metrics.calculateClusterMetrics();
        
        return metrics;
    }
    
    /**
     * 集群扩容
     */
    public boolean scaleOutCluster(List<String> newNodes) {
        try {
            log.info("开始扩容Redis集群,新增节点: {}", newNodes);
            
            // 1. 添加新节点到集群
            for (String newNode : newNodes) {
                addNodeToCluster(newNode);
            }
            
            // 2. 重新分配槽位
            reshardClusterSlots(newNodes);
            
            // 3. 验证集群状态
            boolean isHealthy = verifyClusterHealth();
            
            if (isHealthy) {
                log.info("Redis集群扩容成功");
                return true;
            } else {
                log.error("Redis集群扩容后状态异常");
                return false;
            }
            
        } catch (Exception e) {
            log.error("Redis集群扩容失败", e);
            return false;
        }
    }
    
    /**
     * 集群缩容
     */
    public boolean scaleInCluster(List<String> removeNodes) {
        try {
            log.info("开始缩容Redis集群,移除节点: {}", removeNodes);
            
            // 1. 迁移数据到其他节点
            migrateDataFromNodes(removeNodes);
            
            // 2. 从集群中移除节点
            for (String removeNode : removeNodes) {
                removeNodeFromCluster(removeNode);
            }
            
            // 3. 验证集群状态
            boolean isHealthy = verifyClusterHealth();
            
            if (isHealthy) {
                log.info("Redis集群缩容成功");
                return true;
            } else {
                log.error("Redis集群缩容后状态异常");
                return false;
            }
            
        } catch (Exception e) {
            log.error("Redis集群缩容失败", e);
            return false;
        }
    }
    
    /**
     * 故障节点处理
     */
    public boolean handleNodeFailure(String failedNode) {
        try {
            log.warn("处理Redis集群故障节点: {}", failedNode);
            
            // 1. 检查故障节点状态
            RedisClusterNode failedClusterNode = findNodeByAddress(failedNode);
            if (failedClusterNode == null) {
                log.error("未找到故障节点: {}", failedNode);
                return false;
            }
            
            // 2. 如果是主节点,触发故障转移
            if (failedClusterNode.isMaster()) {
                boolean failoverSuccess = triggerFailover(failedClusterNode);
                if (!failoverSuccess) {
                    log.error("故障转移失败: {}", failedNode);
                    return false;
                }
            }
            
            // 3. 从集群中移除故障节点
            removeNodeFromCluster(failedNode);
            
            // 4. 添加新节点替换(可选)
            String replacementNode = "redis-node-replacement:6379";
            addNodeToCluster(replacementNode);
            
            log.info("故障节点处理完成: {}", failedNode);
            return true;
            
        } catch (Exception e) {
            log.error("故障节点处理失败: {}", failedNode, e);
            return false;
        }
    }
    
    // 辅助方法
    private List<RedisClusterNode> getClusterNodes() {
        return redisTemplate.execute(connection -> {
            return new ArrayList<>(connection.clusterGetNodes());
        }, true);
    }
    
    private Long getKeyCountForNode(RedisClusterNode node) {
        return redisTemplate.execute(connection -> {
            return connection.dbSize();
        }, node);
    }
    
    private NodeMetrics collectNodeMetrics(RedisClusterNode node) {
        return redisTemplate.execute(connection -> {
            Properties info = connection.info();
            return parseNodeMetrics(info);
        }, node);
    }
    
    private void addNodeToCluster(String nodeAddress) {
        redisTemplate.execute(connection -> {
            String[] parts = nodeAddress.split(":");
            connection.clusterMeet(parts[0], Integer.parseInt(parts[1]));
            return null;
        }, true);
    }
    
    private void removeNodeFromCluster(String nodeAddress) {
        redisTemplate.execute(connection -> {
            String nodeId = getNodeIdByAddress(nodeAddress);
            connection.clusterForget(nodeId);
            return null;
        }, true);
    }
    
    private void reshardClusterSlots(List<String> newNodes) {
        // 重新分配槽位的复杂逻辑
        log.info("重新分配集群槽位");
        // 实际实现需要考虑数据迁移、槽位平衡等
    }
    
    private boolean verifyClusterHealth() {
        ClusterInfo info = getClusterInfo();
        return info.isHealthy() && info.getFailedNodes() == 0;
    }
    
    private void migrateDataFromNodes(List<String> removeNodes) {
        // 数据迁移逻辑
        log.info("从待移除节点迁移数据");
    }
    
    private RedisClusterNode findNodeByAddress(String address) {
        List<RedisClusterNode> nodes = getClusterNodes();
        for (RedisClusterNode node : nodes) {
            if (address.equals(node.getHost() + ":" + node.getPort())) {
                return node;
            }
        }
        return null;
    }
    
    private boolean triggerFailover(RedisClusterNode failedNode) {
        // 触发故障转移
        log.info("触发故障转移,节点: {}", failedNode);
        return true;
    }
    
    private String getNodeIdByAddress(String address) {
        // 根据地址获取节点ID
        return "node-id-" + address;
    }
    
    private ClusterInfo parseClusterInfo(String clusterNodes) {
        // 解析集群节点信息
        return new ClusterInfo();
    }
    
    private NodeMetrics parseNodeMetrics(Properties info) {
        // 解析节点性能指标
        return new NodeMetrics();
    }
}

// Redis集群性能优化
@Component
public class RedisClusterOptimizer {
    
    private static final Logger log = LoggerFactory.getLogger(RedisClusterOptimizer.class);
    
    @Autowired
    private RedisClusterService clusterService;
    
    /**
     * 集群性能优化
     */
    public void optimizeCluster() {
        log.info("开始Redis集群性能优化");
        
        // 1. 分析当前性能瓶颈
        ClusterPerformanceMetrics currentMetrics = clusterService.getPerformanceMetrics();
        log.info("当前集群性能指标: {}", currentMetrics);
        
        // 2. 识别性能问题
        List<PerformanceIssue> issues = identifyPerformanceIssues(currentMetrics);
        
        // 3. 应用优化策略
        for (PerformanceIssue issue : issues) {
            applyOptimization(issue);
        }
        
        // 4. 验证优化效果
        ClusterPerformanceMetrics optimizedMetrics = clusterService.getPerformanceMetrics();
        log.info("优化后集群性能指标: {}", optimizedMetrics);
        
        // 5. 生成优化报告
        generateOptimizationReport(currentMetrics, optimizedMetrics);
    }
    
    /**
     * 内存优化
     */
    public void optimizeMemoryUsage() {
        // 内存使用分析
        Map<String, MemoryUsage> memoryUsage = analyzeMemoryUsage();
        
        // 内存优化策略
        for (Map.Entry<String, MemoryUsage> entry : memoryUsage.entrySet()) {
            String node = entry.getKey();
            MemoryUsage usage = entry.getValue();
            
            if (usage.getUsagePercentage() > 80) {
                // 内存使用率过高,执行优化
                optimizeNodeMemory(node);
            }
        }
    }
    
    /**
     * 网络优化
     */
    public void optimizeNetwork() {
        // 网络延迟分析
        Map<String, NetworkLatency> networkLatency = analyzeNetworkLatency();
        
        // 网络拓扑优化
        optimizeNetworkTopology(networkLatency);
    }
    
    private List<PerformanceIssue> identifyPerformanceIssues(ClusterPerformanceMetrics metrics) {
        List<PerformanceIssue> issues = new ArrayList<>();
        
        // 检查内存使用率
        if (metrics.getAverageMemoryUsage() > 80) {
            issues.add(new PerformanceIssue("HIGH_MEMORY_USAGE", "内存使用率过高"));
        }
        
        // 检查网络延迟
        if (metrics.getAverageNetworkLatency() > 10) {
            issues.add(new PerformanceIssue("HIGH_NETWORK_LATENCY", "网络延迟过高"));
        }
        
        // 检查负载不均衡
        if (metrics.getLoadBalanceScore() < 0.8) {
            issues.add(new PerformanceIssue("UNBALANCED_LOAD", "负载分布不均衡"));
        }
        
        return issues;
    }
    
    private void applyOptimization(PerformanceIssue issue) {
        switch (issue.getType()) {
            case "HIGH_MEMORY_USAGE":
                optimizeMemoryUsage();
                break;
            case "HIGH_NETWORK_LATENCY":
                optimizeNetwork();
                break;
            case "UNBALANCED_LOAD":
                rebalanceCluster();
                break;
        }
    }
    
    private void rebalanceCluster() {
        // 重新平衡集群负载
        log.info("重新平衡集群负载");
    }
    
    private Map<String, MemoryUsage> analyzeMemoryUsage() {
        // 分析内存使用情况
        return new HashMap<>();
    }
    
    private void optimizeNodeMemory(String node) {
        // 优化节点内存使用
        log.info("优化节点内存: {}", node);
    }
    
    private Map<String, NetworkLatency> analyzeNetworkLatency() {
        // 分析网络延迟
        return new HashMap<>();
    }
    
    private void optimizeNetworkTopology(Map<String, NetworkLatency> latency) {
        // 优化网络拓扑
        log.info("优化网络拓扑");
    }
    
    private void generateOptimizationReport(ClusterPerformanceMetrics before, ClusterPerformanceMetrics after) {
        // 生成优化报告
        log.info("生成集群优化报告");
    }
}

// 相关数据结构
@Data
public class ClusterInfo {
    private int totalNodes;
    private int masterNodes;
    private int slaveNodes;
    private int failedNodes;
    private boolean healthy;
}

@Data
public class ClusterPerformanceMetrics {
    private double averageMemoryUsage;
    private double averageNetworkLatency;
    private double loadBalanceScore;
    private List<NodeMetrics> nodeMetrics;
    
    public void addNodeMetrics(NodeMetrics metrics) {
        if (nodeMetrics == null) {
            nodeMetrics = new ArrayList<>();
        }
        nodeMetrics.add(metrics);
    }
    
    public void calculateClusterMetrics() {
        // 计算集群整体指标
        if (nodeMetrics != null && !nodeMetrics.isEmpty()) {
            double totalMemory = 0;
            double totalLatency = 0;
            
            for (NodeMetrics metrics : nodeMetrics) {
                totalMemory += metrics.getMemoryUsage();
                totalLatency += metrics.getNetworkLatency();
            }
            
            this.averageMemoryUsage = totalMemory / nodeMetrics.size();
            this.averageNetworkLatency = totalLatency / nodeMetrics.size();
        }
    }
}

@Data
public class NodeMetrics {
    private String nodeId;
    private double memoryUsage;
    private double networkLatency;
    private long connectedClients;
    private long totalCommandsProcessed;
}

@Data
public class PerformanceIssue {
    private String type;
    private String description;
    
    public PerformanceIssue(String type, String description) {
        this.type = type;
        this.description = description;
    }
}

@Data
public class MemoryUsage {
    private long usedMemory;
    private long totalMemory;
    private double usagePercentage;
}

@Data
public class NetworkLatency {
    private double averageLatency;
    private double maxLatency;
    private double minLatency;
}

服务层的水平扩展

微服务架构设计

服务层水平扩展
微服务拆分
服务发现
负载均衡
配置管理
监控告警
业务边界划分
服务粒度控制
依赖关系管理
数据一致性
服务注册
服务发现
健康检查
故障转移
客户端负载均衡
服务端负载均衡
DNS负载均衡
全局负载均衡
实践案例:微服务架构实现
// 服务注册与发现配置
@Configuration
@EnableDiscoveryClient
public class ServiceDiscoveryConfig {
    
    @Bean
    public ServiceInstanceRegistration serviceInstanceRegistration() {
        return ServiceInstanceRegistration.builder()
                .defaultUriSpec()
                .address("localhost")
                .port(8080)
                .ttl(30)
                .build();
    }
    
    @Bean
    public DiscoveryClient discoveryClient() {
        return new DefaultServiceDiscoveryClient();
    }
}

// 微服务基础架构
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
public class MicroserviceApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(MicroserviceApplication.class, args);
    }
    
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

// 服务注册中心 - Eureka Server
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

// Eureka配置
@Configuration
public class EurekaConfig {
    
    @Bean
    public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inetUtils) {
        EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
        config.setNonSecurePort(8761);
        config.setIpAddress("localhost");
        config.setPreferIpAddress(true);
        config.setLeaseRenewalIntervalInSeconds(30);
        config.setLeaseExpirationDurationInSeconds(90);
        return config;
    }
}

// 服务提供者
@RestController
@RequestMapping("/api/users")
public class UserServiceController {
    
    private static final Logger log = LoggerFactory.getLogger(UserServiceController.class);
    
    @Autowired
    private UserService userService;
    
    @Value("${server.port}")
    private int serverPort;
    
    /**
     * 获取用户信息
     */
    @GetMapping("/{userId}")
    @HystrixCommand(fallbackMethod = "getUserFallback")
    public ResponseEntity<User> getUser(@PathVariable Long userId) {
        log.info("处理用户查询请求, userId: {}, 服务端口: {}", userId, serverPort);
        
        User user = userService.getUserById(userId);
        if (user != null) {
            user.setServerPort(serverPort); // 标记响应的服务端口
            return ResponseEntity.ok(user);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    
    /**
     * 创建用户
     */
    @PostMapping
    @HystrixCommand(fallbackMethod = "createUserFallback")
    public ResponseEntity<User> createUser(@RequestBody @Valid UserRequest request) {
        log.info("处理用户创建请求, 服务端口: {}", serverPort);
        
        User user = userService.createUser(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }
    
    /**
     * 批量获取用户
     */
    @PostMapping("/batch")
    @HystrixCommand(fallbackMethod = "getUsersBatchFallback")
    public ResponseEntity<List<User>> getUsersBatch(@RequestBody List<Long> userIds) {
        log.info("处理批量用户查询请求, 数量: {}, 服务端口: {}", userIds.size(), serverPort);
        
        List<User> users = userService.getUsersByIds(userIds);
        return ResponseEntity.ok(users);
    }
    
    /**
     * 服务健康检查
     */
    @GetMapping("/health")
    public ResponseEntity<Map<String, Object>> health() {
        Map<String, Object> health = new HashMap<>();
        health.put("status", "UP");
        health.put("service", "user-service");
        health.put("port", serverPort);
        health.put("timestamp", System.currentTimeMillis());
        return ResponseEntity.ok(health);
    }
    
    // 降级方法
    public ResponseEntity<User> getUserFallback(Long userId) {
        log.warn("用户查询服务降级, userId: {}", userId);
        User fallbackUser = new User();
        fallbackUser.setUserId(userId);
        fallbackUser.setUsername("Fallback User");
        fallbackUser.setEmail("fallback@example.com");
        return ResponseEntity.ok(fallbackUser);
    }
    
    public ResponseEntity<User> createUserFallback(UserRequest request) {
        log.warn("用户创建服务降级");
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
    }
    
    public ResponseEntity<List<User>> getUsersBatchFallback(List<Long> userIds) {
        log.warn("批量用户查询服务降级");
        return ResponseEntity.ok(Collections.emptyList());
    }
}

// 服务消费者 - Feign客户端
@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient {
    
    @GetMapping("/api/users/{userId}")
    ResponseEntity<User> getUser(@PathVariable("userId") Long userId);
    
    @PostMapping("/api/users")
    ResponseEntity<User> createUser(@RequestBody UserRequest request);
    
    @PostMapping("/api/users/batch")
    ResponseEntity<List<User>> getUsersBatch(@RequestBody List<Long> userIds);
    
    @GetMapping("/api/users/health")
    ResponseEntity<Map<String, Object>> health();
}

// Feign客户端降级实现
@Component
public class UserServiceFallback implements UserServiceClient {
    
    private static final Logger log = LoggerFactory.getLogger(UserServiceFallback.class);
    
    @Override
    public ResponseEntity<User> getUser(Long userId) {
        log.warn("用户服务调用失败,执行降级逻辑, userId: {}", userId);
        User fallbackUser = new User();
        fallbackUser.setUserId(userId);
        fallbackUser.setUsername("Fallback User");
        return ResponseEntity.ok(fallbackUser);
    }
    
    @Override
    public ResponseEntity<User> createUser(UserRequest request) {
        log.warn("用户创建服务调用失败,执行降级逻辑");
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
    }
    
    @Override
    public ResponseEntity<List<User>> getUsersBatch(List<Long> userIds) {
        log.warn("批量用户查询服务调用失败,执行降级逻辑");
        return ResponseEntity.ok(Collections.emptyList());
    }
    
    @Override
    public ResponseEntity<Map<String, Object>> health() {
        log.warn("用户服务健康检查失败");
        Map<String, Object> health = new HashMap<>();
        health.put("status", "DOWN");
        health.put("service", "user-service-fallback");
        return ResponseEntity.ok(health);
    }
}

// 负载均衡配置
@Configuration
public class LoadBalancerConfig {
    
    @Bean
    public IRule ribbonRule() {
        // 配置负载均衡策略
        return new WeightedResponseTimeRule(); // 基于响应时间的权重策略
    }
    
    @Bean
    public IPing ribbonPing() {
        return new PingUrl(); // 使用URL健康检查
    }
    
    @Bean
    public ServerListSubsetFilter serverListFilter() {
        ServerListSubsetFilter filter = new ServerListSubsetFilter();
        filter.setSize(5); // 保持5个服务实例的列表
        return filter;
    }
}

// 客户端负载均衡实现
@Component
public class LoadBalancedUserService {
    
    private static final Logger log = LoggerFactory.getLogger(LoadBalancedUserService.class);
    
    @Autowired
    private LoadBalancerClient loadBalancer;
    
    @Autowired
    private RestTemplate restTemplate;
    
    /**
     * 使用Ribbon进行负载均衡调用
     */
    public User getUserWithLoadBalance(Long userId) {
        // 选择服务实例
        ServiceInstance instance = loadBalancer.choose("user-service");
        
        if (instance == null) {
            log.error("没有可用的用户服务实例");
            throw new RuntimeException("No available user service instances");
        }
        
        log.info("选择服务实例: {}:{}, 用户ID: {}", 
                instance.getHost(), instance.getPort(), userId);
        
        // 构建请求URL
        String url = String.format("http://%s:%d/api/users/%d", 
                instance.getHost(), instance.getPort(), userId);
        
        try {
            // 发起请求
            ResponseEntity<User> response = restTemplate.getForEntity(url, User.class);
            User user = response.getBody();
            
            if (user != null) {
                user.setServerPort(instance.getPort()); // 记录实际调用的服务端口
            }
            
            return user;
        } catch (Exception e) {
            log.error("调用用户服务失败: {}", url, e);
            throw new RuntimeException("Failed to call user service", e);
        }
    }
    
    /**
     * 批量调用测试负载均衡效果
     */
    public Map<Integer, Integer> testLoadBalancing(int requestCount) {
        Map<Integer, Integer> portDistribution = new HashMap<>();
        
        for (int i = 0; i < requestCount; i++) {
            try {
                User user = getUserWithLoadBalance(1L);
                int port = user.getServerPort();
                portDistribution.put(port, portDistribution.getOrDefault(port, 0) + 1);
                
                // 模拟处理时间
                Thread.sleep(10);
            } catch (Exception e) {
                log.error("测试请求失败", e);
            }
        }
        
        log.info("负载均衡测试结果: {}", portDistribution);
        return portDistribution;
    }
}

// 服务配置管理
@Configuration
@ConfigurationProperties(prefix = "microservice")
@Data
public class MicroserviceConfig {
    
    private String serviceName;
    private String serviceVersion;
    private int instanceId;
    private Map<String, String> metadata = new HashMap<>();
    
    @PostConstruct
    public void init() {
        // 生成实例ID
        this.instanceId = new Random().nextInt(10000);
        metadata.put("startTime", String.valueOf(System.currentTimeMillis()));
        metadata.put("instanceId", String.valueOf(instanceId));
    }
}

// 服务监控与健康检查
@Component
public class ServiceHealthMonitor {
    
    private static final Logger log = LoggerFactory.getLogger(ServiceHealthMonitor.class);
    
    @Autowired
    private DiscoveryClient discoveryClient;
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    /**
     * 监控所有服务实例的健康状态
     */
    @Scheduled(fixedRate = 30000) // 每30秒检查一次
    public void monitorServiceHealth() {
        List<String> services = discoveryClient.getServices();
        
        for (String service : services) {
            List<ServiceInstance> instances = discoveryClient.getInstances(service);
            
            for (ServiceInstance instance : instances) {
                try {
                    boolean isHealthy = checkInstanceHealth(instance);
                    log.info("服务健康检查: {} - {}:{}, 状态: {}", 
                            service, instance.getHost(), instance.getPort(), isHealthy ? "健康" : "异常");
                    
                    if (!isHealthy) {
                        handleUnhealthyInstance(service, instance);
                    }
                } catch (Exception e) {
                    log.error("健康检查失败: {} - {}:{}", 
                            service, instance.getHost(), instance.getPort(), e);
                }
            }
        }
    }
    
    /**
     * 检查服务实例健康状态
     */
    private boolean checkInstanceHealth(ServiceInstance instance) {
        try {
            // 构建健康检查URL
            String healthUrl = String.format("http://%s:%d/api/users/health", 
                    instance.getHost(), instance.getPort());
            
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<Map> response = restTemplate.getForEntity(healthUrl, Map.class);
            
            if (response.getStatusCode() == HttpStatus.OK) {
                Map<String, Object> health = response.getBody();
                return "UP".equals(health.get("status"));
            }
            
            return false;
        } catch (Exception e) {
            log.error("健康检查请求失败: {}:{}", instance.getHost(), instance.getPort(), e);
            return false;
        }
    }
    
    /**
     * 处理不健康的服务实例
     */
    private void handleUnhealthyInstance(String service, ServiceInstance instance) {
        log.warn("发现不健康的服务实例: {} - {}:{}, 准备进行故障处理", 
                service, instance.getHost(), instance.getPort());
        
        // 1. 记录故障信息
        recordFailure(service, instance);
        
        // 2. 通知运维人员
        notifyOperations(service, instance);
        
        // 3. 触发自动恢复机制(如果配置)
        if (shouldTriggerAutoRecovery(service, instance)) {
            triggerAutoRecovery(service, instance);
        }
    }
    
    /**
     * 性能指标收集
     */
    @Scheduled(fixedRate = 60000) // 每分钟收集一次
    public void collectPerformanceMetrics() {
        List<String> services = discoveryClient.getServices();
        
        for (String service : services) {
            List<ServiceInstance> instances = discoveryClient.getInstances(service);
            
            ServiceMetrics metrics = new ServiceMetrics();
            metrics.setServiceName(service);
            metrics.setInstanceCount(instances.size());
            metrics.setTimestamp(System.currentTimeMillis());
            
            // 收集各实例的性能数据
            for (ServiceInstance instance : instances) {
                InstanceMetrics instanceMetrics = collectInstanceMetrics(instance);
                metrics.addInstanceMetrics(instanceMetrics);
            }
            
            // 存储或上报指标
            storeMetrics(metrics);
        }
    }
    
    private InstanceMetrics collectInstanceMetrics(ServiceInstance instance) {
        InstanceMetrics metrics = new InstanceMetrics();
        metrics.setInstanceId(instance.getInstanceId());
        metrics.setHost(instance.getHost());
        metrics.setPort(instance.getPort());
        
        // 这里可以集成实际的性能监控数据
        // 如:CPU使用率、内存使用率、请求响应时间等
        
        return metrics;
    }
    
    private void recordFailure(String service, ServiceInstance instance) {
        log.error("记录服务故障: {} - {}:{}", service, instance.getHost(), instance.getPort());
        // 实际实现中可以写入数据库或发送到监控系统
    }
    
    private void notifyOperations(String service, ServiceInstance instance) {
        log.warn("通知运维人员: {} - {}:{} 服务异常", service, instance.getHost(), instance.getPort());
        // 实际实现中可以发送邮件、短信或调用告警接口
    }
    
    private boolean shouldTriggerAutoRecovery(String service, ServiceInstance instance) {
        // 根据配置和故障频率决定是否触发自动恢复
        return true;
    }
    
    private void triggerAutoRecovery(String service, ServiceInstance instance) {
        log.info("触发自动恢复机制: {} - {}:{}", service, instance.getHost(), instance.getPort());
        // 实际实现中可以调用容器编排平台的API重启服务
    }
    
    private void storeMetrics(ServiceMetrics metrics) {
        log.debug("存储服务指标: {}", metrics.getServiceName());
        // 实际实现中可以写入时序数据库或监控系统
    }
}

// 服务限流与熔断
@Component
public class ServiceProtection {
    
    private static final Logger log = LoggerFactory.getLogger(ServiceProtection.class);
    
    // 限流器
    private final RateLimiter rateLimiter = RateLimiter.create(1000); // 每秒1000个请求
    
    // 熔断器
    private final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("user-service");
    
    /**
     * 带保护的远程调用
     */
    public <T> T executeWithProtection(Supplier<T> supplier, String operation) {
        // 1. 限流检查
        if (!rateLimiter.tryAcquire()) {
            log.warn("请求被限流: {}", operation);
            throw new RateLimitExceededException("请求过于频繁,请稍后再试");
        }
        
        // 2. 熔断检查
        if (circuitBreaker.getState() == CircuitBreaker.State.OPEN) {
            log.warn("服务熔断中: {}", operation);
            throw new ServiceUnavailableException("服务暂时不可用");
        }
        
        // 3. 执行调用
        try {
            T result = supplier.get();
            circuitBreaker.onSuccess();
            return result;
        } catch (Exception e) {
            circuitBreaker.onError(1, e);
            log.error("服务调用失败: {}", operation, e);
            throw new RuntimeException("服务调用失败", e);
        }
    }
    
    /**
     * 自适应限流
     */
    public void adaptiveRateLimiting() {
        // 根据系统负载动态调整限流阈值
        double cpuUsage = getSystemCpuUsage();
        double memoryUsage = getSystemMemoryUsage();
        
        if (cpuUsage > 80 || memoryUsage > 85) {
            // 系统负载高,降低限流阈值
            double newRate = 500; // 降低到每秒500个请求
            rateLimiter.setRate(newRate);
            log.warn("系统负载过高,调整限流阈值: {}", newRate);
        } else if (cpuUsage < 50 && memoryUsage < 60) {
            // 系统负载低,提高限流阈值
            double newRate = 1500; // 提高到每秒1500个请求
            rateLimiter.setRate(newRate);
            log.info("系统负载正常,调整限流阈值: {}", newRate);
        }
    }
    
    private double getSystemCpuUsage() {
        // 获取系统CPU使用率
        return 50.0; // 模拟数据
    }
    
    private double getSystemMemoryUsage() {
        // 获取系统内存使用率
        return 60.0; // 模拟数据
    }
}

// 相关数据结构
@Data
public class ServiceMetrics {
    private String serviceName;
    private int instanceCount;
    private long timestamp;
    private List<InstanceMetrics> instanceMetrics = new ArrayList<>();
    
    public void addInstanceMetrics(InstanceMetrics metrics) {
        instanceMetrics.add(metrics);
    }
}

@Data
public class InstanceMetrics {
    private String instanceId;
    private String host;
    private int port;
    private double cpuUsage;
    private double memoryUsage;
    private double responseTime;
    private int activeRequests;
    private long timestamp;
}

@Data
public class User {
    private Long userId;
    private String username;
    private String email;
    private int serverPort; // 记录响应的服务端口
    private Timestamp createdTime;
}

@Data
public class UserRequest {
    @NotNull
    private String username;
    
    @Email
    private String email;
    
    @Size(min = 6, max = 20)
    private String password;
}

容器化与编排

# Docker Compose配置 - 微服务部署
version: '3.8'

services:
  # Eureka服务注册中心
  eureka-server:
    image: eureka-server:latest
    ports:
      - "8761:8761"
    environment:
      - SPRING_PROFILES_ACTIVE=production
      - EUREKA_CLIENT_REGISTER_WITH_EUREKA=false
      - EUREKA_CLIENT_FETCH_REGISTRY=false
    networks:
      - microservice-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8761/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # 用户服务实例1
  user-service-1:
    image: user-service:latest
    ports:
      - "8081:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=production
      - SERVER_PORT=8080
      - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka-server:8761/eureka/
      - INSTANCE_ID=user-service-1
    depends_on:
      - eureka-server
      - mysql-master
      - redis-cluster
    networks:
      - microservice-network
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

  # 用户服务实例2
  user-service-2:
    image: user-service:latest
    ports:
      - "8082:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=production
      - SERVER_PORT=8080
      - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka-server:8761/eureka/
      - INSTANCE_ID=user-service-2
    depends_on:
      - eureka-server
      - mysql-master
      - redis-cluster
    networks:
      - microservice-network
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

  # 用户服务实例3
  user-service-3:
    image: user-service:latest
    ports:
      - "8083:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=production
      - SERVER_PORT=8080
      - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka-server:8761/eureka/
      - INSTANCE_ID=user-service-3
    depends_on:
      - eureka-server
      - mysql-master
      - redis-cluster
    networks:
      - microservice-network
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

  # API网关
  api-gateway:
    image: api-gateway:latest
    ports:
      - "80:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=production
      - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka-server:8761/eureka/
      - ZUUL_ROUTES_USER_SERVICE_URL=http://user-service
    depends_on:
      - eureka-server
    networks:
      - microservice-network

  # 负载均衡器 - Nginx
  nginx-lb:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - user-service-1
      - user-service-2
      - user-service-3
    networks:
      - microservice-network

  # MySQL主库
  mysql-master:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=root123
      - MYSQL_DATABASE=user_db
    ports:
      - "3306:3306"
    volumes:
      - mysql-master-data:/var/lib/mysql
    networks:
      - microservice-network

  # MySQL从库1
  mysql-slave-1:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=root123
      - MYSQL_DATABASE=user_db
    ports:
      - "3307:3306"
    volumes:
      - mysql-slave-1-data:/var/lib/mysql
    depends_on:
      - mysql-master
    networks:
      - microservice-network

  # Redis集群节点1
  redis-node-1:
    image: redis:6-alpine
    ports:
      - "7001:6379"
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes
    volumes:
      - redis-node-1-data:/data
    networks:
      - microservice-network

  # Redis集群节点2
  redis-node-2:
    image: redis:6-alpine
    ports:
      - "7002:6379"
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes
    volumes:
      - redis-node-2-data:/data
    networks:
      - microservice-network

  # Redis集群节点3
  redis-node-3:
    image: redis:6-alpine
    ports:
      - "7003:6379"
    command: redis-server --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes
    volumes:
      - redis-node-3-data:/data
    networks:
      - microservice-network

networks:
  microservice-network:
    driver: bridge

volumes:
  mysql-master-data:
  mysql-slave-1-data:
  redis-node-1-data:
  redis-node-2-data:
  redis-node-3-data:
# Kubernetes部署配置 - 水平扩展
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
  namespace: microservices
spec:
  replicas: 3  # 初始副本数
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: user-service:latest
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "production"
        - name: EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE
          value: "http://eureka-server:8761/eureka/"
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 20
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
  namespace: microservices
spec:
  selector:
    app: user-service
  ports:
  - port: 8080
    targetPort: 8080
  type: ClusterIP
---
# 水平自动扩缩容配置
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: user-service-hpa
  namespace: microservices
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: user-service
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60

水平扩展的挑战与解决方案

数据一致性挑战

数据一致性挑战
分布式事务
数据同步
最终一致性
冲突解决
两阶段提交
TCC模式
Saga模式
本地消息表
主从同步
双向同步
异步复制
同步复制
事件驱动
消息队列
补偿机制
重试策略
实践案例:分布式事务处理
// 分布式事务管理器
@Component
public class DistributedTransactionManager {
    
    private static final Logger log = LoggerFactory.getLogger(DistributedTransactionManager.class);
    
    @Autowired
    private TransactionLogRepository transactionLogRepository;
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    /**
     * 执行分布式事务
     */
    @Transactional
    public <T> T executeDistributedTransaction(DistributedTransaction<T> transaction) {
        String transactionId = generateTransactionId();
        log.info("开始分布式事务, ID: {}", transactionId);
        
        try {
            // 1. 记录事务开始
            recordTransactionStart(transactionId, transaction);
            
            // 2. 执行事务
            T result = transaction.execute();
            
            // 3. 记录事务成功
            recordTransactionSuccess(transactionId);
            
            log.info("分布式事务执行成功, ID: {}", transactionId);
            return result;
            
        } catch (Exception e) {
            log.error("分布式事务执行失败, ID: {}", transactionId, e);
            
            // 4. 记录事务失败并触发补偿
            recordTransactionFailure(transactionId, e);
            triggerCompensation(transactionId);
            
            throw new DistributedTransactionException("分布式事务执行失败", e);
        }
    }
    
    /**
     * TCC模式实现
     */
    public class TCCDistributedTransaction {
        
        private final String transactionId;
        private final List<TCCParticipant> participants;
        
        public TCCDistributedTransaction(String transactionId) {
            this.transactionId = transactionId;
            this.participants = new ArrayList<>();
        }
        
        public void addParticipant(TCCParticipant participant) {
            participants.add(participant);
        }
        
        /**
         * Try阶段
         */
        public boolean tryPhase() {
            log.info("TCC Try阶段开始, 事务ID: {}", transactionId);
            
            List<Boolean> tryResults = new ArrayList<>();
            
            for (TCCParticipant participant : participants) {
                try {
                    boolean result = participant.tryExecute();
                    tryResults.add(result);
                    
                    if (!result) {
                        log.warn("TCC Try阶段失败, 参与者: {}", participant.getName());
                        return false;
                    }
                } catch (Exception e) {
                    log.error("TCC Try阶段异常, 参与者: {}", participant.getName(), e);
                    return false;
                }
            }
            
            log.info("TCC Try阶段成功, 事务ID: {}", transactionId);
            return true;
        }
        
        /**
         * Confirm阶段
         */
        public boolean confirmPhase() {
            log.info("TCC Confirm阶段开始, 事务ID: {}", transactionId);
            
            for (TCCParticipant participant : participants) {
                try {
                    participant.confirm();
                } catch (Exception e) {
                    log.error("TCC Confirm阶段异常, 参与者: {}", participant.getName(), e);
                    // 记录异常但继续执行其他参与者的confirm
                }
            }
            
            log.info("TCC Confirm阶段完成, 事务ID: {}", transactionId);
            return true;
        }
        
        /**
         * Cancel阶段
         */
        public boolean cancelPhase() {
            log.info("TCC Cancel阶段开始, 事务ID: {}", transactionId);
            
            for (TCCParticipant participant : participants) {
                try {
                    participant.cancel();
                } catch (Exception e) {
                    log.error("TCC Cancel阶段异常, 参与者: {}", participant.getName(), e);
                    // 记录异常但继续执行其他参与者的cancel
                }
            }
            
            log.info("TCC Cancel阶段完成, 事务ID: {}", transactionId);
            return true;
        }
    }
    
    /**
     * Saga模式实现
     */
    public class SagaDistributedTransaction {
        
        private final String transactionId;
        private final List<SagaStep> steps;
        private final List<SagaStep> completedSteps;
        
        public SagaDistributedTransaction(String transactionId) {
            this.transactionId = transactionId;
            this.steps = new ArrayList<>();
            this.completedSteps = new ArrayList<>();
        }
        
        public void addStep(SagaStep step) {
            steps.add(step);
        }
        
        /**
         * 执行Saga事务
         */
        public boolean execute() {
            log.info("Saga事务执行开始, ID: {}", transactionId);
            
            for (SagaStep step : steps) {
                try {
                    log.info("执行Saga步骤: {}", step.getName());
                    step.execute();
                    completedSteps.add(step);
                    log.info("Saga步骤执行成功: {}", step.getName());
                } catch (Exception e) {
                    log.error("Saga步骤执行失败: {}", step.getName(), e);
                    // 执行补偿
                    compensate();
                    return false;
                }
            }
            
            log.info("Saga事务执行成功, ID: {}", transactionId);
            return true;
        }
        
        /**
         * 执行补偿
         */
        private void compensate() {
            log.info("开始Saga补偿, ID: {}", transactionId);
            
            // 逆序执行补偿
            Collections.reverse(completedSteps);
            
            for (SagaStep step : completedSteps) {
                try {
                    log.info("执行Saga补偿步骤: {}", step.getName());
                    step.compensate();
                } catch (Exception e) {
                    log.error("Saga补偿步骤执行异常: {}", step.getName(), e);
                    // 记录补偿失败,可能需要人工干预
                }
            }
            
            log.info("Saga补偿完成, ID: {}", transactionId);
        }
    }
    
    // 辅助方法
    private String generateTransactionId() {
        return "TX-" + System.currentTimeMillis() + "-" + Thread.currentThread().getId();
    }
    
    private void recordTransactionStart(String transactionId, DistributedTransaction<?> transaction) {
        TransactionLog log = new TransactionLog();
        log.setTransactionId(transactionId);
        log.setTransactionType(transaction.getType());
        log.setStatus("STARTED");
        log.setStartTime(LocalDateTime.now());
        
        transactionLogRepository.save(log);
    }
    
    private void recordTransactionSuccess(String transactionId) {
        updateTransactionStatus(transactionId, "SUCCESS");
    }
    
    private void recordTransactionFailure(String transactionId, Exception e) {
        updateTransactionStatus(transactionId, "FAILED");
        // 记录异常信息
    }
    
    private void updateTransactionStatus(String transactionId, String status) {
        TransactionLog log = transactionLogRepository.findByTransactionId(transactionId);
        if (log != null) {
            log.setStatus(status);
            log.setEndTime(LocalDateTime.now());
            transactionLogRepository.save(log);
        }
    }
    
    private void triggerCompensation(String transactionId) {
        // 发布补偿事件
        CompensationEvent event = new CompensationEvent(transactionId);
        eventPublisher.publishEvent(event);
    }
}

// TCC参与者接口
public interface TCCParticipant {
    String getName();
    boolean tryExecute();
    boolean confirm();
    boolean cancel();
}

// Saga步骤接口
public interface SagaStep {
    String getName();
    void execute() throws Exception;
    void compensate() throws Exception;
}

// 本地消息表实现最终一致性
@Component
public class LocalMessageTable {
    
    private static final Logger log = LoggerFactory.getLogger(LocalMessageTable.class);
    
    @Autowired
    private MessageRepository messageRepository;
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    /**
     * 发送可靠消息
     */
    @Transactional
    public void sendReliableMessage(String exchange, String routingKey, Object message) {
        // 1. 保存消息到本地表
        MessageRecord record = new MessageRecord();
        record.setMessageId(generateMessageId());
        record.setExchange(exchange);
        record.setRoutingKey(routingKey);
        record.setMessageContent(serializeMessage(message));
        record.setStatus("PENDING");
        record.setCreatedTime(LocalDateTime.now());
        
        messageRepository.save(record);
        
        // 2. 发送消息到MQ
        try {
            rabbitTemplate.convertAndSend(exchange, routingKey, message, messagePostProcessor -> {
                messagePostProcessor.getMessageProperties().setMessageId(record.getMessageId());
                return messagePostProcessor;
            });
            
            // 3. 更新消息状态
            record.setStatus("SENT");
            record.setSentTime(LocalDateTime.now());
            messageRepository.save(record);
            
            log.info("可靠消息发送成功, ID: {}", record.getMessageId());
            
        } catch (Exception e) {
            log.error("消息发送失败, ID: {}", record.getMessageId(), e);
            // 消息保持在PENDING状态,等待定时任务重试
        }
    }
    
    /**
     * 定时扫描未发送的消息
     */
    @Scheduled(fixedRate = 30000) // 每30秒扫描一次
    public void scanPendingMessages() {
        log.info("开始扫描待发送消息");
        
        List<MessageRecord> pendingMessages = messageRepository.findByStatusAndCreatedTimeBefore(
                "PENDING", LocalDateTime.now().minusMinutes(1));
        
        for (MessageRecord message : pendingMessages) {
            try {
                resendMessage(message);
            } catch (Exception e) {
                log.error("消息重发失败, ID: {}", message.getMessageId(), e);
                
                // 更新重试次数
                message.incrementRetryCount();
                if (message.getRetryCount() >= 3) {
                    message.setStatus("FAILED");
                }
                messageRepository.save(message);
            }
        }
        
        log.info("待发送消息扫描完成,处理数量: {}", pendingMessages.size());
    }
    
    private void resendMessage(MessageRecord message) {
        // 重新发送消息
        Object messageContent = deserializeMessage(message.getMessageContent());
        
        rabbitTemplate.convertAndSend(
                message.getExchange(), 
                message.getRoutingKey(), 
                messageContent,
                messagePostProcessor -> {
                    messagePostProcessor.getMessageProperties().setMessageId(message.getMessageId());
                    return messagePostProcessor;
                }
        );
        
        // 更新状态
        message.setStatus("SENT");
        message.setSentTime(LocalDateTime.now());
        messageRepository.save(message);
        
        log.info("消息重发成功, ID: {}", message.getMessageId());
    }
    
    private String generateMessageId() {
        return "MSG-" + System.currentTimeMillis() + "-" + Thread.currentThread().getId();
    }
    
    private String serializeMessage(Object message) {
        try {
            return new ObjectMapper().writeValueAsString(message);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("消息序列化失败", e);
        }
    }
    
    private Object deserializeMessage(String messageContent) {
        try {
            return new ObjectMapper().readValue(messageContent, Object.class);
        } catch (IOException e) {
            throw new RuntimeException("消息反序列化失败", e);
        }
    }
}

// 消息监听器
@Component
public class ReliableMessageListener {
    
    private static final Logger log = LoggerFactory.getLogger(ReliableMessageListener.class);
    
    @Autowired
    private MessageRepository messageRepository;
    
    @RabbitListener(queues = "reliable.message.queue")
    public void handleMessage(Message message, Channel channel) throws IOException {
        String messageId = message.getMessageProperties().getMessageId();
        
        try {
            log.info("接收到可靠消息, ID: {}", messageId);
            
            // 1. 检查消息是否已处理(幂等性)
            if (isMessageProcessed(messageId)) {
                log.info("消息已处理,跳过重复处理, ID: {}", messageId);
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }
            
            // 2. 处理消息
            processMessage(message);
            
            // 3. 标记消息已处理
            markMessageAsProcessed(messageId);
            
            // 4. 确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            
            log.info("消息处理成功, ID: {}", messageId);
            
        } catch (Exception e) {
            log.error("消息处理失败, ID: {}", messageId, e);
            
            // 拒绝消息并重新入队
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
        }
    }
    
    private boolean isMessageProcessed(String messageId) {
        return messageRepository.existsByMessageIdAndStatus(messageId, "PROCESSED");
    }
    
    private void processMessage(Message message) {
        // 实际的消息处理逻辑
        String messageBody = new String(message.getBody());
        log.info("处理消息内容: {}", messageBody);
        // 这里可以调用具体的业务逻辑
    }
    
    private void markMessageAsProcessed(String messageId) {
        MessageRecord record = messageRepository.findByMessageId(messageId);
        if (record != null) {
            record.setStatus("PROCESSED");
            record.setProcessedTime(LocalDateTime.now());
            messageRepository.save(record);
        }
    }
}

// 相关数据结构
@Data
@Entity
@Table(name = "transaction_log")
public class TransactionLog {
    @Id
    private String transactionId;
    private String transactionType;
    private String status;
    private LocalDateTime startTime;
    private LocalDateTime endTime;
    private String errorMessage;
}

@Data
@Entity
@Table(name = "message_record")
public class MessageRecord {
    @Id
    private String messageId;
    private String exchange;
    private String routingKey;
    @Column(columnDefinition = "TEXT")
    private String messageContent;
    private String status;
    private int retryCount = 0;
    private LocalDateTime createdTime;
    private LocalDateTime sentTime;
    private LocalDateTime processedTime;
    
    public void incrementRetryCount() {
        this.retryCount++;
    }
}

// 分布式事务异常
public class DistributedTransactionException extends RuntimeException {
    public DistributedTransactionException(String message) {
        super(message);
    }
    
    public DistributedTransactionException(String message, Throwable cause) {
        super(message, cause);
    }
}

网络延迟与分区容错

// 网络延迟监控与处理
@Component
public class NetworkLatencyMonitor {
    
    private static final Logger log = LoggerFactory.getLogger(NetworkLatencyMonitor.class);
    
    @Autowired
    private MeterRegistry meterRegistry;
    
    private final Map<String, Long> latencyMetrics = new ConcurrentHashMap<>();
    
    /**
     * 监控服务间调用延迟
     */
    public <T> T monitorServiceCall(String serviceName, Supplier<T> serviceCall) {
        long startTime = System.currentTimeMillis();
        
        try {
            T result = serviceCall.get();
            
            long duration = System.currentTimeMillis() - startTime;
            recordLatency(serviceName, duration);
            
            // 记录指标
            meterRegistry.timer("service.call.latency", "service", serviceName)
                    .record(duration, TimeUnit.MILLISECONDS);
            
            return result;
            
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            recordLatency(serviceName, duration);
            
            meterRegistry.counter("service.call.errors", "service", serviceName).increment();
            
            throw e;
        }
    }
    
    /**
     * 网络分区检测
     */
    public boolean detectNetworkPartition() {
        // 检测网络分区的方法
        List<String> services = Arrays.asList("user-service", "order-service", "payment-service");
        
        Map<String, Boolean> serviceHealth = new HashMap<>();
        
        for (String service : services) {
            boolean isHealthy = checkServiceHealth(service);
            serviceHealth.put(service, isHealthy);
        }
        
        // 分析网络分区情况
        return analyzeNetworkPartition(serviceHealth);
    }
    
    private void recordLatency(String serviceName, long latency) {
        latencyMetrics.put(serviceName, latency);
        
        if (latency > 1000) { // 超过1秒认为延迟过高
            log.warn("服务 {} 调用延迟过高: {}ms", serviceName, latency);
        }
    }
    
    private boolean checkServiceHealth(String serviceName) {
        // 实际的健康检查逻辑
        return true; // 模拟实现
    }
    
    private boolean analyzeNetworkPartition(Map<String, Boolean> serviceHealth) {
        // 分析是否存在网络分区
        long healthyCount = serviceHealth.values().stream().filter(Boolean::booleanValue).count();
        long totalCount = serviceHealth.size();
        
        // 如果超过一半服务不可用,可能存在网络分区
        return healthyCount < totalCount / 2;
    }
}

// 分区容错策略
@Component
public class PartitionToleranceStrategy {
    
    private static final Logger log = LoggerFactory.getLogger(PartitionToleranceStrategy.class);
    
    /**
     * 处理网络分区
     */
    public void handleNetworkPartition() {
        log.warn("检测到网络分区,启动分区容错策略");
        
        // 1. 启用本地缓存
        enableLocalCache();
        
        // 2. 降级到只读模式
        enableReadOnlyMode();
        
        // 3. 启用异步处理
        enableAsyncProcessing();
        
        // 4. 记录分区事件
        recordPartitionEvent();
    }
    
    /**
     * 脑裂处理
     */
    public void handleSplitBrain() {
        log.error("检测到脑裂情况,启动紧急处理");
        
        // 1. 暂停写操作
        pauseWriteOperations();
        
        // 2. 选举新的主节点
        electNewMaster();
        
        // 3. 数据一致性检查
        checkDataConsistency();
        
        // 4. 恢复服务
        resumeServices();
    }
    
    private void enableLocalCache() {
        log.info("启用本地缓存模式");
        // 实现本地缓存逻辑
    }
    
    private void enableReadOnlyMode() {
        log.info("启用只读模式");
        // 实现只读模式逻辑
    }
    
    private void enableAsyncProcessing() {
        log.info("启用异步处理模式");
        // 实现异步处理逻辑
    }
    
    private void recordPartitionEvent() {
        log.info("记录网络分区事件");
        // 实现事件记录逻辑
    }
    
    private void pauseWriteOperations() {
        log.info("暂停写操作");
        // 实现暂停写操作逻辑
    }
    
    private void electNewMaster() {
        log.info("选举新的主节点");
        // 实现主节点选举逻辑
    }
    
    private void checkDataConsistency() {
        log.info("检查数据一致性");
        // 实现数据一致性检查逻辑
    }
    
    private void resumeServices() {
        log.info("恢复服务");
        // 实现服务恢复逻辑
    }
}

水平扩展的最佳实践

容量规划与预测

// 容量规划服务
@Service
public class CapacityPlanningService {
    
    private static final Logger log = LoggerFactory.getLogger(CapacityPlanningService.class);
    
    @Autowired
    private MetricsCollector metricsCollector;
    
    @Autowired
    private PredictionModel predictionModel;
    
    /**
     * 容量规划分析
     */
    public CapacityPlan analyzeCapacityRequirements(CapacityRequest request) {
        log.info("开始容量规划分析,业务场景: {}", request.getScenario());
        
        // 1. 收集历史数据
        HistoricalData historicalData = metricsCollector.collectHistoricalData(
                request.getTimeRange(), request.getMetrics());
        
        // 2. 分析当前容量
        CurrentCapacity currentCapacity = analyzeCurrentCapacity(historicalData);
        
        // 3. 预测未来需求
        FutureDemand predictedDemand = predictionModel.predictFutureDemand(
                historicalData, request.getForecastHorizon());
        
        // 4. 计算容量缺口
        CapacityGap capacityGap = calculateCapacityGap(currentCapacity, predictedDemand);
        
        // 5. 生成容量规划建议
        List<CapacityRecommendation> recommendations = generateRecommendations(capacityGap);
        
        // 6. 创建容量规划
        CapacityPlan plan = new CapacityPlan();
        plan.setScenario(request.getScenario());
        plan.setCurrentCapacity(currentCapacity);
        plan.setPredictedDemand(predictedDemand);
        plan.setCapacityGap(capacityGap);
        plan.setRecommendations(recommendations);
        plan.setConfidenceLevel(calculateConfidenceLevel(historicalData, predictedDemand));
        
        log.info("容量规划分析完成,建议方案数量: {}", recommendations.size());
        
        return plan;
    }
    
    /**
     * 自动扩缩容决策
     */
    public ScalingDecision makeAutoScalingDecision(AutoScalingRequest request) {
        log.info("执行自动扩缩容决策");
        
        // 1. 获取当前指标
        CurrentMetrics currentMetrics = metricsCollector.getCurrentMetrics();
        
        // 2. 评估扩容需求
        ScalingNeed scalingNeed = evaluateScalingNeed(currentMetrics, request.getPolicies());
        
        // 3. 计算扩缩容幅度
        int scalingDelta = calculateScalingDelta(scalingNeed, request.getConstraints());
        
        // 4. 生成决策
        ScalingDecision decision = new ScalingDecision();
        decision.setTimestamp(System.currentTimeMillis());
        decision.setScalingDelta(scalingDelta);
        decision.setConfidence(scalingNeed.getConfidence());
        decision.setReason(scalingNeed.getReason());
        
        // 5. 风险评估
        RiskAssessment risk = assessScalingRisk(scalingDelta, currentMetrics);
        decision.setRiskLevel(risk.getRiskLevel());
        decision.setRiskFactors(risk.getRiskFactors());
        
        log.info("自动扩缩容决策完成,建议调整: {} 实例", scalingDelta);
        
        return decision;
    }
    
    /**
     * 容量预警
     */
    public List<CapacityAlert> checkCapacityAlerts() {
        List<CapacityAlert> alerts = new ArrayList<>();
        
        // 检查各种容量指标
        checkCpuUtilization(alerts);
        checkMemoryUtilization(alerts);
        checkDiskSpace(alerts);
        checkNetworkBandwidth(alerts);
        checkServiceCapacity(alerts);
        
        return alerts;
    }
    
    private CurrentCapacity analyzeCurrentCapacity(HistoricalData data) {
        CurrentCapacity capacity = new CurrentCapacity();
        
        // 分析CPU容量
        capacity.setCpuCapacity(analyzeCpuCapacity(data));
        
        // 分析内存容量
        capacity.setMemoryCapacity(analyzeMemoryCapacity(data));
        
        // 分析存储容量
        capacity.setStorageCapacity(analyzeStorageCapacity(data));
        
        // 分析网络容量
        capacity.setNetworkCapacity(analyzeNetworkCapacity(data));
        
        return capacity;
    }
    
    private CpuCapacity analyzeCpuCapacity(HistoricalData data) {
        CpuCapacity cpuCapacity = new CpuCapacity();
        
        // 计算CPU使用率趋势
        double avgCpuUsage = data.getMetrics().stream()
                .mapToDouble(Metric::getCpuUsage)
                .average()
                .orElse(0.0);
        
        double maxCpuUsage = data.getMetrics().stream()
                .mapToDouble(Metric::getCpuUsage)
                .max()
                .orElse(0.0);
        
        cpuCapacity.setAverageUsage(avgCpuUsage);
        cpuCapacity.setPeakUsage(maxCpuUsage);
        cpuCapacity.setUtilizationRate(avgCpuUsage / 100.0);
        
        return cpuCapacity;
    }
    
    private MemoryCapacity analyzeMemoryCapacity(HistoricalData data) {
        MemoryCapacity memoryCapacity = new MemoryCapacity();
        
        // 计算内存使用率趋势
        double avgMemoryUsage = data.getMetrics().stream()
                .mapToDouble(Metric::getMemoryUsage)
                .average()
                .orElse(0.0);
        
        memoryCapacity.setAverageUsage(avgMemoryUsage);
        memoryCapacity.setUtilizationRate(avgMemoryUsage / 100.0);
        
        return memoryCapacity;
    }
    
    private StorageCapacity analyzeStorageCapacity(HistoricalData data) {
        StorageCapacity storageCapacity = new StorageCapacity();
        
        // 计算存储使用率趋势
        double avgStorageUsage = data.getMetrics().stream()
                .mapToDouble(Metric::getStorageUsage)
                .average()
                .orElse(0.0);
        
        storageCapacity.setAverageUsage(avgStorageUsage);
        storageCapacity.setUtilizationRate(avgStorageUsage / 100.0);
        
        return storageCapacity;
    }
    
    private NetworkCapacity analyzeNetworkCapacity(HistoricalData data) {
        NetworkCapacity networkCapacity = new NetworkCapacity();
        
        // 计算网络带宽使用率趋势
        double avgNetworkUsage = data.getMetrics().stream()
                .mapToDouble(Metric::getNetworkUsage)
                .average()
                .orElse(0.0);
        
        networkCapacity.setAverageUsage(avgNetworkUsage);
        networkCapacity.setUtilizationRate(avgNetworkUsage / 100.0);
        
        return networkCapacity;
    }
    
    private CapacityGap calculateCapacityGap(CurrentCapacity current, FutureDemand predicted) {
        CapacityGap gap = new CapacityGap();
        
        // 计算CPU容量缺口
        double cpuGap = predicted.getCpuDemand() - current.getCpuCapacity().getCapacity();
        gap.setCpuGap(Math.max(0, cpuGap));
        
        // 计算内存容量缺口
        double memoryGap = predicted.getMemoryDemand() - current.getMemoryCapacity().getCapacity();
        gap.setMemoryGap(Math.max(0, memoryGap));
        
        // 计算存储容量缺口
        double storageGap = predicted.getStorageDemand() - current.getStorageCapacity().getCapacity();
        gap.setStorageGap(Math.max(0, storageGap));
        
        // 计算网络容量缺口
        double networkGap = predicted.getNetworkDemand() - current.getNetworkCapacity().getCapacity();
        gap.setNetworkGap(Math.max(0, networkGap));
        
        return gap;
    }
    
    private List<CapacityRecommendation> generateRecommendations(CapacityGap gap) {
        List<CapacityRecommendation> recommendations = new ArrayList<>();
        
        // CPU容量建议
        if (gap.getCpuGap() > 0) {
            recommendations.add(createCpuRecommendation(gap.getCpuGap()));
        }
        
        // 内存容量建议
        if (gap.getMemoryGap() > 0) {
            recommendations.add(createMemoryRecommendation(gap.getMemoryGap()));
        }
        
        // 存储容量建议
        if (gap.getStorageGap() > 0) {
            recommendations.add(createStorageRecommendation(gap.getStorageGap()));
        }
        
        // 网络容量建议
        if (gap.getNetworkGap() > 0) {
            recommendations.add(createNetworkRecommendation(gap.getNetworkGap()));
        }
        
        return recommendations;
    }
    
    private CapacityRecommendation createCpuRecommendation(double gap) {
        CapacityRecommendation recommendation = new CapacityRecommendation();
        recommendation.setResourceType("CPU");
        recommendation.setCurrentCapacity(100); // 假设当前100核
        recommendation.setRecommendedCapacity((int) (100 + gap));
        recommendation.setPriority("HIGH");
        recommendation.setEstimatedCost(gap * 200); // 假设每核200元
        recommendation.setImplementationTimeline("2周");
        
        return recommendation;
    }
    
    private CapacityRecommendation createMemoryRecommendation(double gap) {
        CapacityRecommendation recommendation = new CapacityRecommendation();
        recommendation.setResourceType("Memory");
        recommendation.setCurrentCapacity(512); // 假设当前512GB
        recommendation.setRecommendedCapacity((int) (512 + gap));
        recommendation.setPriority("MEDIUM");
        recommendation.setEstimatedCost(gap * 10); // 假设每GB 10元
        recommendation.setImplementationTimeline("1周");
        
        return recommendation;
    }
    
    private CapacityRecommendation createStorageRecommendation(double gap) {
        CapacityRecommendation recommendation = new CapacityRecommendation();
        recommendation.setResourceType("Storage");
        recommendation.setCurrentCapacity(10000); // 假设当前10TB
        recommendation.setRecommendedCapacity((int) (10000 + gap));
        recommendation.setPriority("LOW");
        recommendation.setEstimatedCost(gap * 0.1); // 假设每GB 0.1元
        recommendation.setImplementationTimeline("3天");
        
        return recommendation;
    }
    
    private CapacityRecommendation createNetworkRecommendation(double gap) {
        CapacityRecommendation recommendation = new CapacityRecommendation();
        recommendation.setResourceType("Network");
        recommendation.setCurrentCapacity(10); // 假设当前10Gbps
        recommendation.setRecommendedCapacity((int) (10 + gap));
        recommendation.setPriority("MEDIUM");
        recommendation.setEstimatedCost(gap * 1000); // 假设每Gbps 1000元
        recommendation.setImplementationTimeline("1周");
        
        return recommendation;
    }
    
    private double calculateConfidenceLevel(HistoricalData historical, FutureDemand predicted) {
        // 基于历史数据的稳定性和预测模型的准确性计算置信度
        return 0.85; // 85%置信度
    }
    
    private ScalingNeed evaluateScalingNeed(CurrentMetrics metrics, List<ScalingPolicy> policies) {
        ScalingNeed need = new ScalingNeed();
        
        for (ScalingPolicy policy : policies) {
            if (policy.isTriggered(metrics)) {
                need.setScalingRequired(true);
                need.setScalingMagnitude(policy.getScalingMagnitude());
                need.setReason(policy.getName() + "触发");
                need.setConfidence(policy.getConfidence());
                break;
            }
        }
        
        return need;
    }
    
    private int calculateScalingDelta(ScalingNeed need, ScalingConstraints constraints) {
        if (!need.isScalingRequired()) {
            return 0;
        }
        
        int delta = need.getScalingMagnitude();
        
        // 应用约束
        delta = Math.max(delta, constraints.getMinScalingStep());
        delta = Math.min(delta, constraints.getMaxScalingStep());
        
        return delta;
    }
    
    private RiskAssessment assessScalingRisk(int scalingDelta, CurrentMetrics currentMetrics) {
        RiskAssessment assessment = new RiskAssessment();
        
        // 评估各种风险因素
        List<String> riskFactors = new ArrayList<>();
        
        if (currentMetrics.getCpuUsage() > 80) {
            riskFactors.add("高CPU使用率");
        }
        
        if (currentMetrics.getMemoryUsage() > 85) {
            riskFactors.add("高内存使用率");
        }
        
        if (Math.abs(scalingDelta) > 5) {
            riskFactors.add("大幅度扩缩容");
        }
        
        assessment.setRiskFactors(riskFactors);
        assessment.setRiskLevel(calculateRiskLevel(riskFactors));
        
        return assessment;
    }
    
    private String calculateRiskLevel(List<String> riskFactors) {
        if (riskFactors.size() >= 3) {
            return "HIGH";
        } else if (riskFactors.size() >= 1) {
            return "MEDIUM";
        } else {
            return "LOW";
        }
    }
    
    private void checkCpuUtilization(List<CapacityAlert> alerts) {
        double cpuUsage = metricsCollector.getCurrentCpuUsage();
        if (cpuUsage > 80) {
            CapacityAlert alert = new CapacityAlert();
            alert.setType("CPU");
            alert.setSeverity("HIGH");
            alert.setMessage("CPU使用率过高: " + cpuUsage + "%");
            alert.setThreshold(80);
            alert.setCurrentValue(cpuUsage);
            alerts.add(alert);
        }
    }
    
    private void checkMemoryUtilization(List<CapacityAlert> alerts) {
        double memoryUsage = metricsCollector.getCurrentMemoryUsage();
        if (memoryUsage > 85) {
            CapacityAlert alert = new CapacityAlert();
            alert.setType("Memory");
            alert.setSeverity("HIGH");
            alert.setMessage("内存使用率过高: " + memoryUsage + "%");
            alert.setThreshold(85);
            alert.setCurrentValue(memoryUsage);
            alerts.add(alert);
        }
    }
    
    private void checkDiskSpace(List<CapacityAlert> alerts) {
        double diskUsage = metricsCollector.getCurrentDiskUsage();
        if (diskUsage > 90) {
            CapacityAlert alert = new CapacityAlert();
            alert.setType("Disk");
            alert.setSeverity("CRITICAL");
            alert.setMessage("磁盘空间不足: " + diskUsage + "%");
            alert.setThreshold(90);
            alert.setCurrentValue(diskUsage);
            alerts.add(alert);
        }
    }
    
    private void checkNetworkBandwidth(List<CapacityAlert> alerts) {
        double networkUsage = metricsCollector.getCurrentNetworkUsage();
        if (networkUsage > 70) {
            CapacityAlert alert = new CapacityAlert();
            alert.setType("Network");
            alert.setSeverity("MEDIUM");
            alert.setMessage("网络带宽使用率过高: " + networkUsage + "%");
            alert.setThreshold(70);
            alert.setCurrentValue(networkUsage);
            alerts.add(alert);
        }
    }
    
    private void checkServiceCapacity(List<CapacityAlert> alerts) {
        double serviceLoad = metricsCollector.getCurrentServiceLoad();
        if (serviceLoad > 85) {
            CapacityAlert alert = new CapacityAlert();
            alert.setType("Service");
            alert.setSeverity("HIGH");
            alert.setMessage("服务负载过高: " + serviceLoad + "%");
            alert.setThreshold(85);
            alert.setCurrentValue(serviceLoad);
            alerts.add(alert);
        }
    }
}

// 相关数据结构
@Data
public class CapacityRequest {
    private String scenario;
    private TimeRange timeRange;
    private List<String> metrics;
    private int forecastHorizon; // 预测时间范围(天)
}

@Data
public class CapacityPlan {
    private String scenario;
    private CurrentCapacity currentCapacity;
    private FutureDemand predictedDemand;
    private CapacityGap capacityGap;
    private List<CapacityRecommendation> recommendations;
    private double confidenceLevel;
}

@Data
public class CurrentCapacity {
    private CpuCapacity cpuCapacity;
    private MemoryCapacity memoryCapacity;
    private StorageCapacity storageCapacity;
    private NetworkCapacity networkCapacity;
}

@Data
public class FutureDemand {
    private double cpuDemand;
    private double memoryDemand;
    private double storageDemand;
    private double networkDemand;
    private LocalDateTime predictionTime;
}

@Data
public class CapacityGap {
    private double cpuGap;
    private double memoryGap;
    private double storageGap;
    private double networkGap;
}

@Data
public class CapacityRecommendation {
    private String resourceType;
    private int currentCapacity;
    private int recommendedCapacity;
    private String priority;
    private double estimatedCost;
    private String implementationTimeline;
}

@Data
public class AutoScalingRequest {
    private List<ScalingPolicy> policies;
    private ScalingConstraints constraints;
    private int evaluationWindow; // 评估窗口(分钟)
}

@Data
public class ScalingDecision {
    private long timestamp;
    private int scalingDelta;
    private double confidence;
    private String reason;
    private String riskLevel;
    private List<String> riskFactors;
}

@Data
public class CapacityAlert {
    private String type;
    private String severity;
    private String message;
    private double threshold;
    private double currentValue;
    private LocalDateTime timestamp;
}

@Data
public class ScalingNeed {
    private boolean scalingRequired;
    private int scalingMagnitude;
    private String reason;
    private double confidence;
}

@Data
public class RiskAssessment {
    private String riskLevel;
    private List<String> riskFactors;
}

总结

水平扩展架构法则是现代分布式系统设计的核心原则,它通过增加服务器数量来实现系统性能的线性扩展,突破了单节点的物理极限。然而,水平扩展并非简单的"加机器",它需要在架构的各个层次进行精心设计:

核心原则

  1. 分层扩展:在数据库层、缓存层、服务层分别实现水平扩展
  2. 数据分片:通过合理的分片策略实现数据的分布式存储
  3. 负载均衡:确保请求在各个节点间均匀分布
  4. 故障容错:具备节点故障的自动检测和处理能力
  5. 渐进演进:采用渐进式策略,避免大爆炸式改造

关键技术

  1. 数据库水平扩展:数据分片、读写分离、分布式事务
  2. Redis水平扩展:Redis Cluster、自动故障转移、在线扩容
  3. 服务层水平扩展:微服务架构、服务发现、负载均衡、熔断降级
  4. 容器化编排:Docker、Kubernetes、自动扩缩容
  5. 数据一致性:最终一致性、分布式事务、补偿机制

关键挑战

  1. 数据一致性:分布式环境下的数据一致性保证
  2. 网络延迟:服务间调用带来的网络开销
  3. 运维复杂度:分布式系统的运维管理复杂性
  4. 成本控制:平衡扩展需求与成本投入
  5. 技术选型:选择合适的分布式技术和工具

水平扩展架构的核心在于:通过合理的架构设计,将系统负载分散到多个节点上,实现性能的线性扩展,同时保证系统的高可用性和数据一致性。这需要架构师具备深厚的技术功底和丰富的实践经验,能够在性能、成本、复杂度之间找到最佳平衡点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值