架构评审:构建稳定、高效、可扩展的技术架构(下)

发布于:2025-08-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

图片来源网络,侵权联系删

以下架构评审根据的实际经验梳理的一份清单,希望能够对你有所帮助。

在这里插入图片描述

架构评审:构建稳定、高效、可扩展的技术架构(上)

6. 弹性处理:应对异常,保障系统稳定

弹性处理是架构评审中不可或缺的一环。

  • 通过消息队列的幂等性设计,确保了消息重复消费与接口重复调用时业务的正确性。
  • 同时,引入了服务降级机制,对于非核心业务,在系统负载过高时自动降级,优先保障核心业务的正常运行。

例如,在支付接口出现故障时,自动切换至备用支付渠道,并向用户展示友好的提示信息,确保交易流程的顺畅进行。

  • 还实现了服务的超时熔断、异常熔断与限流熔断功能,当某个服务出现故障或响应时间过长时,熔断机制会自动触发,阻止故障的进一步扩散。熔断后,通过隔离故障服务,确保单一服务故障不会影响全局系统的稳定运行。

架构示例图

消息队列
备用服务
非核心服务
核心服务
API网关
客户端
消息队列
消息处理器
备用服务
备用服务1
备用服务2
非核心服务
服务3
服务4
核心服务
服务1
服务2
API网关
限流器
熔断器
客户端

架构示例代码

// 弹性处理系统实现
public class ResilientSystem {
    
    // 熔断器状态
    public enum CircuitState {
        CLOSED,    // 关闭状态,正常调用
        OPEN,      // 开启状态,直接返回错误
        HALF_OPEN  // 半开状态,尝试恢复
    }
    
    // 熔断器实现
    public static class CircuitBreaker {
        private CircuitState state;
        private int failureCount;
        private int failureThreshold;
        private long timeout;
        private long lastFailureTime;
        
        public CircuitBreaker(int failureThreshold, long timeout) {
            this.state = CircuitState.CLOSED;
            this.failureCount = 0;
            this.failureThreshold = failureThreshold;
            this.timeout = timeout;
            this.lastFailureTime = 0;
        }
        
        public synchronized boolean allowRequest() {
            if (state == CircuitState.OPEN) {
                // 检查是否超时,可以尝试半开状态
                if (System.currentTimeMillis() - lastFailureTime > timeout) {
                    state = CircuitState.HALF_OPEN;
                    return true;
                }
                return false;
            }
            return true;
        }
        
        public synchronized void recordSuccess() {
            if (state == CircuitState.HALF_OPEN) {
                state = CircuitState.CLOSED;
                failureCount = 0;
            }
        }
        
        public synchronized void recordFailure() {
            failureCount++;
            lastFailureTime = System.currentTimeMillis();
            
            if (failureCount >= failureThreshold) {
                state = CircuitState.OPEN;
            }
        }
        
        public CircuitState getState() {
            return state;
        }
    }
    
    // 限流器实现
    public static class RateLimiter {
        private int maxRequests;
        private long windowSize;
        private Deque<Long> requestTimestamps;
        
        public RateLimiter(int maxRequests, long windowSize) {
            this.maxRequests = maxRequests;
            this.windowSize = windowSize;
            this.requestTimestamps = new ArrayDeque<>();
        }
        
        public synchronized boolean allowRequest() {
            long currentTime = System.currentTimeMillis();
            
            // 移除过期的请求时间戳
            while (!requestTimestamps.isEmpty() && 
                   currentTime - requestTimestamps.peekFirst() > windowSize) {
                requestTimestamps.pollFirst();
            }
            
            // 检查是否超过限制
            if (requestTimestamps.size() >= maxRequests) {
                return false;
            }
            
            // 记录当前请求时间戳
            requestTimestamps.addLast(currentTime);
            return true;
        }
    }
    
    // 服务降级处理器
    public static class ServiceDegradationHandler {
        private Map<String, Boolean> serviceStates;
        private Map<String, Runnable> fallbackHandlers;
        
        public ServiceDegradationHandler() {
            this.serviceStates = new ConcurrentHashMap<>();
            this.fallbackHandlers = new ConcurrentHashMap<>();
        }
        
        public void registerService(String serviceName, Runnable fallbackHandler) {
            serviceStates.put(serviceName, true); // 默认服务正常
            fallbackHandlers.put(serviceName, fallbackHandler);
        }
        
        public void markServiceDown(String serviceName) {
            serviceStates.put(serviceName, false);
        }
        
        public void markServiceUp(String serviceName) {
            serviceStates.put(serviceName, true);
        }
        
        public Object handleRequest(String serviceName, Supplier<Object> serviceCall) {
            if (!isServiceAvailable(serviceName)) {
                System.out.println("服务 " + serviceName + " 不可用,执行降级处理");
                return fallbackHandlers.get(serviceName).run();
            }
            
            try {
                return serviceCall.get();
            } catch (Exception e) {
                System.out.println("服务 " + serviceName + " 调用失败,执行降级处理: " + e.getMessage());
                return fallbackHandlers.get(serviceName).run();
            }
        }
        
        private boolean isServiceAvailable(String serviceName) {
            return serviceStates.getOrDefault(serviceName, false);
        }
    }
    
    // 幂等消息处理器
    public static class IdempotentMessageProcessor {
        private Set<String> processedMessages;
        private MessageQueue messageQueue;
        
        public IdempotentMessageProcessor(MessageQueue messageQueue) {
            this.processedMessages = ConcurrentHashMap.newKeySet();
            this.messageQueue = messageQueue;
        }
        
        public void processMessage(Message message) {
            // 检查消息是否已处理
            if (processedMessages.contains(message.getId())) {
                System.out.println("消息 " + message.getId() + " 已处理,跳过");
                return;
            }
            
            try {
                // 处理消息
                System.out.println("处理消息: " + message.getId());
                // 模拟处理逻辑
                Thread.sleep(100);
                
                // 标记消息为已处理
                processedMessages.add(message.getId());
                
                // 模拟处理成功,从队列中移除
                messageQueue.ackMessage(message.getId());
            } catch (Exception e) {
                System.out.println("处理消息失败: " + e.getMessage());
                // 模拟重试
                messageQueue.retryMessage(message);
            }
        }
    }
    
    // 消息队列
    public static class MessageQueue {
        private BlockingQueue<Message> queue;
        private Map<String, Message> pendingMessages;
        
        public MessageQueue() {
            this.queue = new LinkedBlockingQueue<>();
            this.pendingMessages = new ConcurrentHashMap<>();
        }
        
        public void enqueue(Message message) {
            queue.add(message);
            pendingMessages.put(message.getId(), message);
        }
        
        public Message dequeue() throws InterruptedException {
            return queue.take();
        }
        
        public void ackMessage(String messageId) {
            pendingMessages.remove(messageId);
        }
        
        public void retryMessage(Message message) {
            // 模拟重试逻辑
            System.out.println("重试消息: " + message.getId());
            enqueue(message);
        }
        
        public int getPendingCount() {
            return pendingMessages.size();
        }
    }
    
    // 消息实体
    public static class Message {
        private String id;
        private String content;
        
        public Message(String id, String content) {
            this.id = id;
            this.content = content;
        }
        
        public String getId() {
            return id;
        }
        
        public String getContent() {
            return content;
        }
    }
    
    // 服务接口
    public interface Service {
        Object call() throws Exception;
    }
    
    // 核心服务实现
    public static class CoreService implements Service {
        @Override
        public Object call() throws Exception {
            // 模拟核心服务调用
            Thread.sleep(50);
            return "核心服务响应";
        }
    }
    
    // 非核心服务实现
    public static class NonCoreService implements Service {
        @Override
        public Object call() throws Exception {
            // 模拟非核心服务调用
            Thread.sleep(100);
            return "非核心服务响应";
        }
    }
    
    // 备用服务实现
    public static class BackupService implements Service {
        @Override
        public Object call() throws Exception {
            // 模拟备用服务调用
            Thread.sleep(30);
            return "备用服务响应";
        }
    }
    
    // 客户端
    public static class Client {
        private CircuitBreaker circuitBreaker;
        private RateLimiter rateLimiter;
        private ServiceDegradationHandler degradationHandler;
        
        public Client(CircuitBreaker circuitBreaker, RateLimiter rateLimiter, 
                     ServiceDegradationHandler degradationHandler) {
            this.circuitBreaker = circuitBreaker;
            this.rateLimiter = rateLimiter;
            this.degradationHandler = degradationHandler;
        }
        
        public Object requestService(String serviceName, Service service) {
            // 检查熔断器状态
            if (!circuitBreaker.allowRequest()) {
                System.out.println("熔断器开启,请求被拒绝");
                return "服务不可用,请稍后再试";
            }
            
            // 检查限流
            if (!rateLimiter.allowRequest()) {
                System.out.println("请求被限流");
                return "请求过于频繁,请稍后再试";
            }
            
            try {
                // 调用服务
                Object result = degradationHandler.handleRequest(serviceName, service::call);
                
                // 记录成功
                circuitBreaker.recordSuccess();
                return result;
            } catch (Exception e) {
                // 记录失败
                circuitBreaker.recordFailure();
                throw e;
            }
        }
    }
    
