接口性能优化实战

从毫秒到微秒:高性能接口优化全攻略

🎯 面试重点

📖 性能指标体系

关键性能指标(KPI)

/**
 * 接口性能核心指标
 */
public class PerformanceMetrics {
    
    // 1. 响应时间(Latency)
    /*
     * P50(中位数):< 100ms
     * P90(90分位):< 200ms  
     * P99(99分位):< 500ms
     * P999(99.9分位):< 1000ms
     */
    
    // 2. 吞吐量(Throughput)
    /*
     * QPS(Query Per Second):每秒请求数
     * TPS(Transaction Per Second):每秒事务数
     * 并发数:同时处理的请求数
     */
    
    // 3. 错误率(Error Rate)
    /*
     * HTTP错误率:< 0.1%
     * 业务错误率:< 0.5%
     * 超时率:< 0.01%
     */
    
    // 4. 资源使用率
    /*
     * CPU使用率:< 70%
     * 内存使用率:< 80%
     * 磁盘IO:< 70%
     * 网络带宽:< 80%
     */
}

性能监控体系

# 监控配置示例
monitoring:
  metrics:
    # 应用层指标
    - name: api_response_time
      type: histogram
      labels: [method, path, status]
      buckets: [10, 50, 100, 200, 500, 1000, 2000]  # 单位ms
    
    - name: api_qps
      type: counter
      labels: [method, path]
    
    # 系统层指标
    - name: system_cpu_usage
      type: gauge
    
    - name: system_memory_usage
      type: gauge
    
    # 中间件指标
    - name: redis_command_duration
      type: histogram
      labels: [command]
    
    - name: mysql_query_duration
      type: histogram
      labels: [table, operation]
  
  alert:
    rules:
      - alert: HighResponseTime
        expr: histogram_quantile(0.99, rate(api_response_time_bucket[5m])) > 500
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "接口响应时间过高"
          description: "&#123;&#123; $labels.path &#125;&#125; P99响应时间超过500ms"

📖 性能分析工具

1. 压测工具

# Apache Bench (ab)
ab -n 10000 -c 100 -T 'application/json' -p data.json http://api.example.com/v1/users

# wrk(更强大)
wrk -t12 -c400 -d30s --latency http://api.example.com/v1/users

# JMeter(功能全面)
# 图形界面,支持复杂场景

# 自定义压测脚本(推荐)
# 使用Python asyncio或Go实现,更灵活

2. 性能分析工具

# 1. JVM分析工具
jstack <pid>                   # 线程栈分析
jmap -heap <pid>              # 堆内存分析  
jstat -gc <pid> 1000 10       # GC统计

# 2. 系统分析工具
top -H -p <pid>               # 线程CPU使用
vmstat 1                      # 系统资源
iostat -x 1                   # 磁盘IO
sar -n DEV 1                  # 网络流量

# 3. 网络分析工具
tcpdump -i eth0 port 8080 -w capture.pcap  # 抓包
ss -tnlp                                     # 连接状态
netstat -an | grep TIME_WAIT | wc -l        # TIME_WAIT连接数

# 4. 应用性能监控(APM)
# SkyWalking、Pinpoint、Arthas
arthas-boot.jar                              # Java诊断神器

3. 火焰图分析

# 生成CPU火焰图
# 1. 使用async-profiler
./profiler.sh -d 60 -f flamegraph.svg <pid>

# 2. 使用perf(Linux)
perf record -F 99 -p <pid> -g -- sleep 60
perf script | ./stackcollapse-perf.pl > out.perf-folded
./flamegraph.pl out.perf-folded > flamegraph.svg

# 3. 使用Java Flight Recorder(JFR)
jcmd <pid> JFR.start duration=60s filename=recording.jfr
jcmd <pid> JFR.dump filename=recording.jfr

📖 常见性能瓶颈

1. CPU密集型瓶颈

/**
 * CPU瓶颈示例
 */
public class CPUBottleneck {
    
    // 示例1:复杂计算未优化
    public BigDecimal calculateTax(BigDecimal amount) {
        // ❌ 低效:每次重新计算
        for (int i = 0; i < 1000; i++) {
            BigDecimal rate = getTaxRateFromDB();  // 频繁查库
            amount = amount.multiply(rate);
        }
        return amount;
    }
    
    // 优化:缓存 + 批量计算
    private static final Map<String, BigDecimal> TAX_RATE_CACHE = new ConcurrentHashMap<>();
    
