如何加快批量课程数据的HTTP POST请求速度?
优化批量课程插入速度的方案
先定位性能瓶颈
先加简单计时代码,快速区分是序列化还是HTTP请求拖慢了速度:
public static void saveCourses(List<Course> courses) throws URISyntaxException, IOException, InterruptedException { Gson gson = new Gson(); HttpClient httpClient = HttpClient.newHttpClient(); URI uri = new URI("http://localhost:8080/course/save"); for (int i = 0; i < courses.size(); i++) { long serializeStart = System.currentTimeMillis(); String json = gson.toJson(courses.get(i)); long serializeEnd = System.currentTimeMillis(); System.out.println("序列化耗时:" + (serializeEnd - serializeStart) + "ms"); long requestStart = System.currentTimeMillis(); HttpRequest httpRequest = HttpRequest.newBuilder() .uri(uri) .header("Content-Type", "application/json") .POST(BodyPublishers.ofString(json)) .build(); httpClient.send(httpRequest, BodyHandlers.ofString()); long requestEnd = System.currentTimeMillis(); System.out.println("请求耗时:" + (requestEnd - requestStart) + "ms"); } }
跑100条左右的数据就能明确瓶颈,大概率是HTTP请求的往返开销占了主要时间。
核心优化措施
1. 复用重复创建的实例
你的代码每次循环都新建Gson和HttpClient,这两个类都是线程安全且设计为可复用的,重复创建会带来不必要的开销:
public static void saveCourses(List<Course> courses) throws URISyntaxException, IOException, InterruptedException { // 只初始化一次,循环内复用 Gson gson = new Gson(); HttpClient httpClient = HttpClient.newHttpClient(); URI uri = new URI("http://localhost:8080/course/save"); for (Course course : courses) { String json = gson.toJson(course); HttpRequest httpRequest = HttpRequest.newBuilder() .uri(uri) .header("Content-Type", "application/json") .POST(BodyPublishers.ofString(json)) .build(); httpClient.send(httpRequest, BodyHandlers.ofString()); } }
2. 改用异步请求并行发送
同步请求需要等待前一个响应返回才发下一个,改成异步并行处理能大幅压缩总耗时:
public static void saveCourses(List<Course> courses) throws URISyntaxException, IOException, InterruptedException { Gson gson = new Gson(); HttpClient httpClient = HttpClient.newHttpClient(); URI uri = new URI("http://localhost:8080/course/save"); List<CompletableFuture<Void>> futures = new ArrayList<>(); for (Course course : courses) { String json = gson.toJson(course); HttpRequest httpRequest = HttpRequest.newBuilder() .uri(uri) .header("Content-Type", "application/json") .POST(BodyPublishers.ofString(json)) .build(); // 异步发送,不阻塞后续请求 CompletableFuture<Void> future = httpClient.sendAsync(httpRequest, BodyHandlers.ofString()) .thenAccept(response -> { // 可在这里记录请求成功日志 }) .exceptionally(e -> { // 处理请求异常,比如打印错误 e.printStackTrace(); return null; }); futures.add(future); } // 等待所有异步请求完成 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); }
注意:可以控制并行数量(比如每批50条),避免过度压垮后端服务。
3. 后端新增批量保存接口(最有效的优化)
单条请求的HTTP开销是最大瓶颈,直接让后端提供批量插入接口,把15000次请求压缩到几百次:
- 后端新增
POST /course/save-batch接口,接收List<Course>格式的JSON数组 - 前端改成批量序列化、批量发送:
public static void saveCourses(List<Course> courses) throws URISyntaxException, IOException, InterruptedException { Gson gson = new Gson(); HttpClient httpClient = HttpClient.newHttpClient(); URI uri = new URI("http://localhost:8080/course/save-batch"); // 分批次处理,比如每50条一批 int batchSize = 50; for (int i = 0; i < courses.size(); i += batchSize) { int end = Math.min(i + batchSize, courses.size()); List<Course> batch = courses.subList(i, end); String json = gson.toJson(batch); HttpRequest httpRequest = HttpRequest.newBuilder() .uri(uri) .header("Content-Type", "application/json") .POST(BodyPublishers.ofString(json)) .build(); httpClient.send(httpRequest, BodyHandlers.ofString()); } }
这种优化能把总耗时从分钟级降到秒级,因为HTTP请求次数减少了几百倍。
4. 序列化优化(若序列化是瓶颈)
如果计时后发现toJson耗时较高:
- 用
GsonBuilder配置精简的序列化规则,比如只序列化必要字段 - 替换为更快的JSON库,比如Jackson或Fastjson(根据项目依赖选择)
额外建议
- 数据库层面:后端批量插入时,使用JDBC的
addBatch+executeBatch批量操作,进一步提升数据库写入速度 - 缓存优化:若PDF内容不会频繁更新,可缓存解析后的Course列表,避免重复下载解析PDF
内容的提问来源于stack exchange,提问作者daytripper
相关产品推荐
相关产品推荐