    // 主方法 - 演示弹性处理系统
    public static void main(String[] args) throws InterruptedException {
        // 创建熔断器(失败阈值5次,超时时间5000毫秒)
        CircuitBreaker circuitBreaker = new CircuitBreaker(5, 5000);
        
        // 创建限流器(每秒最多10个请求)
        RateLimiter rateLimiter = new RateLimiter(10, 1000);
        
        // 创建服务降级处理器
        ServiceDegradationHandler degradationHandler = new ServiceDegradationHandler();
        
        // 注册服务和降级处理器
        degradationHandler.registerService("core-service", () -> {
            System.out.println("核心服务降级处理");
            return "核心服务降级响应";
        });
        
        degradationHandler.registerService("non-core-service", () -> {
            System.out.println("非核心服务降级处理");
            return "非核心服务降级响应";
        });
        
        degradationHandler.registerService("payment-service", () -> {
            System.out.println("支付服务降级处理 - 使用备用支付渠道");
            return "备用支付渠道响应";
        });
        
        // 创建客户端
        Client client = new Client(circuitBreaker, rateLimiter, degradationHandler);
        
        // 创建消息队列和处理器
        MessageQueue messageQueue = new MessageQueue();
        IdempotentMessageProcessor messageProcessor = new IdempotentMessageProcessor(messageQueue);
        
        // 模拟消息处理
        for (int i = 1; i <= 10; i++) {
            messageQueue.enqueue(new Message("msg-" + i, "消息内容 " + i));
        }
        
        // 启动消息处理线程
        new Thread(() -> {
            try {
                while (true) {
                    Message message = messageQueue.dequeue();
                    messageProcessor.processMessage(message);
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
        
        // 模拟正常请求
        System.out.println("\n=== 正常请求测试 ===");
        for (int i = 0; i < 5; i++) {
            Object result = client.requestService("core-service", new CoreService());
            System.out.println("响应: " + result);
            Thread.sleep(100);
        }
        
        // 模拟服务故障
        System.out.println("\n=== 服务故障测试 ===");
        // 标记核心服务为不可用
        degradationHandler.markServiceDown("core-service");
        
        for (int i = 0; i < 5; i++) {
            Object result = client.requestService("core-service", new CoreService());
            System.out.println("响应: " + result);
            Thread.sleep(100);
        }
        
        // 模拟非核心服务请求
        System.out.println("\n=== 非核心服务请求测试 ===");
        for (int i = 0; i < 5; i++) {
            Object result = client.requestService("non-core-service", new NonCoreService());
            System.out.println("响应: " + result);
            Thread.sleep(100);
        }
        
        // 模拟限流
        System.out.println("\n=== 限流测试 ===");
        for (int i = 0; i < 15; i++) {
            Object result = client.requestService("core-service", new CoreService());
            System.out.println("响应: " + result);
            Thread.sleep(50);
        }
        
        // 模拟熔断
        System.out.println("\n=== 熔断测试 ===");
        // 模拟连续失败触发熔断
        for (int i = 0; i < 10; i++) {
            try {
                Object result = client.requestService("core-service", () -> {
                    throw new RuntimeException("模拟服务故障");
                });
                System.out.println("响应: " + result);
            } catch (Exception e) {
                System.out.println("异常: " + e.getMessage());
            }
            Thread.sleep(100);
        }
        
        // 检查熔断器状态
        System.out.println("熔断器状态: " + circuitBreaker.getState());
        
        // 模拟熔断恢复
        System.out.println("\n=== 熔断恢复测试 ===");
        Thread.sleep(6000); // 等待超时
        
        for (int i = 0; i < 3; i++) {
            Object result = client.requestService("core-service", new CoreService());
            System.out.println("响应: " + result);
            Thread.sleep(100);
        }
        
        // 检查最终消息处理状态
        System.out.println("\n=== 消息处理状态 ===");
        System.out.println("待处理消息数: " + messageQueue.getPendingCount());
    }
}

7. 兼容性:确保系统协同,降低升级成本

对上下游系统进行了全面梳理,明确了各系统的依赖关系与影响范围。
在这里插入图片描述

  • 在新老系统替换过程中,采用了灰度发布策略,先将新系统与老系统并行运行,逐步将流量切换至新系统,确保新老系统能够来回切换,降低切换风险。

  • 同时,对数据存储进行了兼容性设计,使得新系统能够兼容老数据的读取与处理。

  • 在对上下游系统有影响的升级过程中,提前与相关业务方进行沟通,制定了详细的升级方案,通过批量处理、数据迁移等手段,将升级成本降至最低。

例如,在一次数据库升级过程中,通过在线热迁移技术,将数据从旧数据库平滑迁移到新数据库,整个过程对业务无任何影响。

架构示例图

数据迁移
灰度发布控制
兼容层
新系统
老系统
数据迁移
增量迁移
全量迁移
灰度发布控制
流量分配
监控
兼容层
API适配器
数据适配器
新系统
新数据库
老系统
旧数据库

架构示例代码

// 兼容性系统实现
public class CompatibilitySystem {
    
    // 系统版本枚举
    public enum SystemVersion {
        V1,  // 老版本
        V2   // 新版本
    }
    
    // 数据模型
    public static class DataModel {
        private String id;
        private String name;
        private Map<String, Object> attributes;
        
        public DataModel(String id, String name) {
            this.id = id;
            this.name = name;
            this.attributes = new HashMap<>();
        }
        
        public String getId() { return id; }
        public String getName() { return name; }
        public Map<String, Object> getAttributes() { return attributes; }
        
        public void addAttribute(String key, Object value) {
            attributes.put(key, value);
        }
    }
    
    // 数据存储接口
    public interface DataStorage {
        DataModel getData(String id);
        void saveData(DataModel data);
    }
    
    // 旧版数据存储
    public static class V1DataStorage implements DataStorage {
        private Map<String, DataModel> storage;
        
        public V1DataStorage() {
            this.storage = new HashMap<>();
            // 初始化一些测试数据
            DataModel user1 = new DataModel("user1", "张三");
            user1.addAttribute("age", 30);
            user1.addAttribute("email", "zhangsan@example.com");
            storage.put("user1", user1);
            
            DataModel user2 = new DataModel("user2", "李四");
            user2.addAttribute("age", 25);
            user2.addAttribute("email", "lisi@example.com");
            storage.put("user2", user2);
        }
        
        @Override
        public DataModel getData(String id) {
            System.out.println("从V1数据存储获取数据: " + id);
            return storage.get(id);
        }
        
        @Override
        public void saveData(DataModel data) {
            System.out.println("保存数据到V1数据存储: " + data.getId());
            storage.put(data.getId(), data);
        }
    }
    
    // 新版数据存储
    public static class V2DataStorage implements DataStorage {
        private Map<String, DataModel> storage;
        
        public V2DataStorage() {
            this.storage = new HashMap<>();
            // 新版数据模型包含更多字段
            DataModel user1 = new DataModel("user1", "张三");
            user1.addAttribute("age", 30);
            user1.addAttribute("email", "zhangsan@example.com");
            user1.addAttribute("phone", "13800138000");
            user1.addAttribute("address", "北京市海淀区");
            storage.put("user1", user1);
            
            DataModel user2 = new DataModel("user2", "李四");
            user2.addAttribute("age", 25);
            user2.addAttribute("email", "lisi@example.com");
            user2.addAttribute("phone", "13900139000");
            user2.addAttribute("address", "上海市浦东新区");
            storage.put("user2", user2);
        }
        
        @Override
        public DataModel getData(String id) {
            System.out.println("从V2数据存储获取数据: " + id);
            return storage.get(id);
        }
        
        @Override
        public void saveData(DataModel data) {
            System.out.println("保存数据到V2数据存储: " + data.getId());
            storage.put(data.getId(), data);
        }
    }
    
    // 兼容层
    public static class CompatibilityLayer {
        private DataStorage v1Storage;
        private DataStorage v2Storage;
        private SystemVersion currentVersion;
        
        public CompatibilityLayer(DataStorage v1Storage, DataStorage v2Storage) {
            this.v1Storage = v1Storage;
            this.v2Storage = v2Storage;
            this.currentVersion = SystemVersion.V1; // 初始使用V1
        }
        
        public void switchVersion(SystemVersion version) {
            this.currentVersion = version;
            System.out.println("系统切换到版本: " + version);
        }
        
        public DataModel getData(String id) {
            // 根据当前版本决定从哪个存储获取数据
            if (currentVersion == SystemVersion.V1) {
                return v1Storage.getData(id);
            } else {
                return v2Storage.getData(id);
            }
        }
        
        public void saveData(DataModel data) {
            // 根据当前版本决定保存到哪个存储
            if (currentVersion == SystemVersion.V1) {
                // 新数据保存时需要兼容旧格式
                DataModel compatibleData = convertToV1Format(data);
                v1Storage.saveData(compatibleData);
            } else {
                v2Storage.saveData(data);
            }
        }
        
        private DataModel convertToV1Format(DataModel data) {
            // 将新格式数据转换为旧格式
            DataModel v1Data = new DataModel(data.getId(), data.getName());
            v1Data.addAttribute("age", data.getAttributes().get("age"));
            v1Data.addAttribute("email", data.getAttributes().get("email"));
            return v1Data;
        }
    }
    
    // 灰度发布控制器
    public static class GrayReleaseController {
        private double v1TrafficRatio;
        private double v2TrafficRatio;
        private Random random;
        
        public GrayReleaseController() {
            this.v1TrafficRatio = 1.0; // 初始全部流量到V1
            this.v2TrafficRatio = 0.0;
            this.random = new Random();
        }
        
        public void setTrafficRatio(double v1Ratio, double v2Ratio) {
            this.v1TrafficRatio = v1Ratio;
            this.v2TrafficRatio = v2Ratio;
            System.out.println("设置流量比例: V1=" + (v1Ratio * 100) + "%, V2=" + (v2Ratio * 100) + "%");
        }
        
        public SystemVersion determineVersion() {
            double value = random.nextDouble();
            if (value < v1TrafficRatio) {
                return SystemVersion.V1;
            } else {
                return SystemVersion.V2;
            }
        }
        
        public void graduallyShiftTraffic(int steps, int delayMs) throws InterruptedException {
            double stepSize = 0.1 / steps;
            
            for (int i = 0; i < steps; i++) {
                v1TrafficRatio -= stepSize;
                v2TrafficRatio += stepSize;
                
                System.out.println("第 " + (i + 1) + " 步: V1=" + (v1TrafficRatio * 100) + 
                                 "%, V2=" + (v2TrafficRatio * 100) + "%");
                
                Thread.sleep(delayMs);
            }
        }
    }
    
    // 数据迁移服务
    public static class DataMigrationService {
        private V1DataStorage v1Storage;
        private V2DataStorage v2Storage;
        
        public DataMigrationService(V1DataStorage v1Storage, V2DataStorage v2Storage) {
            this.v1Storage = v1Storage;
            this.v2Storage = v2Storage;
        }
        
        public void migrateData() {
            System.out.println("开始数据迁移...");
            
            // 获取所有V1数据
            for (String id : v1Storage.getStorage().keySet()) {
                DataModel v1Data = v1Storage.getData(id);
                
                // 转换为V2格式
                DataModel v2Data = convertToV2Format(v1Data);
                
                // 保存到V2存储
                v2Storage.saveData(v2Data);
                
                System.out.println("迁移数据: " + id);
            }
            
            System.out.println("数据迁移完成");
        }
        
        private DataModel convertToV2Format(DataModel v1Data) {
            // 将旧格式数据转换为新格式
            DataModel v2Data = new DataModel(v1Data.getId(), v1Data.getName());
            v2Data.addAttribute("age", v1Data.getAttributes().get("age"));
            v2Data.addAttribute("email", v1Data.getAttributes().get("email"));
            
            // 添加新字段(默认值)
            if (!v2Data.getAttributes().containsKey("phone")) {
                v2Data.addAttribute("phone", "未提供");
            }
            if (!v2Data.getAttributes().containsKey("address")) {
                v2Data.addAttribute("address", "未提供");
            }
            
            return v2Data;
        }
    }
    
    // API适配器
    public static class ApiAdapter {
        private CompatibilityLayer compatibilityLayer;
        private GrayReleaseController grayReleaseController;
        
        public ApiAdapter(CompatibilityLayer compatibilityLayer, 
                         GrayReleaseController grayReleaseController) {
            this.compatibilityLayer = compatibilityLayer;
            this.grayReleaseController = grayReleaseController;
        }
        
        public Object handleRequest(String requestId, String action, Map<String, Object> params) {
            // 根据灰度发布策略决定使用哪个版本
            SystemVersion version = grayReleaseController.determineVersion();
            
            System.out.println("请求 " + requestId + " 将由 " + version + " 处理");
            
            try {
                if ("getUser".equals(action)) {
                    String userId = (String) params.get("userId");
                    DataModel user = compatibilityLayer.getData(userId);
                    return user;
                } else if ("saveUser".equals(action)) {
                    String userId = (String) params.get("userId");
                    String name = (String) params.get("name");
                    int age = (Integer) params.get("age");
                    String email = (String) params.get("email");
                    
                    DataModel user = new DataModel(userId, name);
                    user.addAttribute("age", age);
                    user.addAttribute("email", email);
                    
                    compatibilityLayer.saveData(user);
                    return "用户保存成功";
                }
                
                return "未知操作";
            } catch (Exception e) {
                return "处理请求失败: " + e.getMessage();
            }
        }
    }
    
    // 主方法 - 演示兼容性系统
    public static void main(String[] args) throws InterruptedException {
        // 创建数据存储
        V1DataStorage v1Storage = new V1DataStorage();
        V2DataStorage v2Storage = new V2DataStorage();
        
        // 创建兼容层
        CompatibilityLayer compatibilityLayer = new CompatibilityLayer(v1Storage, v2Storage);
        
        // 创建灰度发布控制器
        GrayReleaseController grayReleaseController = new GrayReleaseController();
        
        // 创建数据迁移服务
        DataMigrationService migrationService = new DataMigrationService(v1Storage, v2Storage);
        
        // 创建API适配器
        ApiAdapter apiAdapter = new ApiAdapter(compatibilityLayer, grayReleaseController);
        
        // 测试初始状态(全部使用V1)
        System.out.println("=== 初始状态测试(全部使用V1) ===");
        Object result1 = apiAdapter.handleRequest("req1", "getUser", Map.of("userId", "user1"));
        System.out.println("响应: " + result1);
        
        // 执行数据迁移
        System.out.println("\n=== 数据迁移测试 ===");
        migrationService.migrateData();
        
        // 测试灰度发布
        System.out.println("\n=== 灰度发布测试 ===");
        
        // 初始状态:100% V1
        grayReleaseController.setTrafficRatio(1.0, 0.0);
        for (int i = 0; i < 5; i++) {
            Object result = apiAdapter.handleRequest("req" + i, "getUser", Map.of("userId", "user1"));
            System.out.println("响应: " + result);
        }
        
        // 逐步切换流量到V2
        System.out.println("\n逐步切换流量到V2...");
        grayReleaseController.graduallyShiftTraffic(5, 1000);
        
        // 测试新版本
        System.out.println("\n=== 新版本测试 ===");
        grayReleaseController.setTrafficRatio(0.0, 1.0);
        for (int i = 0; i < 5; i++) {
            Object result = apiAdapter.handleRequest("req" + i, "getUser", Map.of("userId", "user1"));
            System.out.println("响应: " + result);
        }
        
        // 测试数据保存(兼容性)
        System.out.println("\n=== 数据保存兼容性测试 ===");
        Object saveResult = apiAdapter.handleRequest("saveReq", "saveUser", 
            Map.of("userId", "user3", "name", "王五", "age", 28, "email", "wangwu@example.com"));
        System.out.println("响应: " + saveResult);
        
        // 验证数据保存后的兼容性
        Object getResult = apiAdapter.handleRequest("getReq", "getUser", Map.of("userId", "user3"));
        System.out.println("获取保存的数据: " + getResult);
        
        // 测试版本切换
        System.out.println("\n=== 版本切换测试 ===");
        compatibilityLayer.switchVersion(SystemVersion.V2);
        Object getResultV2 = apiAdapter.handleRequest("getReqV2", "getUser", Map.of("userId", "user1"));
        System.out.println("V2版本获取数据: " + getResultV2);
        
        compatibilityLayer.switchVersion(SystemVersion.V1);
        Object getResultV1 = apiAdapter.handleRequest("getReqV1", "getUser", Map.of("userId", "user1"));
        System.out.println("V1版本获取数据: " + getResultV1);
    }
}

8. 安全性:筑牢防线,守护数据资产

安全性是架构评审中的重中之重。从多个层面构建了安全防护体系。

  • 在代码层面,严格执行SQL注入与XSS攻击的防范措施,对用户输入进行严格的过滤与验证。

  • 在数据层面,实施了数据加密存储与传输,确保数据在各个环节的安全性。

  • 在接口层面,引入了防刷保护机制,通过限流、验证码等手段,防止恶意攻击。

  • 在权限控制方面,建立了精细的访问控制策略,对数据与功能权限进行严格限制,确保只有授权用户能够访问敏感信息。

  • 还对后台运营系统进行了日志审计,记录所有操作行为,以便在发生安全事件时能够快速追溯与定位。

通过这些安全措施,有效地降低了数据泄露与系统被攻击的风险,守护了公司的数据资产。

架构示例图

日志审计
数据层
业务服务
认证授权
安全网关
客户端
日志审计
ELK日志系统
数据库
数据加密
业务服务
权限中间件
认证授权
认证服务
授权服务
令牌管理
安全网关
请求限流
验证码
Web应用防火墙
客户端

架构示例代码

// 安全系统实现
public class SecuritySystem {
    
    // SQL注入防护
    public static class SqlInjectionProtection {
        private static final String[] SQL_INJECTION_PATTERNS = {
            "SELECT", "INSERT", "UPDATE", "DELETE", "DROP", "UNION", 
            "EXEC", "EXECUTE", "xp_", "--", "/*", "*/", ";"
        };
        
        public static String sanitizeInput(String input) {
            if (input == null) {
                return null;
            }
            
            String sanitized = input;
            
            // 移除潜在的SQL注入字符
            for (String pattern : SQL_INJECTION_PATTERNS) {
                sanitized = sanitized.replaceAll("(?i)" + pattern, "");
            }
            
            // 使用预编译语句参数化查询
            return sanitized;
        }
        
        public static PreparedStatement createPreparedStatement(Connection conn, String sql, Object... params) 
            throws SQLException {
            // 使用预编译语句防止SQL注入
            PreparedStatement stmt = conn.prepareStatement(sql);
            
            for (int i = 0; i < params.length; i++) {
                stmt.setObject(i + 1, params[i]);
            }
            
            return stmt;
        }
    }
    
    // XSS防护
    public static class XssProtection {
        private static final String[] XSS_PATTERNS = {
            "<script", "</script>", "javascript:", "onload=", "onerror=", 
            "onfocus=", "onblur=", "onclick=", "onmouseover=", "onchange="
        };
        
        public static String sanitizeHtml(String input) {
            if (input == null) {
                return null;
            }
            
            String sanitized = input;
            
            // 移除潜在的XSS字符
            for (String pattern : XSS_PATTERNS) {
                sanitized = sanitized.replaceAll("(?i)" + pattern, "");
            }
            
            // HTML转义
            sanitized = sanitized.replace("&", "&amp;")
                                .replace("<", "&lt;")
                                .replace(">", "&gt;")
                                .replace("\"", "&quot;")
                                .replace("'", "&apos;");
            
            return sanitized;
        }
    }
    
    // 数据加密
    public static class DataEncryption {
        private static final String ALGORITHM = "AES";
        private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
        private static final String SECRET_KEY = "ThisIsASecretKey123";
        private static final String IV = "ThisIsAnInitVec";
        
        public static String encrypt(String data) throws Exception {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
            
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
            
            byte[] encrypted = cipher.doFinal(data.getBytes());
            return Base64.getEncoder().encodeToString(encrypted);
        }
        
        public static String decrypt(String encryptedData) throws Exception {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
            
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
            
            byte[] decoded = Base64.getDecoder().decode(encryptedData);
            byte[] decrypted = cipher.doFinal(decoded);
            
            return new String(decrypted);
        }
    }
    
    // 请求限流
    public static class RequestRateLimiter {
        private Map<String, Deque<Long>> userRequests;
        private int maxRequests;
        private long windowSize;
        
        public RequestRateLimiter(int maxRequests, long windowSize) {
            this.userRequests = new ConcurrentHashMap<>();
            this.maxRequests = maxRequests;
            this.windowSize = windowSize;
        }
        
        public boolean allowRequest(String userId) {
            Deque<Long> requests = userRequests.computeIfAbsent(userId, k -> new ArrayDeque<>());
            long currentTime = System.currentTimeMillis();
            
            // 移除过期的请求
            while (!requests.isEmpty() && currentTime - requests.peekFirst() > windowSize) {
                requests.pollFirst();
            }
            
            // 检查是否超过限制
            if (requests.size() >= maxRequests) {
                return false;
            }
            
            // 记录当前请求
            requests.addLast(currentTime);
            return true;
        }
    }
    
    // 验证码生成器
    public static class CaptchaGenerator {
        private static final String CHARACTERS = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789";
        private static final int CAPTCHA_LENGTH = 6;
        
        public static String generateCaptcha() {
            Random random = new Random();
            StringBuilder captcha = new StringBuilder(CAPTCHA_LENGTH);
            
            for (int i = 0; i < CAPTCHA_LENGTH; i++) {
                captcha.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length())));
            }
            
            return captcha.toString();
        }
        
        public static boolean verifyCaptcha(String inputCaptcha, String storedCaptcha) {
            return inputCaptcha != null && inputCaptcha.equalsIgnoreCase(storedCaptcha);
        }
    }
    
    // 认证服务
    public static class AuthenticationService {
        private Map<String, String> userCredentials;
        private Map<String, String> userTokens;
        
        public AuthenticationService() {
            this.userCredentials = new ConcurrentHashMap<>();
            this.userTokens = new ConcurrentHashMap<>();
            
            // 初始化测试用户
            userCredentials.put("admin", "admin123");
            userCredentials.put("user1", "password1");
        }
        
        public String login(String username, String password) {
            if (userCredentials.containsKey(username) && 
                userCredentials.get(username).equals(password)) {
                
                // 生成令牌
                String token = UUID.randomUUID().toString();
                userTokens.put(token, username);
                
                System.out.println("用户 " + username + " 登录成功");
                return token;
            }
            
            System.out.println("用户 " + username + " 登录失败");
            return null;
        }
        
        public boolean verifyToken(String token) {
            return userTokens.containsKey(token);
        }
        
        public String getUsernameByToken(String token) {
            return userTokens.get(token);
        }
        
        public void logout(String token) {
            userTokens.remove(token);
            System.out.println("用户已登出");
        }
    }
    
    // 授权服务
    public static class AuthorizationService {
        private Map<String, Set<String>> userPermissions;
        
        public AuthorizationService() {
            this.userPermissions = new ConcurrentHashMap<>();
            
            // 初始化用户权限
            Set<String> adminPermissions = new HashSet<>();
            adminPermissions.add("user:create");
            adminPermissions.add("user:read");
            adminPermissions.add("user:update");
            adminPermissions.add("user:delete");
            adminPermissions.add("system:admin");
            userPermissions.put("admin", adminPermissions);
            
            Set<String> userPermissions = new HashSet<>();
            userPermissions.add("user:read");
            userPermissions.add("user:update:own");
            userPermissions.add("order:create");
            userPermissions.add("order:read");
            userPermissions.add("order:update:own");
            userPermissions.add("order:delete:own");
            userPermissions.put("user1", userPermissions);
        }
        
        public boolean hasPermission(String username, String permission) {
            Set<String> permissions = userPermissions.get(username);
            return permissions != null && permissions.contains(permission);
        }
        
        public boolean hasAnyPermission(String username, String... permissions) {
            Set<String> userPerms = userPermissions.get(username);
            if (userPerms == null) {
                return false;
            }
            
            for (String permission : permissions) {
                if (userPerms.contains(permission)) {
                    return true;
                }
            }
            
            return false;
        }
        
        public boolean hasAllPermissions(String username, String... permissions) {
            Set<String> userPerms = userPermissions.get(username);
            if (userPerms == null) {
                return false;
            }
            
            for (String permission : permissions) {
                if (!userPerms.contains(permission)) {
                    return false;
                }
            }
            
            return true;
        }
    }
    
    // 日志审计
    public static class AuditLogger {
        private List<AuditLog> logs;
        
        public AuditLogger() {
            this.logs = new CopyOnWriteArrayList<>();
        }
        
        public void log(String username, String action, String resource, String details) {
            AuditLog log = new AuditLog(
                username,
                action,
                resource,
                details,
                new Date(),
                InetAddress.getLoopbackAddress().getHostAddress()
            );
            
            logs.add(log);
            System.out.println("审计日志: " + log);
        }
        
        public List<AuditLog> getLogsForUser(String username) {
            return logs.stream()
                .filter(log -> log.getUsername().equals(username))
                .collect(Collectors.toList());
        }
        
        public List<AuditLog> getLogsForResource(String resource) {
            return logs.stream()
                .filter(log -> log.getResource().equals(resource))
                .collect(Collectors.toList());
        }
        
        public List<AuditLog> getLogsByTimeRange(Date startTime, Date endTime) {
            return logs.stream()
                .filter(log -> !log.getTimestamp().before(startTime) && 
                               !log.getTimestamp().after(endTime))
                .collect(Collectors.toList());
        }
    }
    
    // 审计日志实体
    public static class AuditLog {
        private String username;
        private String action;
        private String resource;
        private String details;
        private Date timestamp;
        String ipAddress;
        
        public AuditLog(String username, String action, String resource, 
                       String details, Date timestamp, String ipAddress) {
            this.username = username;
            this.action = action;
            this.resource = resource;
            this.details = details;
            this.timestamp = timestamp;
            this.ipAddress = ipAddress;
        }
        
        // getter方法
        public String getUsername() { return username; }
        public String getAction() { return action; }
        public String getResource() { return resource; }
        public String getDetails() { return details; }
        public Date getTimestamp() { return timestamp; }
        public String getIpAddress() { return ipAddress; }
        
        @Override
        public String toString() {
            return String.format("[%s] 用户 %s 执行了 %s 操作 on %s. 详情: %s. IP: %s",
                timestamp, username, action, resource, details, ipAddress);
        }
    }
    
    // 安全中间件
    public static class SecurityMiddleware {
        private AuthenticationService authService;
        private AuthorizationService authzService;
        private RequestRateLimiter rateLimiter;
        private AuditLogger auditLogger;
        
        public SecurityMiddleware(AuthenticationService authService, 
                                AuthorizationService authzService,
                                RequestRateLimiter rateLimiter,
                                AuditLogger auditLogger) {
            this.authService = authService;
            this.authzService = authzService;
            this.rateLimiter = rateLimiter;
            this.auditLogger = auditLogger;
        }
        
        public SecurityResponse checkRequest(String token, String userId, String action, String resource) {
            // 1. 检查令牌
            if (!authService.verifyToken(token)) {
                auditLogger.log(userId, "AUTH_FAILED", resource, "无效的访问令牌");
                return new SecurityResponse(false, "无效的访问令牌");
            }
            
            String username = authService.getUsernameByToken(token);
            
            // 2. 检查限流
            if (!rateLimiter.allowRequest(username)) {
                auditLogger.log(username, "RATE_LIMIT_EXCEEDED", resource, "请求频率超限");
                return new SecurityResponse(false, "请求频率超限,请稍后再试");
            }
            
            // 3. 检查权限
            String permission = resource + ":" + action;
            if (!authzService.hasPermission(username, permission)) {
                auditLogger.log(username, "PERMISSION_DENIED", resource, "权限不足");
                return new SecurityResponse(false, "权限不足");
            }
            
            // 4. 记录成功日志
            auditLogger.log(username, action, resource, "操作成功");
            return new SecurityResponse(true, "安全检查通过");
        }
    }
    
    // 安全响应
    public static class SecurityResponse {
        private boolean allowed;
        private String message;
        
        public SecurityResponse(boolean allowed, String message) {
            this.allowed = allowed;
            this.message = message;
        }
        
        public boolean isAllowed() { return allowed; }
        public String getMessage() { return message; }
    }
    
    // 主方法 - 演示安全系统
    public static void main(String[] args) throws Exception {
        // 创建安全组件
        AuthenticationService authService = new AuthenticationService();
        AuthorizationService authzService = new AuthorizationService();
        RequestRateLimiter rateLimiter = new RequestRateLimiter(10, 60000); // 每分钟10次请求
        AuditLogger auditLogger = new AuditLogger();
        
        // 创建安全中间件
        SecurityMiddleware securityMiddleware = new SecurityMiddleware(
            authService, authzService, rateLimiter, auditLogger);
        
        // 测试SQL注入防护
        System.out.println("=== SQL注入防护测试 ===");
        String maliciousInput = "SELECT * FROM users WHERE id = 1; DROP TABLE users;";
        String sanitizedInput = SqlInjectionProtection.sanitizeInput(maliciousInput);
        System.out.println("原始输入: " + maliciousInput);
        System.out.println("净化后输入: " + sanitizedInput);
        
        // 测试XSS防护
        System.out.println("\n=== XSS防护测试 ===");
        String xssInput = "<script>alert('XSS攻击')</script>";
        String sanitizedHtml = XssProtection.sanitizeHtml(xssInput);
        System.out.println("原始HTML: " + xssInput);
        System.out.println("净化后HTML: " + sanitizedHtml);
        
        // 测试数据加密
        System.out.println("\n=== 数据加密测试 ===");
        String sensitiveData = "用户敏感信息";
        String encrypted = DataEncryption.encrypt(sensitiveData);
        String decrypted = DataEncryption.decrypt(encrypted);
        System.out.println("原始数据: " + sensitiveData);
        System.out.println("加密后: " + encrypted);
        System.out.println("解密后: " + decrypted);
        
        // 测试验证码
        System.out.println("\n=== 验证码测试 ===");
        String captcha = CaptchaGenerator.generateCaptcha();
        System.out.println("生成的验证码: " + captcha);
        System.out.println("验证码验证: " + CaptchaGenerator.verifyCaptcha(captcha, captcha));
        
        // 测试认证授权
        System.out.println("\n=== 认证授权测试 ===");
        
        // 用户登录
        String token = authService.login("admin", "admin123");
        System.out.println("登录令牌: " + (token != null ? "成功" : "失败"));
        
        if (token != null) {
            // 检查权限
            boolean hasPermission = authzService.hasPermission("admin", "user:create");
            System.out.println("admin用户是否有创建用户权限: " + hasPermission);
            
            // 使用安全中间件检查请求
            SecurityResponse response = securityMiddleware.checkRequest(
                token, "admin", "create", "user");
            System.out.println("安全检查结果: " + response.getMessage());
            
            // 模拟无权限操作
            response = securityMiddleware.checkRequest(
                token, "admin", "delete", "user");
            System.out.println("无权限操作检查结果: " + response.getMessage());
            
            // 用户登出
            authService.logout(token);
        }
        
        // 测试请求限流
        System.out.println("\n=== 请求限流测试 ===");
        String testToken = authService.login("user1", "password1");
        
        if (testToken != null) {
            // 模拟多次请求
            for (int i = 0; i < 15; i++) {
                SecurityResponse response = securityMiddleware.checkRequest(
                    testToken, "user1", "read", "product");
                System.out.println("请求 " + (i + 1) + ": " + response.getMessage());
                
                if (!response.isAllowed()) {
                    break;
                }
                
                try {
                    Thread.sleep(100); // 模拟请求间隔
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            
            authService.logout(testToken);
        }
        
        // 测试日志审计
        System.out.println("\n=== 日志审计测试 ===");
        
        // 模拟一些操作
        authService.login("admin", "admin123");
        auditLogger.log("admin", "read", "user", "查看用户列表");
        auditLogger.log("admin", "create", "user", "创建新用户");
        auditLogger.log("user1", "read", "order", "查看订单");
        
        // 查询特定用户的日志
        List<AuditLog> adminLogs = auditLogger.getLogsForUser("admin");
        System.out.println("\nadmin用户的操作日志:");
        adminLogs.forEach(System.out::println);
        
        // 查询特定资源的日志
        List<AuditLog> userLogs = auditLogger.getLogsForResource("user");
        System.out.println("\nuser资源的操作日志:");
        userLogs.forEach(System.out::println);
    }
}

9. 可测性:精准测试,确保系统质量

尽量缩小测试环境与线上的差异,确保测试结果能够真实反映线上系统的运行状态。

同时,支持在线上进行压测,但通过隔离测试数据、设置测试白名单等手段,避免对真实用户产生影响。在这里插入图片描述

例如,在一次线上压测中,通过模拟10万并发用户,对系统的性能进行了全面测试,及时发现了系统中的性能瓶颈,并进行了针对性优化。

此外,还支持部署多套隔离的测试环境,满足不同测试场景的需求。在测试过程中,合理分配黑盒测试与白盒测试的工作量,确保测试的全面性与深入性。
例如,对于核心业务逻辑,采用白盒测试,深入代码层面进行验证;对于系统接口与用户交互,采用黑盒测试,从用户视角进行测试。

通过这些可测性设计,能够精准定位系统中的问题,确保系统上线后的稳定运行。

架构示例图

测试策略
测试数据
测试工具
线上环境
测试环境
测试策略
黑盒测试
白盒测试
性能测试
安全测试
测试数据
测试数据生成器
测试数据管理
测试工具
单元测试框架
集成测试框架
系统测试框架
负载测试工具
线上环境
生产负载测试
隔离沙箱
测试环境
单元测试环境
集成测试环境
系统测试环境

架构示例代码

// 可测试系统实现
public class TestableSystem {
    
    // 业务服务接口
    public interface BusinessService {
        Result process(Request request);
    }
    
    // 请求对象
    public static class Request {
        private String id;
        private String type;
        private Map<String, Object> parameters;
        
        public Request(String id, String type) {
            this.id = id;
            this.type = type;
            this.parameters = new HashMap<>();
        }
        
        public String getId() { return id; }
        public String getType() { return type; }
        public Map<String, Object> getParameters() { return parameters; }
        
        public void addParameter(String key, Object value) {
            parameters.put(key, value);
        }
    }
    
    // 结果对象
    public static class Result {
        private boolean success;
        private String message;
        private Object data;
        
        public Result(boolean success, String message) {
            this(success, message, null);
        }
        
        public Result(boolean success, String message, Object data) {
            this.success = success;
            this.message = message;
            this.data = data;
        }
        
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public Object getData() { return data; }
    }
    
    // 业务服务实现
    public static class OrderService implements BusinessService {
        private OrderRepository orderRepository;
        
        public OrderService(OrderRepository orderRepository) {
            this.orderRepository = orderRepository;
        }
        
        @Override
        public Result process(Request request) {
            try {
                String orderId = request.getId();
                String userId = (String) request.getParameters().get("userId");
                BigDecimal amount = new BigDecimal((String) request.getParameters().get("amount"));
                
                // 验证订单
                if (orderId == null || orderId.isEmpty()) {
                    return new Result(false, "订单ID不能为空");
                }
                
                if (userId == null || userId.isEmpty()) {
                    return new Result(false, "用户ID不能为空");
                }
                
                if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
                    return new Result(false, "订单金额必须大于0");
                }
                
                // 创建订单
                Order order = new Order(orderId, userId, amount);
                orderRepository.save(order);
                
                return new Result(true, "订单创建成功", order);
            } catch (Exception e) {
                return new Result(false, "处理订单失败: " + e.getMessage());
            }
        }
    }
    
    // 订单仓库
    public interface OrderRepository {
        void save(Order order);
        Order findById(String orderId);
        List<Order> findByUserId(String userId);
    }
    
    // 内存订单仓库(用于测试)
    public static class InMemoryOrderRepository implements OrderRepository {
        private Map<String, Order> orders;
        
        public InMemoryOrderRepository() {
            this.orders = new ConcurrentHashMap<>();
        }
        
        @Override
        public void save(Order order) {
            orders.put(order.getId(), order);
        }
        
        @Override
        public Order findById(String orderId) {
            return orders.get(orderId);
        }
        
        @Override
        public List<Order> findByUserId(String userId) {
            return orders.values().stream()
                .filter(order -> order.getUserId().equals(userId))
                .collect(Collectors.toList());
        }
        
        public void clear() {
            orders.clear();
        }
    }
    
    // 订单实体
    public static class Order {
        private String id;
        private String userId;
        private BigDecimal amount;
        private Date createTime;
        
        public Order(String id, String userId, BigDecimal amount) {
            this.id = id;
            this.userId = userId;
            this.amount = amount;
            this.createTime = new Date();
        }
        
        public String getId() { return id; }
        public String getUserId() { return userId; }
        public BigDecimal getAmount() { return amount; }
        public Date getCreateTime() { return createTime; }
    }
    
    // 单元测试
    public static class UnitTest {
        private OrderService orderService;
        private InMemoryOrderRepository orderRepository;
        
        public UnitTest() {
            this.orderRepository = new InMemoryOrderRepository();
            this.orderService = new OrderService(orderRepository);
        }
        
        public void testOrderCreation() {
            // 测试正常订单创建
            Request request = new Request("order123", "create");
            request.addParameter("userId", "user123");
            request.addParameter("amount", "100.00");
            
            Result result = orderService.process(request);
            
            assert result.isSuccess() : "订单创建应该成功";
            assert result.getData() instanceof Order : "返回数据应该是Order对象";
            
            Order order = (Order) result.getData();
            assert order.getId().equals("order123") : "订单ID应该匹配";
            assert order.getUserId().equals("user123") : "用户ID应该匹配";
            assert order.getAmount().compareTo(new BigDecimal("100.00")) == 0 : "订单金额应该匹配";
            
            System.out.println("单元测试通过: 订单创建");
        }
        
        public void testInvalidOrderId() {
            // 测试无效订单ID
            Request request = new Request("", "create");
            request.addParameter("userId", "user123");
            request.addParameter("amount", "100.00");
            
            Result result = orderService.process(request);
            
            assert !result.isSuccess() : "无效订单ID应该失败";
            assert result.getMessage().equals("订单ID不能为空") : "错误消息应该匹配";
            
            System.out.println("单元测试通过: 无效订单ID");
        }
        
        public void testInvalidAmount() {
            // 测试无效金额
            Request request = new Request("order123", "create");
            request.addParameter("userId", "user123");
            request.addParameter("amount", "-100.00");
            
            Result result = orderService.process(request);
            
            assert !result.isSuccess() : "无效金额应该失败";
            assert result.getMessage().equals("订单金额必须大于0") : "错误消息应该匹配";
            
            System.out.println("单元测试通过: 无效金额");
        }
        
        public void runAllTests() {
            orderRepository.clear();
            
            testOrderCreation();
            testInvalidOrderId();
            testInvalidAmount();
            
            System.out.println("所有单元测试通过");
        }
    }
    
    // 集成测试
    public static class IntegrationTest {
        private OrderService orderService;
        private InMemoryOrderRepository orderRepository;
        
        public IntegrationTest() {
            this.orderRepository = new InMemoryOrderRepository();
            this.orderService = new OrderService(orderRepository);
        }
        
        public void testOrderPersistence() {
            // 创建订单
            Request request = new Request("order123", "create");
            request.addParameter("userId", "user123");
            request.addParameter("amount", "100.00");
            
            Result result = orderService.process(request);
            assert result.isSuccess() : "订单创建应该成功";
            
            // 验证订单是否持久化
            Order savedOrder = orderRepository.findById("order123");
            assert savedOrder != null : "订单应该被持久化";
            assert savedOrder.getId().equals("order123") : "持久化的订单ID应该匹配";
            
            System.out.println("集成测试通过: 订单持久化");
        }
        
        public void testUserOrderQuery() {
            // 创建多个订单
            Request request1 = new Request("order1", "create");
            request1.addParameter("userId", "user123");
            request1.addParameter("amount", "100.00");
            orderService.process(request1);
            
            Request request2 = new Request("order2", "create");
            request2.addParameter("userId", "user123");
            request2.addParameter("amount", "200.00");
            orderService.process(request2);
            
            Request request3 = new Request("order3", "create");
            request3.addParameter("userId", "user456");
            request3.addParameter("amount", "150.00");
            orderService.process(request3);
            
            // 查询用户订单
            List<Order> userOrders = orderRepository.findByUserId("user123");
            assert userOrders.size() == 2 : "用户应该有2个订单";
            
            System.out.println("集成测试通过: 用户订单查询");
        }
        
        public void runAllTests() {
            orderRepository.clear();
            
            testOrderPersistence();
            testUserOrderQuery();
            
            System.out.println("所有集成测试通过");
        }
    }
    
    // 性能测试
    public static class PerformanceTest {
        private OrderService orderService;
        private InMemoryOrderRepository orderRepository;
        
        public PerformanceTest() {
            this.orderRepository = new InMemoryOrderRepository();
            this.orderService = new OrderService(orderRepository);
        }
        
        public void testConcurrentOrderCreation(int threadCount, int requestsPerThread) {
            ExecutorService executor = Executors.newFixedThreadPool(threadCount);
            CountDownLatch latch = new CountDownLatch(threadCount * requestsPerThread);
            
            long startTime = System.currentTimeMillis();
            
            // 提交并发请求
            for (int i = 0; i < threadCount; i++) {
                final int threadId = i;
                executor.submit(() -> {
                    for (int j = 0; j < requestsPerThread; j++) {
                        Request request = new Request("order-" + threadId + "-" + j, "create");
                        request.addParameter("userId", "user-" + threadId);
                        request.addParameter("amount", "100.00");
                        
                        Result result = orderService.process(request);
                        assert result.isSuccess() : "订单创建应该成功";
                        
                        latch.countDown();
                    }
                });
            }
            
            try {
                latch.await();
                long endTime = System.currentTimeMillis();
                
                double duration = (endTime - startTime) / 1000.0;
                double tps = (threadCount * requestsPerThread) / duration;
                
                System.out.println("性能测试结果:");
                System.out.println("线程数: " + threadCount);
                System.out.println("每线程请求数: " + requestsPerThread);
                System.out.println("总请求数: " + (threadCount * requestsPerThread));
                System.out.println("总耗时: " + duration + "秒");
                System.out.println("TPS: " + tps);
                
                // 验证所有订单都被创建
                int totalOrders = orderRepository.findByUserId("user-0").size() + 
                                 orderRepository.findByUserId("user-1").size();
                assert totalOrders == (threadCount * requestsPerThread) : "所有订单都应该被创建";
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                executor.shutdown();
            }
        }
        
        public void runPerformanceTest() {
            orderRepository.clear();
            
            testConcurrentOrderCreation(10, 100); // 10个线程,每个线程100个请求
            
            System.out.println("性能测试完成");
        }
    }
    
    // 测试数据生成器
    public static class TestDataGenerator {
        private static final Random random = new Random();
        
        public static String generateOrderId() {
            return "order-" + System.currentTimeMillis() + "-" + random.nextInt(10000);
        }
        
        public static String generateUserId() {
            return "user-" + random.nextInt(10000);
        }
        
        public static String generateAmount() {
            return String.format("%.2f", 10 + random.nextDouble() * 1000);
        }
        
        public static Request generateOrderRequest() {
            Request request = new Request(generateOrderId(), "create");
            request.addParameter("userId", generateUserId());
            request.addParameter("amount", generateAmount());
            return request;
        }
        
        public static List<Request> generateOrderRequests(int count) {
            List<Request> requests = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                requests.add(generateOrderRequest());
            }
            return requests;
        }
    }
    
    // 主方法 - 演示可测试系统
    public static void main(String[] args) {
        // 运行单元测试
        System.out.println("=== 运行单元测试 ===");
        UnitTest unitTest = new UnitTest();
        unitTest.runAllTests();
        
        // 运行集成测试
        System.out.println("\n=== 运行集成测试 ===");
        IntegrationTest integrationTest = new IntegrationTest();
        integrationTest.runAllTests();
        
        // 运行性能测试
        System.out.println("\n=== 运行性能测试 ===");
        PerformanceTest performanceTest = new PerformanceTest();
        performanceTest.runPerformanceTest();
        
        // 测试数据生成器演示
        System.out.println("\n=== 测试数据生成器演示 ===");
        List<Request> requests = TestDataGenerator.generateOrderRequests(5);
        for (Request request : requests) {
            System.out.println("生成的请求: ID=" + request.getId() + 
                             ", 用户ID=" + request.getParameters().get("userId") + 
                             ", 金额=" + request.getParameters().get("amount"));
        }
    }
}

10. 可运维性:简化运维,降低运营成本

可运维性关注系统在长期运行过程中的维护与管理。

为系统设计了初始化与预热环节,确保系统在启动时能够快速进入稳定状态。针对数据指数级别递增的问题,制定了定期归档策略,将历史数据迁移到低成本存储介质中,降低了存储成本。

同时,建立了完善的系统巡检与维护机制,定期对系统进行性能监控、日志分析与故障排查,及时发现并解决潜在问题。

例如,通过自动化脚本,每天凌晨对系统进行全量巡检,生成巡检报告,并将异常情况及时通知运维人员。

此外,还设计了业务运维的可视化界面,使运维人员能够直观地了解系统运行状态,快速定位问题根源,提高了运维效率,降低了运营成本。

架构示例图

存储系统
自动化工具
监控系统
运维系统
存储系统
热存储
冷存储
自动化工具
归档存储
自动化通知
监控系统
性能监控
日志监控
故障监控
运维系统
初始化系统
预热系统
数据归档系统
巡检系统
可视化分析

架构示例代码

// 可运维系统实现
public class OperableSystem {
    