    public BigDecimal calculateTaxOptimized(BigDecimal amount) {
        // ✅ 优化:缓存税率,批量计算
        BigDecimal rate = TAX_RATE_CACHE.computeIfAbsent("current", k -> getTaxRateFromDB());
        return amount.multiply(rate).multiply(BigDecimal.valueOf(1000));
    }
    
    // 示例2:频繁的JSON序列化/反序列化
    public User parseUserJson(String json) {
        // ❌ 每次创建ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(json, User.class);
    }
    
    // 优化:重用ObjectMapper(线程安全)
    private static final ObjectMapper MAPPER = new ObjectMapper();
    
    public User parseUserJsonOptimized(String json) throws Exception {
        // ✅ 重用ObjectMapper
        return MAPPER.readValue(json, User.class);
    }
}

2. 内存密集型瓶颈

/**
 * 内存瓶颈示例
 */
public class MemoryBottleneck {
    
    // 示例1:大对象频繁创建
    public List<User> getUsers() {
        // ❌ 每次创建大ArrayList
        List<User> users = new ArrayList<>(1000000);  // 预分配过大
        for (int i = 0; i < 1000; i++) {
            users.add(new User("name" + i, i));
        }
        return users;
    }
    
    // 优化:合适的大小 + 流式处理
    public List<User> getUsersOptimized() {
        // ✅ 合适的大小 + 考虑分页
        List<User> users = new ArrayList<>(1000);
        for (int i = 0; i < 1000; i++) {
            users.add(new User("name" + i, i));
        }
        return users;
    }
    
    // 更好的优化:流式处理
    public Stream<User> getUserStream() {
        return IntStream.range(0, 1000)
            .mapToObj(i -> new User("name" + i, i));
    }
    
    // 示例2:内存泄漏
    public class MemoryLeak {
        private static final Map<String, Object> CACHE = new HashMap<>();
        
        public void cacheData(String key, Object value) {
            CACHE.put(key, value);  // ❌ 无限增长,导致内存泄漏
        }
        
        // 优化:使用WeakHashMap或设置过期时间
        private static final Map<String, Object> OPTIMIZED_CACHE = 
            Collections.synchronizedMap(new LinkedHashMap<String, Object>(100, 0.75f, true) {
                @Override
                protected boolean removeEldestEntry(Map.Entry eldest) {
                    return size() > 1000;  // ✅ 限制大小
                }
            });
    }
}

3. I/O密集型瓶颈

/**
 * I/O瓶颈示例
 */
public class IOBottleneck {
    
    // 示例1:N+1查询问题
    public List<OrderDTO> getUserOrders(Long userId) {
        // ❌ N+1查询
        List<Order> orders = orderRepository.findByUserId(userId);
        List<OrderDTO> dtos = new ArrayList<>();
        for (Order order : orders) {
            User user = userRepository.findById(order.getUserId());  // 每次查询用户
            OrderDTO dto = convert(order, user);
            dtos.add(dto);
        }
        return dtos;
    }
    
    // 优化1:JOIN查询
    public List<OrderDTO> getUserOrdersOptimized(Long userId) {
        // ✅ 一次查询,使用JOIN
        return orderRepository.findOrdersWithUser(userId);
    }
    
    // 优化2:批量查询
    public List<OrderDTO> getUserOrdersBatch(Long userId) {
        List<Order> orders = orderRepository.findByUserId(userId);
        List<Long> userIds = orders.stream()
            .map(Order::getUserId)
            .distinct()
            .collect(Collectors.toList());
        
        // ✅ 批量查询用户
        Map<Long, User> userMap = userRepository.findByIds(userIds)
            .stream()
            .collect(Collectors.toMap(User::getId, Function.identity()));
        
        return orders.stream()
            .map(order -> convert(order, userMap.get(order.getUserId())))
            .collect(Collectors.toList());
    }
    
    // 示例2:频繁的小文件读写
    public void processFiles(List<String> filePaths) {
        for (String path : filePaths) {
            // ❌ 每次打开关闭文件
            String content = Files.readString(Path.of(path));
            processContent(content);
        }
    }
    
    // 优化:批量读写
    public void processFilesOptimized(List<String> filePaths) {
        // ✅ 使用NIO批量读取
        List<CompletableFuture<Void>> futures = filePaths.stream()
            .map(path -> CompletableFuture.runAsync(() -> {
                String content = Files.readString(Path.of(path));
                processContent(content);
            }))
            .collect(Collectors.toList());
        
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
    }
}

