apisix~对sse事件流的支持~api7.ai的方案

打印 上一主题 下一主题

主题 1719|帖子 1719|积分 5167

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在 APISIX 中,如果你需要关闭 Nginx 的缓冲区以支持 SSE(Server-Sent Events)的 text/event-stream 响应,确保数据可以或许实时流式传输到客户端,可以通过以下步骤实现。
1. 禁用 Nginx 的代理缓冲

Nginx 默认会启用代理缓冲(proxy_buffering),这会导致 SSE 数据被缓存并按块返回,而不是实时流式传输。为了禁用缓冲,需要修改 Nginx 的配置。
修改 APISIX 的 Nginx 配置文件

APISIX 是基于 Nginx 的,因此可以通过修改 APISIX 的 Nginx 配置文件来禁用缓冲。

  • 打开 APISIX 的 Nginx 配置文件模板:

    • 文件路径通常为 /usr/local/apisix/conf/nginx.conf。
    • 如果你使用了自定义的 Nginx 模板,路径可能不同。

  • 在 http 块中添加全局配置:
    1. http {
    2.     proxy_buffering off;  # 禁用代理缓冲
    3.     proxy_buffer_size 1k;  # 设置缓冲区大小为 1KB
    4.     proxy_buffers 4 1k;    # 设置缓冲区数量和大小
    5. }
    复制代码

    • proxy_buffering off:完全禁用代理缓冲,确保数据实时传输。
    • proxy_buffer_size 和 proxy_buffers:将缓冲区大小设置为较小的值(如 1KB),以减少数据分块的大小。

加到某个server下面
  1. server {
  2.     listen 80;
  3.     server_name app1.example.com;
  4.    
  5.     # 覆盖全局配置:关闭本server所有请求的代理缓冲
  6.     proxy_buffering off;  # ✅ 生效层级:当前server
  7.     }
复制代码

  • 生存文件并重启 APISIX:
    1. apisix restart
    复制代码
2. 在路由中禁用缓冲

除了全局禁用缓冲,还可以在特定路由中禁用缓冲。通过 proxy-rewrite 插件的 disable_buffering 参数实现。
示例配置
  1. {
  2.     "uri": "/your-sse-endpoint",
  3.     "plugins": {
  4.         "proxy-rewrite": {
  5.             "disable_buffering": true  # 禁用缓冲
  6.         }
  7.     },
  8.     "upstream": {
  9.         "type": "roundrobin",
  10.         "nodes": {
  11.             "your-backend-service:80": 1
  12.         }
  13.     }
  14. }
复制代码

  • disable_buffering: true:确保该路由的响应数据不会被缓冲。
3. 调整 Nginx 的 chunked_transfer_encoding

确保 Nginx 启用了分块传输编码(chunked_transfer_encoding),这是 SSE 流式传输的基础。
在 Nginx 配置中添加以下内容:
  1. http {
  2.     chunked_transfer_encoding on;  # 启用分块传输编码
  3. }
复制代码
4. 查抄后端服务的响应头

确保后端服务返回的响应头中没有 Content-Length,并且启用了分块传输编码(Transfer-Encoding: chunked)。SSE 是流式协议,响应应该是分块传输的。
查抄后端服务的响应头,确保如下:
  1. HTTP/1.1 200 OK
  2. Content-Type: text/event-stream
  3. Transfer-Encoding: chunked
  4. Connection: keep-alive
复制代码
如果后端服务返回了 Content-Length,Nginx 可能会根据该长度举行缓冲。
5. 使用 Lua 脚本自定义流式处理

如果以上方法仍旧无法满意需求,可以通过 Lua 脚本自定义流式处理逻辑,确保数据逐字转发。
示例 Lua 脚本
  1. local core = require("apisix.core")
  2. local ngx = ngx
  3. local function逐字转发()
  4.     -- 设置响应头
  5.     ngx.header["Content-Type"] = "text/event-stream"
  6.     ngx.header["Cache-Control"] = "no-cache"
  7.     ngx.header["Connection"] = "keep-alive"
  8.     -- 连接后端服务
  9.     local sock = ngx.socket.tcp()
  10.     local ok, err = sock:connect("your-backend-service", 80)
  11.     if not ok then
  12.         core.log.error("failed to connect to backend: ", err)
  13.         return ngx.exit(500)
  14.     end
  15.     -- 逐字读取并转发
  16.     while true do
  17.         local byte, err = sock:receive(1)  -- 每次读取 1 字节
  18.         if not byte then
  19.             break
  20.         end
  21.         ngx.print(byte)  -- 逐字转发
  22.         ngx.flush(true)  -- 立即刷新缓冲区
  23.     end
  24.     -- 关闭连接
  25.     sock:close()
  26. end
  27. return逐字转发
复制代码
在路由中应用 Lua 脚本

通过 serverless-pre-function 插件加载 Lua 脚本:
  1. {
  2.     "uri": "/your-sse-endpoint",
  3.     "plugins": {
  4.         "serverless-pre-function": {
  5.             "phase": "access",
  6.             "functions": [
  7.                 "local function逐字转发 = require('sse_stream') 逐字转发()"
  8.             ]
  9.         }
  10.     },
  11.     "upstream": {
  12.         "type": "roundrobin",
  13.         "nodes": {
  14.             "your-backend-service:80": 1
  15.         }
  16.     }
  17. }
复制代码
6. 测试

完成配置后,通过以下方式测试 SSE 数据是否实时流式传输:

  • 使用 curl 测试:
    1. curl -N http://<APISIX-IP>:<APISIX-PORT>/your-sse-endpoint
    复制代码
  • 在浏览器中测试:
    打开开发者工具,查察 SSE 数据是否实时吸收。
总结

要关闭 Nginx 的缓冲区以支持 SSE 的 text/event-stream 响应,可以:

  • 在 Nginx 配置中禁用代理缓冲(proxy_buffering off)。
  • 在路由中设置 disable_buffering: true。
  • 确保后端服务返回分块传输编码(Transfer-Encoding: chunked)。
  • 如果需要更精细的控制,可以使用 Lua 脚本自定义流式处理逻辑。
通过这些方法,可以确保 SSE 数据实时流式传输到客户端。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

泉缘泉

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表