    // 系统初始化服务
    public static class SystemInitializer {
        private List<SystemComponent> components;
        
        public SystemInitializer() {
            this.components = new ArrayList<>();
        }
        
        public void registerComponent(SystemComponent component) {
            components.add(component);
        }
        
        public void initialize() {
            System.out.println("开始系统初始化...");
            
            for (SystemComponent component : components) {
                try {
                    System.out.println("初始化组件: " + component.getName());
                    component.initialize();
                    System.out.println("组件 " + component.getName() + " 初始化成功");
                } catch (Exception e) {
                    System.err.println("组件 " + component.getName() + " 初始化失败: " + e.getMessage());
                    throw new RuntimeException("系统初始化失败", e);
                }
            }
            
            System.out.println("系统初始化完成");
        }
    }
    
    // 系统预热服务
    public static class SystemWarmer {
        private List<SystemComponent> components;
        
        public SystemWarmer() {
            this.components = new ArrayList<>();
        }
        
        public void registerComponent(SystemComponent component) {
            components.add(component);
        }
        
        public void warmUp() {
            System.out.println("开始系统预热...");
            
            for (SystemComponent component : components) {
                try {
                    System.out.println("预热组件: " + component.getName());
                    component.warmUp();
                    System.out.println("组件 " + component.getName() + " 预热完成");
                } catch (Exception e) {
                    System.err.println("组件 " + component.getName() + " 预热失败: " + e.getMessage());
                }
            }
            
            System.out.println("系统预热完成");
        }
    }
    