📖 优化策略与实践

1. 数据库优化

-- 优化前:慢查询
SELECT * FROM orders 
WHERE user_id = 123 
  AND status = 'PAID'
  AND created_at > '2023-01-01'
ORDER BY created_at DESC 
LIMIT 100;

-- 优化1:添加复合索引
CREATE INDEX idx_user_status_time ON orders(user_id, status, created_at);

-- 优化2:使用覆盖索引
CREATE INDEX idx_user_status_time_covering ON orders(user_id, status, created_at, amount, product_id);

-- 优化3:分页优化(游标分页)
SELECT * FROM orders 
WHERE user_id = 123 
  AND status = 'PAID'
  AND created_at < '2023-06-01'  -- 上一页最后一条的时间
  AND id < 1000                  -- 上一页最后一条的ID
ORDER BY created_at DESC, id DESC 
LIMIT 20;

-- 优化4:读写分离
-- 写操作:主库
-- 读操作:从库
-- 配置:Spring Boot + dynamic-datasource

2. 缓存优化

/**
 * 多级缓存架构
 */
public class MultiLevelCache {
    
    // L1: 本地缓存(Caffeine)
    private Cache<String, Object> localCache = Caffeine.newBuilder()
        .maximumSize(10000)
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .recordStats()
        .build();
    
    // L2: Redis集群缓存
    private RedisTemplate<String, Object> redisTemplate;
    
    // L3: 数据库
    private UserRepository userRepository;
    
    public User getUserWithCache(Long userId) {
        String cacheKey = "user:" + userId;
        
        // 1. 尝试本地缓存
        User user = (User) localCache.getIfPresent(cacheKey);
        if (user != null) {
            return user;
        }
        
        // 2. 尝试Redis缓存
        user = (User) redisTemplate.opsForValue().get(cacheKey);
        if (user != null) {
            // 回填本地缓存
            localCache.put(cacheKey, user);
            return user;
        }
        
        // 3. 查询数据库
        user = userRepository.findById(userId).orElse(null);
        if (user != null) {
            // 写入缓存(异步)
            CompletableFuture.runAsync(() -> {
                redisTemplate.opsForValue().set(cacheKey, user, 30, TimeUnit.MINUTES);
                localCache.put(cacheKey, user);
            });
        }
        
        return user;
    }
    
    // 缓存击穿解决方案
    public User getUserWithBloomFilter(Long userId) {
        // 使用布隆过滤器判断是否存在
        if (!bloomFilter.mightContain(userId)) {
            return null;  // 一定不存在
        }
        
        // 缓存穿透:缓存空值
        String cacheKey = "user:" + userId;
        User user = (User) redisTemplate.opsForValue().get(cacheKey);
        if (user != null) {
            if (user.getId() == null) {  // 空值标记
                return null;
            }
            return user;
        }
        
        // 查询数据库
        user = userRepository.findById(userId).orElse(null);
        if (user == null) {
            // 缓存空值,防止缓存穿透
            redisTemplate.opsForValue().set(cacheKey, new User(), 5, TimeUnit.MINUTES);
        } else {
            redisTemplate.opsForValue().set(cacheKey, user, 30, TimeUnit.MINUTES);
        }
        
        return user;
    }
}

3. 异步与并发优化

/**
 * 异步处理优化
 */
public class AsyncOptimization {
    
    // 优化前:同步阻塞
    public OrderResult createOrder(OrderRequest request) {
        // 1. 验证库存(同步)
        boolean valid = inventoryService.validate(request.getProductId(), request.getQuantity());
        if (!valid) {
            throw new BusinessException("库存不足");
        }
        
        // 2. 扣减库存(同步)
        inventoryService.deduct(request.getProductId(), request.getQuantity());
        
        // 3. 创建订单(同步)
        Order order = orderService.create(request);
        
        // 4. 发送消息(同步)
        messageService.sendOrderCreated(order);
        
        // 5. 更新用户统计(同步)
        userStatService.updateOrderCount(request.getUserId());
        
        return convert(order);
    }
    
