Nginx反向代理服务流式输出设置

1.问题场景

提问:为什么我部署的服务没有流式响应

最近在重构原有的GPT项目时,遇到gpt回答速度很慢的现象。在使用流式输出的接口时,接口响应速度居然还是达到了30s以上。

2.现象分析

分析现象我发现,虽然前端还是流式打印的结果,但是,好像是接口处理完了,再以流式返回到的前端。

3.解决过程记录

起初

因为新的重构项目中用MASA 的minimalAPI代替了传统的MVC。所以在接口实现上跟之前有所不同,在对Stream流的处理方式上也有不同。我以为是我处理的方式不对,为此,我的代码做过多次改进。最终的接口如下:

/// <summary>
/// 聊天接口(gpt-4)返回流
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
[Authorize]
[Produces("application/octet-stream")]
public async Task ChatCompletionStream(ChatReq req, CancellationToken cancellationToken = default)
{
if (_httpContextAccessor.HttpContext?.Items["key"] != null)
{
req.Key = _httpContextAccessor.HttpContext?.Items["key"]?.ToString();
}
_logger.Information($"ChatStream1开始时间:{DateTime.Now},key【{req.Key}】");
var userId = long.Parse(_httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.UserData));
req.UserId = userId;
req.IP = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.MapToIPv4().ToString();
var response = _httpContextAccessor.HttpContext.Response;
response.ContentType = "application/octet-stream";
var enumerable = _chatService.ChatCompletionStream(req);
await foreach (var item in enumerable)
{
var bytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(item, new JsonSerializerOptions()
{
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
}) + "\n");
await response.BodyWriter.WriteAsync(bytes);
}
_logger.Information($"ChatStream1结束时间:{DateTime.Now}");
}

后来

在优化代码后,本地速度提升明显。但是在服务器上速度任然不理想。让我怀疑,是不是代码问题?难道是别的问题。

与此同时,昨天,我的搭档同样向我抛出了这个问题:“聊天的接口好慢”

我说出了两种可能:1.代码,是minimalAPI的锅。2.网络,我们的服务部署在自己的服务器上,然后通过内网映射,又通过反向代理调用的OpenAI的接口,网络复杂,造成了速度慢。

最后发现问题

今天,我想到问题所在,我们的反向代理服务,是通过nginx做了反向代理的,之前我们解决过后端服务的nginx反向代理设置流式传输的问题。问题就在这里。对应的yarn服务的nginx配置同样需要设置流式传输。

2.解决问题的方法

如果你使用 ngnix 反向代理,需要在配置文件中增加下列代码:

\# 不缓存,支持流式输出

proxy_cache off;  # 关闭缓存

proxy_buffering off;  # 关闭代理缓冲

chunked_transfer_encoding on;  # 开启分块传输编码

tcp_nopush on;  # 开启TCP NOPUSH选项,禁止Nagle算法

tcp_nodelay on;  # 开启TCP NODELAY选项,禁止延迟ACK算法

keepalive_timeout 300;  # 设定keep-alive超时时间为65秒

3 什么是代理,如何使用?

由于 OpenAI 的 IP 限制,中国和其他一些国家/地区无法直接连接 OpenAI API,需要通过代理。你可以使用代理服务器(正向代理),或者已经设置好的 OpenAI API 反向代理。

- 正向代理例子:梯子。docker 部署的情况下,设置环境变量 HTTP_PROXY 为你的代理地址(例如:10.10.10.10:8002)。

- 反向代理例子:可以用别人搭建的代理地址,或者通过 Cloudflare 免费设置。设置项目环境变量 BASE_URL 为你的代理地址。

4.搭建反向代理服务

yarn 服务反向代理GPT部署方案:yarn 反向代理

阅读如遇样式问题,请前往个人博客浏览: https://www.raokun.top

拥抱ChatGPT:https://chat111.terramours.site

开源项目地址:https://github.com/raokun/YarpProject

