我有一个返回json响应的REST API。有时(以及似乎完全随机的),json响应会在中途被切断。所以返回的json字符串如下所示:
...route_short_name":"135","route_long_name":"Secte // end of response
我很确定它不是编码问题,因为截止点会不断改变位置,具体取决于返回的json字符串。我还没有找到一个特定的响应大小,要么截断发生(我看到65kb没有被切断,而40kbs会被切断)。
查看切断时的响应标题:
{
"Cache-Control" = "must-revalidate, private, max-age=0";
Connection = "keep-alive";
"Content-Type" = "application/json; charset=utf-8";
Date = "Fri, 11 May 2012 19:58:36 GMT";
Etag = "\"f36e55529c131f9c043b01e965e5f291\"";
Server = "nginx/1.0.14";
"Transfer-Encoding" = Identity;
"X-Rack-Cache" = miss;
"X-Runtime" = "0.739158";
"X-UA-Compatible" = "IE=Edge,chrome=1";
}
也不响铃。任何人吗?
答案 0 :(得分:32)
我遇到了同样的问题:
Nginx切断了FastCGI后端的一些回复。例如,我无法从PhpMyAdmin生成正确的SQL备份。我检查了日志,发现了这个:
2012/10/15 02:28:14 [暴击] 16443#0:* 14534527 open() “/ usr / local / nginx / fastcgi_temp / 4/81 / 0000004814”失败(13:许可 在读取上游时,客户端: *,服务器: ,请求: “POST / HTTP / 1.1”,上游:“fastcgi://127.0.0.1:9000”,主持人: “ ”,推荐人:“http:// * / server_export.php?token = * * 强>“
我必须做的就是为/usr/local/nginx/fastcgi_temp
文件夹以及client_body_temp
提供适当的权限。
已修复!
非常感谢 samvermette ,您的问题&答案让我走上正轨。
答案 1 :(得分:30)
查看我的nginx error.log
文件并找到以下内容:
13870 open() "/var/lib/nginx/tmp/proxy/9/00/0000000009" failed (13: Permission denied) while reading upstream...
看起来nginx的代理正在尝试将响应内容(由thin传入)保存到文件中。它仅在响应大小超过proxy_buffers
时才会这样做(64位平台默认为64kb)。所以最后错误 连接到我的请求响应大小。
我通过在我的nginx配置文件中将proxy_buffering
设置为off
而不是提升proxy_buffers
或修复文件权限问题来解决我的问题。
还不确定nginx缓冲区的用途。我很感激,如果有人能加上这个。禁用缓冲是一个坏主意吗?
答案 2 :(得分:10)
我在切断服务器的响应方面遇到了类似的问题。
只有在我返回响应header('Content-type: application/json');
在我的情况下,gzip
导致了这个问题。
我通过在gzip_types
中指定nginx.conf
并在启用application/json
之前将gzip
添加到列表中来解决此问题:
gzip_types text / plain text / html text / css application / x-javascript text / xml application / xml application / xml + rss text / javascript 应用/ JSON;
gzip on;
答案 3 :(得分:2)
你可能会用完inode,这会阻止NginX正确使用fastcgi_temp目录。
尝试df -i
,如果你有0%的inode免费,那就是问题。
尝试使用find /tmp -mtime 10
(超过10天)查看可能正在填满磁盘的内容。
或许它是另一个文件太多的目录。例如,转到/home/www-data/example.com并计算文件:
find . -print | wc -l
答案 4 :(得分:2)
感谢您提出的问题和优秀的答案,它为我节省了很多时间。最后,克莱门特和山姆的答案帮助我解决了我的问题,所以学分归他们所有。
只是想指出,在阅读了一些关于该主题的内容之后,似乎不建议禁用proxy_buffering
,因为如果客户端(系统用户)的互联网不良,它可能会导致服务器停止连接例如。
我发现this discussion非常有用,可以了解更多信息。 Francis Daly的例子让我非常清楚:
将整个过程视为一系列过程可能更容易。
web浏览器通过1 MB / s链接与nginx对话。 nginx通过100 MB / s链路与上游服务器通信。 上游服务器向nginx返回100 MB的内容。 nginx向Web浏览器返回100 MB的内容。
启用proxy_buffering后,nginx可以保存整个100 MB,所以 nginx-upstream连接可以在1秒后关闭,然后nginx可以 花费100秒将内容发送到网络浏览器。
关闭proxy_buffering,nginx只能从上游获取内容 与nginx可以将其发送到Web浏览器的速率相同。
网络浏览器并不关心差异 - 它仍然需要100 为了获得全部内容。
nginx并不关心差异 - 它仍需要100秒才能完成 将内容提供给浏览器,但它必须保持连接 向上游开放额外99秒。
上游确实关心差异 - 可以采取什么措施1 s实际需要100秒;对于额外的99秒,上游服务器是 不提供任何其他要求。
通常:nginx-upstream链接比browser-nginx链接快; 上游是更重要的"重量级"比nginx;所以谨慎一点 上游完成处理尽快。
答案 5 :(得分:1)
我们遇到了类似的问题。它是由启用了SO_LINGER的REST服务器(DropWizard)引起的。在负载下DropWizard在有机会冲洗它的缓冲区之前断开连接NGINX。 JSON大于8kb,前端会被截断。
答案 6 :(得分:0)
我也有这个问题 - authorized_keys
解析客户端有问题,响应被切断或更糟,响应是陈旧的,并从一些随机内存缓冲区中读取。
在尝试配置nginx以提供简单的<?php
$externalData = array(array("a","b",3,"d"), array("f","g",1,"h"));
echo "<pre>";
print_r($externalData);
usort($externalData, function ($a, $b) {
return $a[2] - $b[2];
});
echo "<br>";
print_r($externalData);
echo "</pre>";
?>
文件时,浏览了一些指南 - Serving Static Content Via POST From Nginx以及Nginx: Fix to “405 Not Allowed” when using POST serving static。
在我的情况下,我不得不使用:
JSON
因此,当nginx在响应标头中添加JSON
时,浏览器不会得到任何有趣的想法以及
max_ranges 0;
在我的Accept-Ranges: bytes
块中,代理服务于静态文件。将其添加到sendfile off;
块中,最终会为找到的server
文件提供帮助。
另一个用于提供静态location
的原型也不会忘记响应类型:
JSON
其他搜索产生了文件夹权限问题 - nginx is cutting the end of dynamic pages and cache it或代理缓冲问题 - Getting a chunked request through nginx,但这不是我的情况。