    // 优化后:异步非阻塞
    @Transactional
    public CompletableFuture<OrderResult> createOrderAsync(OrderRequest request) {
        // 1. 异步验证库存
        CompletableFuture<Boolean> validateFuture = CompletableFuture.supplyAsync(
            () -> inventoryService.validate(request.getProductId(), request.getQuantity()),
            threadPool
        );
        
        // 2. 链式异步操作
        return validateFuture.thenCompose(valid -> {
            if (!valid) {
                return CompletableFuture.failedFuture(new BusinessException("库存不足"));
            }
            
            // 异步扣减库存
            return CompletableFuture.runAsync(
                () -> inventoryService.deduct(request.getProductId(), request.getQuantity()),
                threadPool
            );
        }).thenApply(v -> {
            // 同步创建订单(需要事务)
            return orderService.create(request);
        }).thenApply(order -> {
            // 异步发送消息(不需要事务)
            CompletableFuture.runAsync(
                () -> messageService.sendOrderCreated(order),
                threadPool
            );
            
            // 异步更新统计
            CompletableFuture.runAsync(
                () -> userStatService.updateOrderCount(request.getUserId()),
                threadPool
            );
            
            return convert(order);
        }).exceptionally(ex -> {
            // 异常处理
            log.error("创建订单失败", ex);
            throw new BusinessException("订单创建失败");
        });
    }
    
    // 批量处理优化
    public void batchProcessOrders(List<Order> orders) {
        // 优化前:顺序处理
        for (Order order : orders) {
            processOrder(order);  // 慢!
        }
        
        // 优化后:并行流处理
        orders.parallelStream()
            .forEach(this::processOrder);
        
        // 更好的优化:分批处理 + 并行
        int batchSize = 100;
        List<List<Order>> batches = ListUtils.partition(orders, batchSize);
        
        batches.parallelStream()
            .forEach(batch -> {
                batch.forEach(this::processOrder);
            });
    }
}

4. JVM优化

# JVM参数优化配置
# application.yml
jvm:
  options: >
    -Xms4g -Xmx4g                     # 堆内存(生产环境设相同值,避免动态调整)
    -XX:MaxMetaspaceSize=512m         # 元空间
    -XX:MaxDirectMemorySize=1g        # 直接内存
    -Xmn2g                            # 新生代大小(建议1/2 ~ 1/3堆大小)
    -XX:SurvivorRatio=8               # Eden:Survivor比例
    -XX:+UseG1GC                      # 使用G1垃圾回收器
    -XX:MaxGCPauseMillis=200          # 目标暂停时间
    -XX:InitiatingHeapOccupancyPercent=45  # 触发Mixed GC的堆占用率
    -XX:+ParallelRefProcEnabled       # 并行处理引用
    -XX:+HeapDumpOnOutOfMemoryError   # OOM时生成堆转储
    -XX:HeapDumpPath=/tmp/heapdump.hprof
    -XX:+UseCompressedOops            # 压缩普通对象指针
    -XX:+UseCompressedClassPointers   # 压缩类指针
    -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps
    -Xloggc:/tmp/gc.log               # GC日志
    -XX:+UseGCLogFileRotation         # GC日志轮转
    -XX:NumberOfGCLogFiles=5
    -XX:GCLogFileSize=20M
    -Djava.security.egd=file:/dev/./urandom  # 加速随机数生成

5. 网络优化

/**
 * HTTP客户端优化
 */
public class HttpOptimization {
    
    // 优化前:每次创建HttpClient
    public String getWithHttpURLConnection(String url) throws IOException {
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();  // ❌ 每次创建
        con.setRequestMethod("GET");
        // ... 每次建立新连接
    }
    
    // 优化后:连接池
    public class HttpClientPool {
        private static final CloseableHttpClient httpClient;
        
        static {
            // 连接池配置
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(200);                  // 最大连接数
            cm.setDefaultMaxPerRoute(50);         // 每个路由最大连接数
            cm.setValidateAfterInactivity(30000); // 连接空闲30秒后验证
            
            RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(5000)          // 连接超时5秒
                .setSocketTimeout(10000)          // 读取超时10秒
                .setConnectionRequestTimeout(3000) // 从连接池获取连接超时3秒
                .build();
            
            httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .setDefaultRequestConfig(config)
                .setRetryHandler(new DefaultHttpRequestRetryHandler(2, true))  // 重试2次
                .build();
        }
        
        public String getWithPool(String url) throws IOException {
            HttpGet request = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                return EntityUtils.toString(response.getEntity());
            }
        }
    }
    
    // HTTP/2优化
    public class Http2Client {
        private static final HttpClient http2Client = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)      // 使用HTTP/2
            .connectTimeout(Duration.ofSeconds(5))
            .followRedirects(HttpClient.Redirect.NORMAL)
            .build();
        
        public String getWithHttp2(String url) throws Exception {
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(10))
                .header("Accept-Encoding", "gzip")  // 启用压缩
                .build();
            
            HttpResponse<String> response = http2Client.send(request, 
                HttpResponse.BodyHandlers.ofString());
            return response.body();
        }
    }
}

