【架构实战】接口性能优化:异步化/并行化/缓存化

一、接口性能优化概述

接口性能优化是提升用户体验的关键:

优化方向:

  • 减少等待时间(同步→异步)
  • 并行处理(串行→并行)
  • 减少计算量(缓存、预计算)
  • 减少IO(合并请求、压缩)

二、异步化优化

1. 异步Servlet

java 复制代码
@RestController
public class AsyncOrderController {
    
    @Autowired
    private AsyncOrderService asyncOrderService;
    
    @GetMapping("/api/orders/{id}")
    public Callable<Order> getOrderAsync(@PathVariable Long id) {
        return () -> {
            // 在另外的线程池中执行
            return asyncOrderService.getOrder(id);
        };
    }
    
    @GetMapping("/api/orders/{id}")
    public CompletableFuture<Order> getOrderCompletable(@PathVariable Long id) {
        return CompletableFuture.supplyAsync(() -> {
            return asyncOrderService.getOrder(id);
        });
    }
}

2. 异步调用

java 复制代码
@Service
public class OrderDetailService {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private ProductService productService;
    
    @Autowired
    private LogisticsService logisticsService;
    
    // 同步方式(串行,耗时长)
    public OrderDetail getOrderDetailSync(Long orderId) {
        Order order = orderService.getById(orderId);        // 10ms
        User user = userService.getUser(order.getUserId()); // 20ms
        Product product = productService.getProduct(order.getProductId()); // 15ms
        Logistics logistics = logisticsService.getLogistics(order.getLogisticsId()); // 30ms
        
        return new OrderDetail(order, user, product, logistics); // 总计:75ms
    }
    
    // 异步方式(并行,耗时短)
    public CompletableFuture<OrderDetail> getOrderDetailAsync(Long orderId) {
        CompletableFuture<Order> orderFuture = 
            CompletableFuture.supplyAsync(() -> orderService.getById(orderId));
        
        CompletableFuture<User> userFuture = 
            CompletableFuture.supplyAsync(() -> userService.getUser(1001L));
        
        CompletableFuture<Product> productFuture = 
            CompletableFuture.supplyAsync(() -> productService.getProduct(2001L));
        
        CompletableFuture<Logistics> logisticsFuture = 
            CompletableFuture.supplyAsync(() -> logisticsService.getLogistics("LP123"));
        
        return CompletableFuture.allOf(
            orderFuture, userFuture, productFuture, logisticsFuture
        ).thenApply(v -> new OrderDetail(
            orderFuture.join(),
            userFuture.join(),
            productFuture.join(),
            logisticsFuture.join()
        )); // 总耗时:max(10,20,15,30) = 30ms
    }
}

3. 异步消息

java 复制代码
@Service
public class OrderAsyncService {
    
    @Autowired
    private KafkaTemplate kafkaTemplate;
    
    // 下单异步化
    public String createOrderAsync(OrderRequest request) {
        // 1. 生成预订单号
        String orderNo = generateOrderNo();
        
        // 2. 发送异步消息处理
        kafkaTemplate.send("order:create", orderNo, request);
        
        // 3. 立即返回
        return orderNo;
    }
}

@Component
public class OrderMessageConsumer {
    
    @KafkaListener(topics = "order:create")
    public void handleOrderCreate(ConsumerRecord<String, OrderRequest> record) {
        // 在后台处理订单
        Order order = processOrder(record.value());
        saveOrder(order);
        notifyUser(order);
    }
}

三、并行化优化

1. CompletableFuture并行

java 复制代码
@Service
public class HomePageService {
    
    @Autowired
    private BannerService bannerService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private ProductService productService;
    @Autowired
    private RecommendService recommendService;
    
    // 首页数据(串行)
    public HomeData getHomeDataSync() {
        List<Banner> banners = bannerService.getBanners();           // 100ms
        List<Category> categories = categoryService.getCategories();  // 80ms
        List<Product> hotProducts = productService.getHotProducts();   // 120ms
        List<Product> recommendProducts = recommendService.getRecommend(); // 150ms
        
        return new HomeData(banners, categories, hotProducts, recommendProducts);
        // 总耗时:100+80+120+150 = 450ms
    }
    