    // 系统组件接口
    public interface SystemComponent {
        String getName();
        void initialize() throws Exception;
        void warmUp() throws Exception;
        void shutdown() throws Exception;
    }
    
    // 数据库组件
    public static class DatabaseComponent implements SystemComponent {
        private String name;
        private boolean initialized;
        
        public DatabaseComponent(String name) {
            this.name = name;
            this.initialized = false;
        }
        
        @Override
        public String getName() {
            return name;
        }
        
        @Override
        public void initialize() throws Exception {
            // 模拟数据库初始化
            System.out.println("初始化数据库连接池...");
            Thread.sleep(1000); // 模拟初始化耗时
            
            // 创建必要的表
            System.out.println("创建数据库表结构...");
            Thread.sleep(500);
            
            initialized = true;
        }
        
        @Override
        public void warmUp() throws Exception {
            if (!initialized) {
                throw new IllegalStateException("数据库未初始化");
            }
            
            // 预热数据库连接
            System.out.println("预热数据库连接...");
            Thread.sleep(500);
            
            // 预加载常用数据
            System.out.println("预加载常用数据...");
            Thread.sleep(500);
        }
        
        @Override
        public void shutdown() throws Exception {
            System.out.println("关闭数据库连接...");
            Thread.sleep(300);
        }
    }
    
