共计 1896 个字符,预计需要花费 5 分钟才能阅读完成。
Java 程序接入 ChatGPT 实战指南
背景痛点
传统的 HTTP 客户端在处理 AI 服务时面临几个主要挑战:

- 长连接管理:ChatGPT 的响应时间可能较长,需要有效管理连接超时和保持活动连接
- JSON 解析效率:大模型返回的 JSON 数据结构复杂,传统解析方式性能较差
- 异步响应处理:需要处理流式响应,避免阻塞主线程
技术选型
对比主流 HTTP 客户端在 ChatGPT 场景的表现:
- Apache HttpClient
- 优点:稳定可靠,连接池成熟
-
缺点:同步 API,需要额外线程池
-
OkHttp
- 优点:支持 HTTP/2,异步 API
-
缺点:回调地狱(Callback Hell)
-
WebClient
- 优点:响应式编程,背压支持
- 缺点:学习曲线较陡
推荐使用 Spring WebFlux + WebClient 组合,特别适合处理流式响应。
核心实现
1. Spring WebFlux 非阻塞调用
@Bean
public WebClient webClient() {return WebClient.builder()
.baseUrl("https://api.openai.com/v1")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();}
2. 指数退避重试机制
.retryWhen(Retry.backoff(3, Duration.ofSeconds(1))
.filter(this::isRetryableException)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) ->
new ServiceUnavailableException("Retry exhausted")))
3. SSE 流式处理
webClient.post()
.uri("/chat/completions")
.bodyValue(request)
.accept(MediaType.TEXT_EVENT_STREAM)
.retrieve()
.bodyToFlux(String.class)
.map(this::parseSSEEvent)
.subscribe(event -> {// 处理分块响应});
生产环境考量
连接池调优
reactor:
netty:
resources:
max-connections: 500
max-idle-time: 30s
速率限制实现
private final Semaphore rateLimiter = new Semaphore(50);
public Mono<String> callApi(String prompt) {return Mono.fromCallable(() -> {rateLimiter.acquire();
return prompt;
}).flatMap(this::doCallApi)
.doFinally(s -> rateLimiter.release());
}
日志过滤
@Bean
public FilterRegistrationBean<RequestLoggingFilter> loggingFilter() {
FilterRegistrationBean<RequestLoggingFilter> registration =
new FilterRegistrationBean<>();
registration.setFilter(new RequestLoggingFilter());
registration.addUrlPatterns("/api/*");
return registration;
}
避坑指南
- 避免阻塞 EventLoop:
- 不要在响应式链中执行阻塞 IO
-
使用
publishOn切换线程 -
API 版本兼容:
- 固定 API 版本号
-
实现版本回退机制
-
监控指标:
- 记录请求延迟
- 监控错误率
- 跟踪令牌使用量
延伸思考
当 ChatGPT API 不可用时,可以考虑以下降级策略:
- 本地缓存历史响应
- 切换备用模型(如本地部署的 LLM)
- 返回预定义的兜底内容
- 基于规则的简化回复
实现示例:
public Mono<String> getCompletion(String prompt) {return chatGptApi.call(prompt)
.onErrorResume(e -> {if (isCriticalError(e)) {return fallbackService.getCompletion(prompt);
}
return Mono.error(e);
});
}
通过合理的降级策略,可以确保系统在 API 不可用时仍然提供基本服务能力。
正文完
