对接AI大模型之nginx代理配置SSE接口

一、背景

在对接AI大模型的时候,采用流式输出,可以较好地缓解用户等待的焦虑,但是,接口极其容易超时。

前端这时候会一直报错:

bash 复制代码
Expected content-type to be text/event-stream, Actual: text/html

而后端的错误显示是客户端断开了连接。

这里摘录其中的一段错误信息,如果你也遇到该错误,希望本文可以帮助到你。

bash 复制代码
Caused by: java.io.IOException: Broken pipe
	at java.base/sun.nio.ch.SocketDispatcher.writev0(Native Method) ~[na:na]
	at java.base/sun.nio.ch.SocketDispatcher.writev(SocketDispatcher.java:66) ~[na:na]
	at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:227) ~[na:na]
	at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:158) ~[na:na]
	at java.base/sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:574) ~[na:na]
	at org.xnio.nio.NioSocketConduit.write(NioSocketConduit.java:162) ~[xnio-nio-3.8.16.Final.jar!/:3.8.16.Final]
	at io.undertow.conduits.IdleTimeoutConduit.write(IdleTimeoutConduit.java:130) ~[undertow-core-2.3.18.Final.jar!/:2.3.18.Final]

二、架构图

不通过内网域名访问后端服务:

三、排查过程

1、机房B的nginx配置

第一个被怀疑的对象是机房B的nginx超时时长,因为sse接口总是60秒即超时。

机房A的nginx,我看全局的配置nginx.conf已把连接超时调整为600秒。

vi /etc/nginx/nginx.conf

而接口每到了60秒的时候就断开了。

这一点,从机房B的nginx可以看到。

所以我们尝试改大机房B的nginx的超时,ingress的配置见下:

bash 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-connect-timeout: '600'
    nginx.ingress.kubernetes.io/proxy-read-timeout: '600'
    nginx.ingress.kubernetes.io/proxy-send-timeout: '600'

它无需重启,热加载配置生效。

2、机房A的nginx

既然机房B的nginx超时不能解决问题,试着从源头来排查。

首先,在机房A通过IP地址访问,不通过内网域名访问机房B的后端服务。

尝试后,无果。

在机房A,无论通过内网域名还是IP地址,测试后端服务的接口,都不会出现60秒即超时的异常。

bash 复制代码
curl -w "\n=== 耗时统计 ===\nDNS解析: %{time_namelookup}s\nTCP连接: %{time_connect}s\nSSL握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总耗时: %{time_total}s\nHTTP状态: %{http_code}\n" \
  -X POST \
  -H "Accept:text/event-stream" \
  -H "Content-Type:application/json" \
  -d '...略' \
  "http://内网域名/api/v1/pub/.../chat/messages" \
  -o /dev/null \
  -s

你可以通过curl进行测试,这一点很关键,可以排查,非机房B的问题。

既然是机房A的问题,那就转换下思路。

因为机房B的后端服务,原本是kong代理对外提供服务正常的,不同的是机房A现在是使用nginx代理。

3、nginx配置

试着单独配置sse接口的反向代理,见下:

bash 复制代码
location ~ ^/ai(/api/v1/pub/.../chat/messages)$ {
    proxy_pass http://10.xxx.xxx.196:7209$1;

    proxy_http_version 1.1;
    proxy_set_header Connection "";
    # sse 关闭缓存
    proxy_buffering off;
    proxy_cache off;
    chunked_transfer_encoding on;

    proxy_connect_timeout 600s;
    proxy_send_timeout 600s;
    proxy_read_timeout 600s;
    send_timeout 30s;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

其他接口则走默认:

bash 复制代码
	location /ai/ {
	    # 注意host末尾要加斜杆,否则访问后端接口的地址会被追加/ai
       proxy_pass  http://10.xxx.xxx.196:7209/;
    }

当然,proxy_pass 也可以配置内网域名。

经测试,前端访问sse接口,终于不会60秒即断开了。

三、测试验证

同样,通过curl工具,对外网接口进行测试。

bash 复制代码
curl -w "\n=== 耗时统计 ===\nDNS解析: %{time_namelookup}s\nTCP连接: %{time_connect}s\nSSL握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总耗时: %{time_total}s\nHTTP状态: %{http_code}\n" \
  -X POST \
  -H "Accept:text/event-stream" \
  -H "Content-Type:application/json" \
  -d '...略' \
  "http://外网域名/api/v1/pub/.../chat/messages" \
  -o /dev/null \
  -s

=== 耗时统计 ===

DNS解析: 0.012s

TCP连接: 0.024s

SSL握手: 0.185s

首字节: 17.739s

总耗时: 72.965s

HTTP状态: 200

相关推荐
躺不平的理查德1 分钟前
CMAKE备忘录
linux·运维·服务器
9624569 分钟前
跨域与私有网络访问限制排查实录
运维·服务器·网络
南方程序猴16 分钟前
2026年7月最新国内 Codex 安装教程和使用教程:GPT-5.6 完整指南
人工智能·gpt·ai·ai编程
发量惊人的中年网工17 分钟前
SD-WAN如何赋能工业物联网?打造工厂网络远程连接和数据传输新方案
运维·网络·分布式·物联网
Chengbei1121 分钟前
云存储桶漏洞检测工具OSS-2.0更新,全类型文件解析,存储桶遍历 + 敏感排查一站式完成渗透取证
网络·安全·web安全·网络安全·xss
乐维_lwops34 分钟前
乐维社区“专家坐诊”第403期问答
运维·网络·监控系统·答疑·lerwee运维智能体
爱喝水的鱼丶38 分钟前
SAP-ABAP:SAP 实战笔记:BAPI_OUTB_DELIVERY_CONFIRM_DEC 详解——外向交货单过账的利器
运维·性能优化·sap·abap·经验交流
国际云,接待44 分钟前
AWS RDS 备份与 PITR 恢复演练:从保留期、恢复命令到应用切换验证
运维·云计算·aws·灾难恢复·数据库备份·rds
国科安芯1 小时前
ASC0101S自动双向电平转换原理深剖
单片机·嵌入式硬件·fpga开发·云计算·信息与通信
Kevinten101 小时前
OpenOctopus:领域原生 AI 家庭助手系统,Summon 功能将实体转化为智能 Agent
人工智能·ai·开源·开发工具·智能体