    // 缓存组件
    public static class CacheComponent implements SystemComponent {
        private String name;
        private boolean initialized;
        
        public CacheComponent(String name) {
            this.name = name;
            this.initialized = false;
        }
        
        @Override
        public String getName() {
            return name;
        }
        
        @Override
        public void initialize() throws Exception {
            // 模拟缓存初始化
            System.out.println("初始化缓存连接...");
            Thread.sleep(800);
            
            initialized = true;
        }
        
        @Override
        public void warmUp() throws Exception {
            if (!initialized) {
                throw new IllegalStateException("缓存未初始化");
            }
            
            // 预热缓存
            System.out.println("预热缓存数据...");
            Thread.sleep(1000);
        }
        
        @Override
        public void shutdown() throws Exception {
            System.out.println("关闭缓存连接...");
            Thread.sleep(200);
        }
    }
    
    // 数据归档服务
    public static class DataArchivingService {
        private StorageSystem storageSystem;
        private DataArchivingPolicy policy;
        
        public DataArchivingService(StorageSystem storageSystem, DataArchivingPolicy policy) {
            this.storageSystem = storageSystem;
            this.policy = policy;
        }
        
        public void archiveData() {
            System.out.println("开始数据归档...");
            
            // 获取需要归档的数据
            List<DataRecord> dataToArchive = storageSystem.getDataToArchive(policy);
            
            if (dataToArchive.isEmpty()) {
                System.out.println("没有需要归档的数据");
                return;
            }
            
            // 归档数据
            for (DataRecord record : dataToArchive) {
                try {
                    storageSystem.moveToArchive(record);
                    System.out.println("数据已归档: " + record.getId());
                } catch (Exception e) {
                    System.err.println("数据归档失败: " + record.getId() + ", 错误: " + e.getMessage());
                }
            }
            
            System.out.println("数据归档完成,共归档 " + dataToArchive.size() + " 条记录");
        }
    }
    