    // 首页数据(并行)
    public HomeData getHomeDataParallel() {
        long start = System.currentTimeMillis();
        
        CompletableFuture<List<Banner>> bannersFuture = 
            CompletableFuture.supplyAsync(() -> bannerService.getBanners());
        
        CompletableFuture<List<Category>> categoriesFuture = 
            CompletableFuture.supplyAsync(() -> categoryService.getCategories());
        
        CompletableFuture<List<Product>> hotProductsFuture = 
            CompletableFuture.supplyAsync(() -> productService.getHotProducts());
        
        CompletableFuture<List<Product>> recommendFuture = 
            CompletableFuture.supplyAsync(() -> recommendService.getRecommend());
        
        // 等待所有完成
        CompletableFuture.allOf(
            bannersFuture, categoriesFuture, hotProductsFuture, recommendFuture
        ).join();
        
        HomeData data = new HomeData(
            bannersFuture.join(),
            categoriesFuture.join(),
            hotProductsFuture.join(),
            recommendFuture.join()
        );
        
        System.out.println("并行耗时: " + (System.currentTimeMillis() - start) + "ms");
        return data;
        // 总耗时:max(100,80,120,150) = 150ms
    }
}

2. 线程池优化

java 复制代码
@Configuration
public class ThreadPoolConfig {
    
    @Bean("asyncExecutor")
    public ThreadPoolTaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

@Service
public class ParallelService {
    
    @Async("asyncExecutor")
    public CompletableFuture<Result> processTask(String taskId) {
        // 异步任务
        return CompletableFuture.completedFuture(process(taskId));
    }
}

四、缓存化优化

1. 多级缓存

java 复制代码
@Service
public class ProductCacheService {
    
    // L1: 本地缓存(Caffeine)
    private final LoadingCache<Long, Product> localCache = Caffeine.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .build(id -> loadFromRedis(id));
    
    // L2: Redis缓存
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    public Product getProduct(Long id) {
        // 1. 查本地缓存
        Product product = localCache.getIfPresent(id);
        if (product != null) {
            return product;
        }
        
        // 2. 查Redis
        String key = "product:" + id;
        product = (Product) redisTemplate.opsForValue().get(key);
        
        if (product != null) {
            localCache.put(id, product);
            return product;
        }
        
        // 3. 查数据库
        product = productMapper.selectById(id);
        
        if (product != null) {
            redisTemplate.opsForValue().set(key, product, 30, TimeUnit.MINUTES);
            localCache.put(id, product);
        }
        
        return product;
    }
}

2. 预计算缓存

java 复制代码
@Service
public class StatisticsCacheService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // 定时预计算
    @Scheduled(cron = "0 0 * * * ?") // 每小时执行
    public void precomputeStatistics() {
        // 预计算今日销售统计
        Map<String, Object> stats = calculateDailyStats();
        
        String key = "stats:daily:" + LocalDate.now();
        redisTemplate.opsForValue().set(key, stats, 25, TimeUnit.HOURS);
    }
    
    // 直接读取缓存
    public Map<String, Object> getDailyStats() {
        String key = "stats:daily:" + LocalDate.now();
        return (Map<String, Object>) redisTemplate.opsForValue().get(key);
    }
}

3. 热点数据缓存

java 复制代码
@Service
public class HotProductService {
    
    // 热点商品自动发现
    private final LoadingCache<Long, Product> hotProductCache = Caffeine.newBuilder()
        .maximumSize(100)
        .expireAfterWrite(1, TimeUnit.MINUTES)
        .refreshAfterWrite(30, TimeUnit.SECONDS)
        .build(id -> {
            // 热点商品走数据库,但使用更长的过期时间
            Product product = productMapper.selectById(id);
            return product;
        });
    
    public Product getHotProduct(Long id) {
        return hotProductCache.get(id);
    }
}

五、数据库优化

1. 批量查询

java 复制代码
@Service
public class ProductBatchService {
    
    @Autowired
    private ProductMapper productMapper;
    