📖 实战案例

案例1:商品详情页优化

/**
 * 商品详情页优化:从200ms到50ms
 */
public class ProductDetailOptimization {
    
    // 优化前:200ms
    public ProductDetail getProductDetail(Long productId) {
        // 1. 查询商品基本信息:20ms
        Product product = productRepository.findById(productId);
        
        // 2. 查询商品SKU:30ms
        List<Sku> skus = skuRepository.findByProductId(productId);
        
        // 3. 查询商品图片:25ms
        List<Image> images = imageRepository.findByProductId(productId);
        
        // 4. 查询商品评价统计:40ms
        ReviewStats stats = reviewRepository.getStats(productId);
        
        // 5. 查询促销信息:35ms
        Promotion promotion = promotionRepository.findByProductId(productId);
        
        // 6. 查询库存信息:50ms(多个SKU分别查询)
        Map<Long, Integer> inventory = new HashMap<>();
        for (Sku sku : skus) {
            Integer stock = inventoryRepository.getStock(sku.getId());
            inventory.put(sku.getId(), stock);
        }
        
        // 总计:200ms
        return assemble(product, skus, images, stats, promotion, inventory);
    }
    
    // 优化后:50ms
    public ProductDetail getProductDetailOptimized(Long productId) {
        // 使用CompletableFuture并行查询
        CompletableFuture<Product> productFuture = CompletableFuture.supplyAsync(
            () -> productRepository.findById(productId), threadPool);
        
        CompletableFuture<List<Sku>> skusFuture = CompletableFuture.supplyAsync(
            () -> skuRepository.findByProductId(productId), threadPool);
        
        CompletableFuture<List<Image>> imagesFuture = CompletableFuture.supplyAsync(
            () -> imageRepository.findByProductId(productId), threadPool);
        
        CompletableFuture<ReviewStats> statsFuture = CompletableFuture.supplyAsync(
            () -> reviewRepository.getStats(productId), threadPool);
        
        CompletableFuture<Promotion> promotionFuture = CompletableFuture.supplyAsync(
            () -> promotionRepository.findByProductId(productId), threadPool);
        
        // 批量查询库存
        CompletableFuture<Map<Long, Integer>> inventoryFuture = skusFuture.thenApply(skus -> {
            List<Long> skuIds = skus.stream().map(Sku::getId).collect(Collectors.toList());
            return inventoryRepository.batchGetStock(skuIds);  // 批量查询:5ms
        });
        
        // 等待所有结果
        CompletableFuture.allOf(
            productFuture, skusFuture, imagesFuture, statsFuture, 
            promotionFuture, inventoryFuture
        ).join();
        
        // 从缓存获取热点数据
        ProductDetail cached = productCache.get(productId);
        if (cached != null && !cached.isExpired()) {
            return cached;  // 缓存命中:1ms
        }
        
        // 组装结果
        ProductDetail detail = assemble(
            productFuture.join(),
            skusFuture.join(),
            imagesFuture.join(),
            statsFuture.join(),
            promotionFuture.join(),
            inventoryFuture.join()
        );
        
        // 异步更新缓存
        CompletableFuture.runAsync(() -> {
            productCache.put(productId, detail);
        }, threadPool);
        
        return detail;
    }
}

案例2:秒杀系统优化

/**
 * 秒杀系统优化:应对瞬时高并发
 */
public class SeckillOptimization {
    
    // 优化前:直接操作数据库
    public boolean seckill(Long productId, Long userId) {
        // 1. 查询库存
        Integer stock = inventoryRepository.getStock(productId);
        if (stock <= 0) {
            return false;
        }
        
        // 2. 扣减库存
        int rows = inventoryRepository.decreaseStock(productId);
        if (rows <= 0) {
            return false;  // 库存不足
        }
        
        // 3. 创建订单
        Order order = createOrder(productId, userId);
        
        return true;
    }
    
    // 问题:数据库成为瓶颈,QPS有限
    