    // 存储系统
    public static class StorageSystem {
        private Map<String, DataRecord> hotStorage;
        private Map<String, DataRecord> coldStorage;
        private Map<String, DataRecord> archiveStorage;
        
        public StorageSystem() {
            this.hotStorage = new ConcurrentHashMap<>();
            this.coldStorage = new ConcurrentHashMap<>();
            this.archiveStorage = new ConcurrentHashMap<>();
            
            // 初始化一些测试数据
            initializeTestData();
        }
        
        private void initializeTestData() {
            // 创建一些测试数据
            for (int i = 1; i <= 1000; i++) {
                DataRecord record = new DataRecord("record-" + i, "数据内容 " + i, 
                    new Date(System.currentTimeMillis() - i * 24 * 60 * 60 * 1000L));
                
                if (i <= 100) {
                    hotStorage.put(record.getId(), record);
                } else if (i <= 500) {
                    coldStorage.put(record.getId(), record);
                } else {
                    archiveStorage.put(record.getId(), record);
                }
            }
        }
        
        public List<DataRecord> getDataToArchive(DataArchivingPolicy policy) {
            List<DataRecord> toArchive = new ArrayList<>();
            
            // 根据策略获取需要归档的数据
            Date cutoffDate = new Date(System.currentTimeMillis() - policy.getArchiveThreshold());
            
            coldStorage.forEach((id, record) -> {
                if (record.getCreateTime().before(cutoffDate)) {
                    toArchive.add(record);
                }
            });
            
            return toArchive;
        }
        
        public void moveToArchive(DataRecord record) {
            // 从冷存储中移除
            coldStorage.remove(record.getId());
            
            // 添加到归档存储
            archiveStorage.put(record.getId(), record);
        }
        
        public int getHotStorageSize() {
            return hotStorage.size();
        }
        
        public int getColdStorageSize() {
            return coldStorage.size();
        }
        
        public int getArchiveStorageSize() {
            return archiveStorage.size();
        }
    }
    
    // 数据记录
    public static class DataRecord {
        private String id;
        private String content;
        private Date createTime;
        
        public DataRecord(String id, String content, Date createTime) {
            this.id = id;
            this.content = content;
            this.createTime = createTime;
        }
        
        public String getId() { return id; }
        public String getContent() { return content; }
        public Date getCreateTime() { return createTime; }
    }
    
    // 数据归档策略
    public static class DataArchivingPolicy {
        private long archiveThreshold; // 归档阈值(毫秒)
        private int batchSize; // 批处理大小
        
        public DataArchivingPolicy(long archiveThreshold, int batchSize) {
            this.archiveThreshold = archiveThreshold;
            this.batchSize = batchSize;
        }
        
        public long getArchiveThreshold() {
            return archiveThreshold;
        }
        
        public int getBatchSize() {
            return batchSize;
        }
    }
    
    // 系统巡检服务
    public static class SystemInspectionService {
        private List<SystemInspector> inspectors;
        private NotificationService notificationService;
        
        public SystemInspectionService(NotificationService notificationService) {
            this.inspectors = new ArrayList<>();
            this.notificationService = notificationService;
        }
        
        public void registerInspector(SystemInspector inspector) {
            inspectors.add(inspector);
        }
        
        public InspectionReport performInspection() {
            System.out.println("开始系统巡检...");
            
            InspectionReport report = new InspectionReport();
            
            for (SystemInspector inspector : inspectors) {
                try {
                    InspectionResult result = inspector.inspect();
                    report.addResult(result);
                    
                    if (!result.isHealthy()) {
                        notificationService.sendAlert(result.getMessage());
                    }
                } catch (Exception e) {
                    InspectionResult errorResult = new InspectionResult(
                        inspector.getName(), false, "巡检失败: " + e.getMessage());
                    report.addResult(errorResult);
                    notificationService.sendAlert("系统巡检异常: " + e.getMessage());
                }
            }
            
            System.out.println("系统巡检完成");
            return report;
        }
    }
    
    // 系统巡检器接口
    public interface SystemInspector {
        String getName();
        InspectionResult inspect() throws Exception;
    }
    
    // CPU使用率巡检器
    public static class CpuUsageInspector implements SystemInspector {
        @Override
        public String getName() {
            return "CPU使用率巡检器";
        }
        
        @Override
        public InspectionResult inspect() throws Exception {
            // 模拟获取CPU使用率
            double cpuUsage = 50 + Math.random() * 40; // 50-90%
            
            if (cpuUsage > 80) {
                return new InspectionResult(getName(), false, 
                    "CPU使用率过高: " + String.format("%.2f", cpuUsage) + "%");
            }
            
            return new InspectionResult(getName(), true, 
                "CPU使用率正常: " + String.format("%.2f", cpuUsage) + "%");
        }
    }
    
    // 内存使用率巡检器
    public static class MemoryUsageInspector implements SystemInspector {
        @Override
        public String getName() {
            return "内存使用率巡检器";
        }
        
        @Override
        public InspectionResult inspect() throws Exception {
            // 模拟获取内存使用率
            double memoryUsage = 40 + Math.random() * 50; // 40-90%
            
            if (memoryUsage > 85) {
                return new InspectionResult(getName(), false, 
                    "内存使用率过高: " + String.format("%.2f", memoryUsage) + "%");
            }
            
            return new InspectionResult(getName(), true, 
                "内存使用率正常: " + String.format("%.2f", memoryUsage) + "%");
        }
    }
    
    // 磁盘空间巡检器
    public static class DiskSpaceInspector implements SystemInspector {
        @Override
        public String getName() {
            return "磁盘空间巡检器";
        }
        
        @Override
        public InspectionResult inspect() throws Exception {
            // 模拟获取磁盘使用率
            double diskUsage = 30 + Math.random() * 60; // 30-90%
            
            if (diskUsage > 85) {
                return new InspectionResult(getName(), false, 
                    "磁盘空间不足: " + String.format("%.2f", diskUsage) + "%");
            }
            
            return new InspectionResult(getName(), true, 
                "磁盘空间正常: " + String.format("%.2f", diskUsage) + "%");
        }
    }
    
    // 巡检结果
    public static class InspectionResult {
        private String inspectorName;
        private boolean healthy;
        private String message;
        
        public InspectionResult(String inspectorName, boolean healthy, String message) {
            this.inspectorName = inspectorName;
            this.healthy = healthy;
            this.message = message;
        }
        
        public String getInspectorName() { return inspectorName; }
        public boolean isHealthy() { return healthy; }
        public String getMessage() { return message; }
    }
    
    // 巡检报告
    public static class InspectionReport {
        private List<InspectionResult> results;
        
        public InspectionReport() {
            this.results = new ArrayList<>();
        }
        