    // 批量查询
    public List<Product> getProductsByIds(List<Long> ids) {
        // 分批查询,每批100个
        List<Product> results = new ArrayList<>();
        List<List<Long>> batches = Lists.partition(ids, 100);
        
        for (List<Long> batch : batches) {
            List<Product> products = productMapper.selectBatchIds(batch);
            results.addAll(products);
        }
        
        return results;
    }
}

2. 乐观锁

java 复制代码
@Service
public class InventoryOptimisticLockService {
    
    @Autowired
    private InventoryMapper inventoryMapper;
    
    // 乐观锁扣减库存
    public boolean deductStock(Long productId, Integer quantity) {
        int retries = 3;
        
        while (retries > 0) {
            Inventory inventory = inventoryMapper.selectById(productId);
            
            if (inventory.getStock() < quantity) {
                throw new BusinessException("库存不足");
            }
            
            // CAS更新
            int result = inventoryMapper.updateStockOptimistic(
                productId, 
                inventory.getVersion(), 
                inventory.getStock() - quantity
            );
            
            if (result > 0) {
                return true;
            }
            
            retries--;
        }
        
        throw new BusinessException("库存扣减失败,请重试");
    }
}

@Mapper
public interface InventoryMapper {
    
    @Update("UPDATE inventory SET stock = #{stock}, version = version + 1 " +
            "WHERE id = #{id} AND version = #{version}")
    int updateStockOptimistic(@Param("id") Long id, 
                               @Param("version") Integer version, 
                               @Param("stock") Integer stock);
}

六、网络优化

1. 合并请求

java 复制代码
@Service
public class BatchRequestService {
    
    // 批量接口
    @PostMapping("/api/batch")
    public List<Object> batchRequest(@RequestBody List<Request> requests) {
        return requests.parallelStream()
            .map(this::processSingleRequest)
            .collect(Collectors.toList());
    }
}

2. 数据压缩

java 复制代码
@Configuration
public class CompressionConfig {
    
    @Bean
    public FilterRegistrationBean<GzipCompressionFilter> compressionFilter() {
        FilterRegistrationBean<GzipCompressionFilter> registration = 
            new FilterRegistrationBean<>();
        registration.addUrlPatterns("/*");
        registration.setFilter(new GzipCompressionFilter());
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registration;
    }
}

七、总结

接口性能优化三大方向:

  • 异步化:非核心流程异步处理
  • 并行化:多任务并行执行
  • 缓存化:多级缓存减少计算

优化效果:

  • 串行75ms → 并行30ms(提升60%)
  • 单次查询 → 缓存命中(提升90%)

最佳实践:

  1. 先监控定位瓶颈
  2. 从简单优化开始
  3. 异步、并行、缓存组合使用

个人观点,仅供参考

相关推荐
一个有温度的技术博主2 小时前
Eureka注册中心:微服务架构的“智能通讯录”
微服务·架构
Aray12342 小时前
Redis服务端分片(Redis Cluster)详解
数据库·redis·缓存
墨香幽梦客2 小时前
全站HTTPS化实战:SSL证书管理、自动续期与TLS 1.3性能优化详解
性能优化·https·ssl
喜欢流萤吖~3 小时前
SpringBoot 性能优化实战
spring boot·后端·性能优化
企业架构师老王3 小时前
2026年国内AI Agent选型指南:企业数字化转型中的非侵入式架构方案深度评测
人工智能·ai·架构
JZC_xiaozhong3 小时前
2026技术深潜:解构Spring Boot与Spring Framework架构,透视KPaaS集成平台底层逻辑
大数据·spring boot·spring·架构·数据集成与应用集成·异构系统集成·应用对接
8Qi83 小时前
Elasticsearch实战篇:索引库、文档与JavaRestClient操作指南
java·大数据·elasticsearch·搜索引擎·微服务·架构·springcloud
爱莉希雅&&&4 小时前
Docker 部署 MySQL 双主双从同步架构详细笔记
linux·运维·数据库·mysql·docker·架构·主从同步
Alex艾力的IT数字空间11 小时前
在 Kylin(麒麟)操作系统上搭建 Docker 环境
大数据·运维·缓存·docker·容器·负载均衡·kylin