![nginx 是否允许上游服务器在请求完成之前响应并关闭请求?](https://linux22.com/image/654209/nginx%20%E6%98%AF%E5%90%A6%E5%85%81%E8%AE%B8%E4%B8%8A%E6%B8%B8%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%9C%A8%E8%AF%B7%E6%B1%82%E5%AE%8C%E6%88%90%E4%B9%8B%E5%89%8D%E5%93%8D%E5%BA%94%E5%B9%B6%E5%85%B3%E9%97%AD%E8%AF%B7%E6%B1%82%EF%BC%9F.png)
我有一个 nginx 代理请求的图片上传服务。一切运行良好。但有时,服务器已经有用户正在上传的图片。因此,我想尽早响应并关闭连接。
在读取标头并与服务器检查后,我调用 Node 的response.end([数据][, 编码][, 回调])。
Nginx 崩溃并返回空白响应:
[error] 3831#0: *12879 readv() failed (104: Connection reset by peer) while reading upstream
我的猜测是,nginx 认为上游服务器发生了一些不好的事情,立即断开客户端连接而不发送上游服务器的响应。
有人知道当 nginx 作为代理时如何正确响应和关闭客户端的连接吗?我知道这是可以做到的:参见:在请求之前发送响应
这是 nginx conf 文件:
worker_processes 8; # the number of processors
worker_rlimit_nofile 128; # each connection needs 2 file handles
events {
worker_connections 128; # two connections per end-user connection (proxy)
multi_accept on;
use kqueue;
}
http {
sendfile on;
tcp_nopush on; # attempt to send HTTP response head in one packet
tcp_nodelay off; # Nagle algorithm, wait until we have the maximum amount of data the network can send at once
keepalive_timeout 65s;
include nginx.mime.types;
default_type application/octet-stream;
error_log /usr/local/var/log/nginx/error.log;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
gzip off;
}
upstream upload_service {
server 127.0.0.1:1337 fail_timeout=0;
keepalive 64;
}
location /api/upload_service/ {
# setup proxy to UpNode
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;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_pass http://upload_service;
# The timeout is set only between two successive read operations
proxy_read_timeout 500s;
# timeout for reading client request body, only for a period between two successive read operations
client_body_timeout 30s;
# maximum allowed size of the client request body, specified in the "Content-Length"
client_max_body_size 64M;
}
答案1
您没有提到您的客户端是什么,但是,这听起来像是使用 expect 标头可以实现的功能。本质上,客户端设置一个带有“100-continue”期望的“Expect”标头。然后,客户端等待服务器的 100 Continue 响应,然后再发送其请求主体。
如果服务器不想接收主体,它可以用最终状态进行响应,并且客户端不会发送主体。
该过程定义在RFC2616,第 8.2.3 节
答案2
https://forum.nginx.org/read.php?2,254918,254918#msg-254918提到RFC2616,8.2.2也相关:
根据 RFC2616,8.2.21如果请求包含 Content-Length 并且客户端(本例中为 nginx)由于错误响应而停止传输主体,则客户端(nginx)必须关闭连接