        public void addResult(InspectionResult result) {
            results.add(result);
        }
        
        public boolean isSystemHealthy() {
            return results.stream().allMatch(InspectionResult::isHealthy);
        }
        
        public String getSummary() {
            int healthyCount = (int) results.stream().filter(InspectionResult::isHealthy).count();
            int unhealthyCount = results.size() - healthyCount;
            
            return String.format("巡检完成: 共%d项检查, %d项正常, %d项异常", 
                results.size(), healthyCount, unhealthyCount);
        }
        
        public List<InspectionResult> getUnhealthyResults() {
            return results.stream()
                .filter(result -> !result.isHealthy())
                .collect(Collectors.toList());
        }
    }
    
    // 通知服务
    public static class NotificationService {
        private List<String> notifications;
        
        public NotificationService() {
            this.notifications = new CopyOnWriteArrayList<>();
        }
        
        public void sendAlert(String message) {
            String notification = "[ALERT] " + new Date() + ": " + message;
            notifications.add(notification);
            System.out.println(notification);
        }
        
        public void sendInfo(String message) {
            String notification = "[INFO] " + new Date() + ": " + message;
            notifications.add(notification);
            System.out.println(notification);
        }
        
        public List<String> getNotifications() {
            return notifications;
        }
    }
    
    // 可视化分析服务
    public static class VisualizationService {
        private SystemInspectionService inspectionService;
        
        public VisualizationService(SystemInspectionService inspectionService) {
            this.inspectionService = inspectionService;
        }
        
        public void generateDashboard() {
            InspectionReport report = inspectionService.performInspection();
            
            System.out.println("\n=== 系统状态仪表板 ===");
            System.out.println(report.getSummary());
            
            if (!report.isSystemHealthy()) {
                System.out.println("\n异常项目:");
                for (InspectionResult result : report.getUnhealthyResults()) {
                    System.out.println("- " + result.getInspectorName() + ": " + result.getMessage());
                }
            }
            
            System.out.println("\n=== 系统资源使用情况 ===");
            System.out.println("- CPU使用率: " + (40 + Math.random() * 40) + "%");
            System.out.println("- 内存使用率: " + (30 + Math.random() * 50) + "%");
            System.out.println("- 磁盘使用率: " + (20 + Math.random() * 60) + "%");
            
            System.out.println("\n=== 存储使用情况 ===");
            System.out.println("- 热存储: " + (50 + Math.random() * 100) + "GB");
            System.out.println("- 冷存储: " + (200 + Math.random() * 300) + "GB");
            System.out.println("- 归档存储: " + (500 + Math.random() * 1000) + "GB");
        }
    }
    
    // 主方法 - 演示可运维系统
    public static void main(String[] args) throws Exception {
        // 创建通知服务
        NotificationService notificationService = new NotificationService();
        
        // 创建系统初始化和预热服务
        SystemInitializer systemInitializer = new SystemInitializer();
        SystemWarmer systemWarmer = new SystemWarmer();
        
        // 注册系统组件
        DatabaseComponent dbComponent = new DatabaseComponent("主数据库");
        CacheComponent cacheComponent = new CacheComponent("分布式缓存");
        
        systemInitializer.registerComponent(dbComponent);
        systemInitializer.registerComponent(cacheComponent);
        systemWarmer.registerComponent(dbComponent);
        systemWarmer.registerComponent(cacheComponent);
        
        // 初始化系统
        systemInitializer.initialize();
        
        // 预热系统
        systemWarmer.warmUp();
        
        // 创建存储系统和归档策略
        StorageSystem storageSystem = new StorageSystem();
        DataArchivingPolicy archivingPolicy = new DataArchivingPolicy(
            90L * 24 * 60 * 60 * 1000, // 90天
            1000 // 每批处理1000条记录
        );
        
        // 创建数据归档服务
        DataArchivingService archivingService = new DataArchivingService(storageSystem, archivingPolicy);
        
        // 执行数据归档
        archivingService.archiveData();
        
        // 创建系统巡检服务
        SystemInspectionService inspectionService = new SystemInspectionService(notificationService);
        
        // 注册巡检器
        inspectionService.registerInspector(new CpuUsageInspector());
        inspectionService.registerInspector(new MemoryUsageInspector());
        inspectionService.registerInspector(new DiskSpaceInspector());
        
        // 执行系统巡检
        InspectionReport report = inspectionService.performInspection();
        System.out.println("\n" + report.getSummary());
        
        // 创建可视化分析服务
        VisualizationService visualizationService = new VisualizationService(inspectionService);
        
        // 生成仪表板
        visualizationService.generateDashboard();
        
        // 显示通知
        System.out.println("\n=== 通知历史 ===");
        notificationService.getNotifications().forEach(System.out::println);
        
        // 关闭系统组件
        dbComponent.shutdown();
        cacheComponent.shutdown();
    }
}

11. 监控与报警:实时感知,快速响应

监控与报警是架构评审中保障系统稳定运行的最后一道防线。

  • 对系统内外部依赖的接口进行了全面监控,包括接口的响应时间、错误率等关键指标。
  • 在应用层面,暴露了丰富的系统内部指标,如线程池使用率、内存使用率等,为监控与报警提供了数据支持。
  • 针对系统层面使用的中间件与存储,也建立了完善的监控报警机制。
    例如,当数据库连接池使用率超过90%时,监控系统会立即发出报警,提醒运维人员及时采取措施,如增加数据库连接数或优化数据库查询。

通过这些监控报警设计,能够实时感知系统运行状态,快速响应异常情况,将故障影响降至最低。

架构示例图

自动化响应
报警系统
监控展示
数据处理
监控数据采集
自动化响应
脚本执行
自动修复
报警系统
实时报警
事件处理
通知渠道
监控展示
仪表板
图表
表格
数据处理
数据聚合
存储
监控采集器
应用指标
中间件指标
数据库指标
网络指标

架构示例代码

// 监控与报警系统实现
public class MonitoringAndAlertSystem {
    
    // 监控指标类型
    public enum MetricType {
        COUNTER,    // 计数器,只增不减
        GAUGE,      // 测量值,可增可减
        HISTOGRAM,  // 直方图,用于统计分布
        SUMMARY     // 摘要,用于统计分位数
    }
    
    // 监控指标
    public static class Metric {
        private String name;
        private String description;
        private MetricType type;
        private double value;
        private Map<String, String> labels;
        private long timestamp;
        
        public Metric(String name, String description, MetricType type) {
            this.name = name;
            this.description = description;
            this.type = type;
            this.value = 0;
            this.labels = new HashMap<>();
            this.timestamp = System.currentTimeMillis();
        }
        
        public void setValue(double value) {
            this.value = value;
            this.timestamp = System.currentTimeMillis();
        }
        
        public void increment(double delta) {
            this.value += delta;
            this.timestamp = System.currentTimeMillis();
        }
        
        public String getName() { return name; }
        public String getDescription() { return description; }
        public MetricType getType() { return type; }
        public double getValue() { return value; }
        public Map<String, String> getLabels() { return labels; }
        public long getTimestamp() { return timestamp; }
        
        public void addLabel(String key, String value) {
            labels.put(key, value);
        }
    }
    
    // 监控数据采集器
    public static class MetricCollector {
        private Map<String, Metric> metrics;
        
        public MetricCollector() {
            this.metrics = new ConcurrentHashMap<>();
        }
        
        public void registerMetric(Metric metric) {
            metrics.put(metric.getName(), metric);
        }
        
        public void recordMetric(String name, double value) {
            Metric metric = metrics.get(name);
            if (metric != null) {
                metric.setValue(value);
            }
        }
        
        public void incrementMetric(String name, double delta) {
            Metric metric = metrics.get(name);
            if (metric != null) {
                metric.increment(delta);
            }
        }
        
        public Metric getMetric(String name) {
            return metrics.get(name);
        }
        
        public List<Metric> getAllMetrics() {
            return new ArrayList<>(metrics.values());
        }
    }
    
    // 应用指标监控
    public static class ApplicationMetrics {
        private MetricCollector collector;
        
        public ApplicationMetrics(MetricCollector collector) {
            this.collector = collector;
            
            // 注册应用指标
            collector.registerMetric(new Metric("http_requests_total", "HTTP请求总数", MetricType.COUNTER));
            collector.registerMetric(new Metric("http_requests_duration_seconds", "HTTP请求耗时", MetricType.HISTOGRAM));
            collector.registerMetric(new Metric("jvm_memory_used_bytes", "JVM内存使用量", MetricType.GAUGE));
            collector.registerMetric(new Metric("jvm_thread_count", "JVM线程数", MetricType.GAUGE));
            collector.registerMetric(new Metric("app_errors_total", "应用错误总数", MetricType.COUNTER));
        }
        
        public void recordHttpRequest(String method, String path, int statusCode, double duration) {
            // 记录HTTP请求
            collector.incrementMetric("http_requests_total", 1);
            
            // 记录请求耗时
            Metric durationMetric = collector.getMetric("http_requests_duration_seconds");
            if (durationMetric != null) {
                durationMetric.increment(duration);
            }
            
            // 记录错误
            if (statusCode >= 400) {
                collector.incrementMetric("app_errors_total", 1);
            }
        }
        
        public void updateJvmMetrics(long memoryUsed, int threadCount) {
            // 更新JVM指标
            collector.recordMetric("jvm_memory_used_bytes", memoryUsed);
            collector.recordMetric("jvm_thread_count", threadCount);
        }
    }
    
    // 中间件指标监控
    public static class MiddlewareMetrics {
        private MetricCollector collector;
        
        public MiddlewareMetrics(MetricCollector collector) {
            this.collector = collector;
            
            // 注册中间件指标
            collector.registerMetric(new Metric("database_connections_active", "数据库活跃连接数", MetricType.GAUGE));
            collector.registerMetric(new Metric("database_connections_max", "数据库最大连接数", MetricType.GAUGE));
            collector.registerMetric(new Metric("cache_hits_total", "缓存命中总数", MetricType.COUNTER));
            collector.registerMetric(new Metric("cache_misses_total", "缓存未命中总数", MetricType.COUNTER));
            collector.registerMetric(new Metric("message_queue_size", "消息队列大小", MetricType.GAUGE));
        }
        
        public void updateDatabaseMetrics(int activeConnections, int maxConnections) {
            // 更新数据库指标
            collector.recordMetric("database_connections_active", activeConnections);
            collector.recordMetric("database_connections_max", maxConnections);
        }
        
        public void recordCacheHit() {
            collector.incrementMetric("cache_hits_total", 1);
        }
        
        public void recordCacheMiss() {
            collector.incrementMetric("cache_misses_total", 1);
        }
        
        public void updateMessageQueueSize(int size) {
            collector.recordMetric("message_queue_size", size);
        }
    }
    
    // 报警规则
    public static class AlertRule {
        private String name;
        private String metricName;
        private String operator;
        private double threshold;
        private String severity;
        private String message;
        
        public AlertRule(String name, String metricName, String operator, 
                        double threshold, String severity, String message) {
            this.name = name;
            this.metricName = metricName;
            this.operator = operator;
            this.threshold = threshold;
            this.severity = severity;
            this.message = message;
        }
        