Nginx反向代理服务流式输出设置的更多相关文章

  1. HttpURLConnection的流式输出的缺陷和解决方法

    转自:http://www.mzone.cc/article/198.html 最近在用applet写文件上传控件的时候发现使用URLConnection来对服务器进行流式输出时的一些问题.我们通常要 ...

  2. 文件下载(StreamingHttpResponse流式输出)

    文件下载(StreamingHttpResponse流式输出) HttpResponse会直接使用迭代器对象,将迭代器对象的内容存储成字符串,然后返回给客户端,同时释放内存.可以当文件变大看出这是一个 ...

  3. nginx反向代理-后端服务器组设置

    nginx服务器的反向代理时其最常用的重要功能之一,在实际工作中应用广泛,涉及的配置指令也比较多.下面会尽量详细地介绍对应的指令,及其使用状态. 反向代理一般是互联网需要向内网拉取资源,比如访问一个w ...

  4. 11、Nginx反向代理服务

    1Nginx代理服务基本概述 1.代理一词并不陌生, 该服务我们常常用到如(代理理财.代理租房.代理收货等等),如下图所示 2.在没有代理模式的情况下,客户端和Nginx服务端,都是客户端直接请求服务 ...

  5. nginx 反向代理服务

    目录 Nginx代理服务基本概述 Nginx代理服务常见模式 Nginx代理服务支持协议 Nginx反向代理配置语法 Nginx反向代理场景实践 配置代理实战 在lb01上安装nginx Nginx代 ...

  6. Linux 部署Nginx反向代理服务 使用openssl自生成证书并配置https

    1.安装Nginx编译所依赖的包 正常centos中可以使用yum安装一下依赖包: yum install -y gcc gcc-c++ pcre pcre-devel zlib zlib-devel ...

  7. 动态PHP电商网站伪静态的 Nginx反向代理Cache缓存终极设置

    转自: http://www.ttlsa.com/nginx/dynamic-php-nginx-cache/

  8. DJANGO的HTTPRESPONSE流式输出

    在项目当中遇到的问题,网上有样例代码,但都不行,后来,发现在了1.5版本之后,新的STREAMHTTPRESPONSE对象, 搞定. from django.http import HttpRespo ...

  9. Openresty的同步输出与流式响应

    Openresty的同步输出与流式响应 默认情况下, ngx.say和ngx.print都是异步输出的,先来看一个例子: location /test { content_by_lua_block { ...

  10. Nginx反向代理部署指南

    一.反向代理 我们都知道,80端口是web服务的默认端口,其他主机访问web服务器也是默认和80端口进行web交互,而一台服务器也只有一个80端口,这是约定俗成的标准. 我们来看下面两个场景: 1.服 ...

随机推荐

  1. 2022-11-14:rust语言,请使用过程宏给结构体AAA生成结构体AAABuilder和创建AAABuilder实例的方法。 宏使用如下: #[derive(Builder)] pub stru

    2022-11-14:rust语言,请使用过程宏给结构体AAA生成结构体AAABuilder和创建AAABuilder实例的方法. 宏使用如下: #[derive(Builder)] pub stru ...

  2. 【.NET】C#/.NET新建项目sln,增加src和test文件夹问题和解决方案

    ​ 问题介绍 经常逛github找优秀的.NET项目看,看到github上的项目的层级有src test,sln放在外层.如下图: 发现自己再Visaul Studio新建的项目即使添加了src和te ...

  3. 虚拟机linux系统密码忘记了该怎么办?

    当你的linux系统的密码忘记了该怎么办? 首先不要慌,重启电脑,开机的时候 出现这个页面的时候点击e然后出现这个页面 把里面的ro修改为 rw 修改为rw之后在这一行语句的最后面输入enforcin ...

  4. flutter填坑之旅(flutter页面生命周期篇)

    一.初始化时期 1.createState ///构建一个StatefulWidget时,会立即调用该方法(必须重写) @override _WidgetLifecycleState createSt ...

  5. dockder 学习第一篇

    1 docker安装 1 yum包的更新到最新 yum update 2 安装需要软件包,yum-util [root@localhost ~]# yum install -y yum-utils d ...

  6. es mysql 适用场景对比

    es mysql 适用场景对比 问题一 全文检索毫无疑问直接上es,那么除了这种场景,什么时候该选es?为啥mysql不行? 对枚举字段的搜索 mysql创建索引的原则是对于那些区别度高字段建立索引, ...

  7. Intellij IDEA最新激活码,适合2022,2023和所有版本,永久更新

    分享一下 IntelliJ IDEA 2023.1 最新激活注册码,破解教程如下,可免费永久激活,亲测有效,下面是详细文档哦~ 申明:本教程 IntelliJ IDEA 破解补丁.激活码均收集于网络, ...

  8. OpenOffice4.1.6 linux安装/卸载教程

    以下是centos的安装方法 1.先安装并配置好jdk 2.拷贝 把Apache_OpenOffice_4.1.6_Linux_x86-64_install-rpm_zh-CN.tar.gz拷贝到自己 ...

  9. Redis系列14:使用List实现消息队列

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  10. c# 如何将枚举以下拉数据源的形式返回给前端

    前言: 相信各位有碰到过与我类似的问题,当表中存一些状态的字段,无非以下几种形式1.直接写死 如: 正常:1,异常:2 ,还有一种则是写在字典中,再或者就是加在枚举上,前两者对于返回下拉数据源来说比较 ...