    // 优化后:多层防御
    public boolean seckillOptimized(Long productId, Long userId) {
        // 第一层:请求限流(Nginx层)
        // 配置:limit_req_zone $binary_remote_addr zone=seckill:10m rate=10r/s;
        
        // 第二层:恶意请求过滤(风控)
        if (!riskService.check(userId, productId)) {
            return false;
        }
        
        // 第三层:Redis预减库存(内存操作,快)
        Long stock = redisTemplate.opsForValue().decrement("seckill:stock:" + productId);
        if (stock < 0) {
            // 库存不足,回滚
            redisTemplate.opsForValue().increment("seckill:stock:" + productId);
            return false;
        }
        
        // 第四层:消息队列异步处理
        SeckillMessage message = new SeckillMessage(productId, userId);
        kafkaTemplate.send("seckill-topic", message);
        
        // 立即返回"抢购中",提高用户体验
        return true;
    }
    
    // 消息消费者:异步处理订单
    @KafkaListener(topics = "seckill-topic")
    public void processSeckill(SeckillMessage message) {
        // 1. 检查是否重复购买
        String key = "seckill:user:" + message.getProductId() + ":" + message.getUserId();
        Boolean success = redisTemplate.opsForValue().setIfAbsent(key, "1", 1, TimeUnit.HOURS);
        if (!success) {
            return;  // 已购买过
        }
        
        // 2. 数据库扣减库存(最终一致性)
        int rows = inventoryRepository.decreaseStock(message.getProductId());
        if (rows <= 0) {
            // 库存不足,回滚Redis
            redisTemplate.opsForValue().increment("seckill:stock:" + message.getProductId());
            redisTemplate.delete(key);
            return;
        }
        
        // 3. 创建订单
        Order order = createOrder(message.getProductId(), message.getUserId());
        
        // 4. 发送成功通知
        notifyService.sendSeckillSuccess(message.getUserId(), order);
    }
}

📖 面试真题

Q1: 如何定位接口性能瓶颈?

答:

  1. 监控指标分析:查看响应时间、QPS、错误率等指标
  2. 链路追踪:使用APM工具(SkyWalking、Pinpoint)分析调用链
  3. CPU分析:使用jstack、arthas分析CPU热点
  4. 内存分析:使用jmap、MAT分析内存使用
  5. I/O分析:使用iostat、vmstat分析磁盘和网络IO
  6. 数据库分析:慢查询日志、执行计划分析
  7. 压测验证:使用wrk、JMeter模拟高并发,观察瓶颈点

Q2: 常见的接口性能优化手段有哪些?

答:

  1. 缓存优化:多级缓存、缓存预热、缓存击穿解决方案
  2. 数据库优化:索引优化、分库分表、读写分离
  3. 异步处理:消息队列、异步调用、并行处理
  4. 代码优化:算法优化、避免重复计算、资源复用
  5. JVM优化:合理配置堆内存、选择合适的GC算法
  6. 网络优化:连接池、HTTP/2、CDN加速
  7. 架构优化:微服务拆分、服务治理、负载均衡

Q3: 如何设计一个高性能的API网关?

答:

  1. 异步非阻塞:使用Netty或WebFlux实现异步IO
  2. 连接池管理:合理配置连接池参数
  3. 缓存策略:缓存鉴权结果、响应内容
  4. 限流熔断:实现令牌桶、漏桶等限流算法
  5. 负载均衡:支持多种负载均衡策略
  6. 协议优化:支持HTTP/2、gRPC等高性能协议
  7. 监控告警:实时监控网关性能,快速发现故障

Q4: 如何解决缓存穿透、击穿、雪崩?

答:

  1. 缓存穿透
    • 布隆过滤器判断key是否存在
    • 缓存空值(设置较短过期时间)
    • 接口层校验非法请求
  2. 缓存击穿
    • 热点数据永不过期
    • 互斥锁(Redis setnx)
    • 后台定时更新缓存
  3. 缓存雪崩
    • 设置随机过期时间
    • 缓存高可用(集群、哨兵)
    • 降级熔断机制
    • 缓存预热

Q5: 如何进行有效的压力测试?

答:

  1. 制定压测目标:明确QPS、响应时间、错误率等指标
  2. 准备测试环境:隔离的测试环境,与生产环境配置一致
  3. 设计压测场景:单接口压测、混合场景压测、峰值压力测试
  4. 执行压测:使用wrk、JMeter等工具,逐步增加压力
  5. 监控分析:实时监控系统指标,发现性能瓶颈
  6. 优化验证:实施优化后,重新压测验证效果
  7. 生成报告:记录压测过程、结果和优化建议

📚 延伸阅读


⭐ 重点:性能优化是系统工程,需要从监控、分析、优化、验证全流程入手,平衡开发效率和系统性能