        public boolean evaluate(Metric metric) {
            if (metric == null) {
                return false;
            }
            
            double value = metric.getValue();
            
            switch (operator) {
                case ">":
                    return value > threshold;
                case ">=":
                    return value >= threshold;
                case "<":
                    return value < threshold;
                case "<=":
                    return value <= threshold;
                case "==":
                    return value == threshold;
                case "!=":
                    return value != threshold;
                default:
                    return false;
            }
        }
        
        public String getName() { return name; }
        public String getMetricName() { return metricName; }
        public String getOperator() { return operator; }
        public double getThreshold() { return threshold; }
        public String getSeverity() { return severity; }
        public String getMessage() { return message; }
    }
    
    // 报警系统
    public static class AlertSystem {
        private List<AlertRule> rules;
        private List<Alert> activeAlerts;
        private NotificationService notificationService;
        
        public AlertSystem(NotificationService notificationService) {
            this.rules = new ArrayList<>();
            this.activeAlerts = new ArrayList<>();
            this.notificationService = notificationService;
        }
        
        public void addRule(AlertRule rule) {
            rules.add(rule);
        }
        
        public void evaluateMetrics(List<Metric> metrics) {
            for (Metric metric : metrics) {
                for (AlertRule rule : rules) {
                    if (rule.getMetricName().equals(metric.getName()) && rule.evaluate(metric)) {
                        // 检查是否已有活跃的报警
                        boolean existingAlert = activeAlerts.stream()
                            .anyMatch(alert -> alert.getRuleName().equals(rule.getName()));
                            
                        if (!existingAlert) {
                            // 创建新报警
                            Alert alert = new Alert(
                                rule.getName(),
                                rule.getSeverity(),
                                rule.getMessage(),
                                metric.getValue(),
                                new Date()
                            );
                            
                            activeAlerts.add(alert);
                            notificationService.sendAlert(alert);
                        }
                    }
                }
            }
            
            // 检查是否需要关闭报警
            checkAlertResolution();
        }
        
        private void checkAlertResolution() {
            Iterator<Alert> iterator = activeAlerts.iterator();
            while (iterator.hasNext()) {
                Alert alert = iterator.next();
                Metric metric = getMetricByName(alert.getRuleName());
                
                if (metric != null && !getRuleByName(alert.getRuleName()).evaluate(metric)) {
                    // 报警已解决
                    iterator.remove();
                    notificationService.sendResolution(alert);
                }
            }
        }
        
        private Metric getMetricByName(String metricName) {
            // 简化实现,实际应该从MetricCollector获取
            return null;
        }
        
        private AlertRule getRuleByName(String ruleName) {
            return rules.stream()
                .filter(rule -> rule.getName().equals(ruleName))
                .findFirst()
                .orElse(null);
        }
        
        public List<Alert> getActiveAlerts() {
            return new ArrayList<>(activeAlerts);
        }
    }
    
    // 报警
    public static class Alert {
        private String ruleName;
        private String severity;
        private String message;
        private double value;
        private Date timestamp;
        
        public Alert(String ruleName, String severity, String message, double value, Date timestamp) {
            this.ruleName = ruleName;
            this.severity = severity;
            this.message = message;
            this.value = value;
            this.timestamp = timestamp;
        }
        
        public String getRuleName() { return ruleName; }
        public String getSeverity() { return severity; }
        public String getMessage() { return message; }
        public double getValue() { return value; }
        public Date getTimestamp() { return timestamp; }
    }
    
    // 通知服务
    public static class NotificationService {
        private List<String> notifications;
        
        public NotificationService() {
            this.notifications = new CopyOnWriteArrayList<>();
        }
        
        public void sendAlert(Alert alert) {
            String message = String.format("[%s] %s: %s (当前值: %.2f) - %s",
                alert.getSeverity(), alert.getRuleName(), alert.getMessage(), 
                alert.getValue(), new Date());
                
            notifications.add(message);
            System.out.println("报警: " + message);
            
            // 这里可以添加实际的通知逻辑,如发送邮件、短信等
        }
        
        public void sendResolution(Alert alert) {
            String message = String.format("[RESOLVED] %s: 报警已解决 - %s",
                alert.getRuleName(), new Date());
                
            notifications.add(message);
            System.out.println("报警解决: " + message);
        }
        
        public List<String> getNotifications() {
            return notifications;
        }
    }
    
    // 自动化响应
    public static class AutomatedResponse {
        private AlertSystem alertSystem;
        private Map<String, ResponseAction> actions;
        
        public AutomatedResponse(AlertSystem alertSystem) {
            this.alertSystem = alertSystem;
            this.actions = new HashMap<>();
            
            // 注册响应动作
            actions.put("high_database_connections", new ScaleUpDatabaseAction());
            actions.put("high_memory_usage", new RestartServiceAction());
            actions.put("high_error_rate", new CircuitBreakerAction());
        }
        
        public void processAlerts() {
            List<Alert> alerts = alertSystem.getActiveAlerts();
            
            for (Alert alert : alerts) {
                ResponseAction action = actions.get(alert.getRuleName());
                if (action != null && alert.getSeverity().equals("CRITICAL")) {
                    try {
                        action.execute();
                        System.out.println("执行自动化响应: " + action.getClass().getSimpleName());
                    } catch (Exception e) {
                        System.err.println("自动化响应执行失败: " + e.getMessage());
                    }
                }
            }
        }
    }
    
    // 响应动作接口
    public interface ResponseAction {
        void execute() throws Exception;
    }
    
    // 数据库扩容动作
    public static class ScaleUpDatabaseAction implements ResponseAction {
        @Override
        public void execute() throws Exception {
            System.out.println("执行数据库扩容...");
            Thread.sleep(2000); // 模拟扩容过程
            System.out.println("数据库扩容完成");
        }
    }
    
    // 服务重启动作
    public static class RestartServiceAction implements ResponseAction {
        @Override
        public void execute() throws Exception {
            System.out.println("执行服务重启...");
            Thread.sleep(3000); // 模拟重启过程
            System.out.println("服务重启完成");
        }
    }
    
    // 熔断器动作
    public static class CircuitBreakerAction implements ResponseAction {
        @Override
        public void execute() throws Exception {
            System.out.println("启用熔断器...");
            Thread.sleep(1000); // 模拟熔断器启用过程
            System.out.println("熔断器已启用");
        }
    }
    
    // 监控仪表板
    public static class MonitoringDashboard {
        private MetricCollector collector;
        private AlertSystem alertSystem;
        
        public MonitoringDashboard(MetricCollector collector, AlertSystem alertSystem) {
            this.collector = collector;
            this.alertSystem = alertSystem;
        }
        
        public void display() {
            System.out.println("\n=== 监控仪表板 ===");
            System.out.println("时间: " + new Date());
            
            // 显示关键指标
            System.out.println("\n关键指标:");
            for (Metric metric : collector.getAllMetrics()) {
                System.out.printf("%-30s: %.2f %s%n", 
                    metric.getName(), metric.getValue(), metric.getType());
            }
            
            // 显示活跃报警
            List<Alert> activeAlerts = alertSystem.getActiveAlerts();
            if (!activeAlerts.isEmpty()) {
                System.out.println("\n活跃报警:");
                for (Alert alert : activeAlerts) {
                    System.out.printf("[%s] %s: %s (当前值: %.2f)%n", 
                        alert.getSeverity(), alert.getRuleName(), alert.getMessage(), alert.getValue());
                }
            } else {
                System.out.println("\n当前无活跃报警");
            }
        }
    }
    
    // 主方法 - 演示监控与报警系统
    public static void main(String[] args) throws InterruptedException {
        // 创建监控数据采集器
        MetricCollector collector = new MetricCollector();
        
        // 创建应用和中间件指标监控
        ApplicationMetrics appMetrics = new ApplicationMetrics(collector);
        Middleware middlewareMetrics = new MiddlewareMetrics(collector);
        
        // 创建通知服务
        NotificationService notificationService = new NotificationService();
        
        // 创建报警系统
        AlertSystem alertSystem = new AlertSystem(notificationService);
        
        // 添加报警规则
        alertSystem.addRule(new AlertRule(
            "high_database_connections", 
            "database_connections_active", 
            ">=", 
            90, 
            "CRITICAL", 
            "数据库连接数过高"
        ));
        
        alertSystem.addRule(new AlertRule(
            "high_memory_usage", 
            "jvm_memory_used_bytes", 
            ">=", 
            0.9, 
            "WARNING", 
            "JVM内存使用率过高"
        ));
        
        alertSystem.addRule(new AlertRule(
            "high_error_rate", 
            "app_errors_total", 
            ">=", 
            100, 
            "CRITICAL", 
            "应用错误数过高"
        ));
        
        // 创建自动化响应
        AutomatedResponse automatedResponse = new AutomatedResponse(alertSystem);
        
        // 创建监控仪表板
        MonitoringDashboard dashboard = new MonitoringDashboard(collector, alertSystem);
        
        // 模拟系统运行
        for (int i = 0; i < 20; i++) {
            // 模拟HTTP请求
            appMetrics.recordHttpRequest("GET", "/api/users", 200, 0.05);
            
            // 模拟数据库连接数变化
            int dbConnections = 50 + (int)(Math.random() * 50);
            middlewareMetrics.updateDatabaseMetrics(dbConnections, 100);
            
            // 模拟缓存命中
            if (Math.random() > 0.3) {
                middlewareMetrics.recordCacheHit();
            } else {
                middlewareMetrics.recordCacheMiss();
            }
            
            // 模拟JVM内存使用
            long memoryUsed = (long)(Runtime.getRuntime().totalMemory() * 0.6 + Math.random() * 0.3);
            int threadCount = Thread.activeCount();
            appMetrics.updateJvmMetrics(memoryUsed, threadCount);
            
            // 模拟错误
            if (i > 10 && Math.random() > 0.8) {
                appMetrics.recordHttpRequest("POST", "/api/orders", 500, 0.1);
            }
            
            // 每5秒显示一次仪表板
            if (i % 5 == 0) {
                dashboard.display();
                
                // 评估报警规则
                alertSystem.evaluateMetrics(collector.getAllMetrics());
                
                // 处理自动化响应
                automatedResponse.processAlerts();
            }
            
            Thread.sleep(1000);
        }
        
        // 最终状态
        dashboard.display();
        
        // 显示通知历史
        System.out.println("\n=== 通知历史 ===");
        notificationService.getNotifications().forEach(System.out::println);
    }
}

在这里插入图片描述

总结

架构评审是一个复杂而系统的过程,需要从多个维度全面考量。在实际项目中,应根据项目所处阶段与业务目标,合理权衡各维度的重要性,制定出最合适的架构方案。随着项目的发展,也可以借助公司中间件与容器的标准化,逐步将一些架构工作交由专业团队负责,让业务代码更加专注于业务逻辑的实现。

在项目初期,可以适当简化一些架构设计,但必须对关键问题有清晰的认识与规划,确保系统能够在未来的发展中持续满足业务需求,实现稳定、高效、可扩展的目标。


网站公告

今日签到

点亮在社区的每一天
去签到