Rails 4,Puma,Nginx – ActionController :: Live Streaming在发送第一个块后死亡

下面是我设置的一个裸机Rails 4项目来解决我的问题:

https://github.com/rejacobson/rails4-streamtest

我在/ home / stream中build立了一个路线,这个路线应该以1秒的间隔stream5行文本。

def stream 5.times do |n| puts "Streaming: #{n}" response.stream.write "Streaming: #{n+1}" sleep 1 end rescue IOError => e puts 'Connection closed' ensure response.stream.close end 

当我使用tcp://运行puma时,没有nginx,stream式传输完美。

 curl -N http://localhost:3000/home/stream 

而我得到的5条线stream回来,没问题。

当我介绍nginx的时候,curl会输出第一行,然后立即退出。 我不断地看到在服务器和日志上的put调用的输出,所以我知道请求仍然在5times循环中处理。

它也不会像用户切断连接一样抛出IOErrorexception。

以下是我迄今为止所尝试的:

  • 主要conf文件和服务器conf中nginx指令的不同组合。
  • 更改导轨设置。
  • 各种美洲狮configuration设置。
  • 在控制器方法中设置各种不同的头文件,希望这是一个caching问题。

search互联网也提供了很less的帮助。

我不知所措,需要一些方向。

这是两个curl调用的输出,有和没有nginx。

没有nginx

 ~/projects/streamtest ▰ master ▰ ryan mirage ▰▰▰▰ curl -i -N http://192.168.1.100:3000/home/stream HTTP/1.1 200 OK X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff X-UA-Compatible: chrome=1 Cache-Control: no-cache Content-Type: text/html; charset=utf-8 Set-Cookie: request_method=GET; path=/ X-Request-Id: 9ce86358-4476-404a-97e5-769c16ec7b0c X-Runtime: 0.978099 Transfer-Encoding: chunked Streaming: 1Streaming: 2Streaming: 3Streaming: 4Streaming: 5 

puma.stdout

 Streaming: 0 Streaming: 1 Streaming: 2 Streaming: 3 Streaming: 4 [8048] 192.168.1.100 - - [14/Mar/2014 21:04:50] "GET /home/stream HTTP/1.1" 200 - 6.0661 

用nginx

 ~/projects/streamtest ▰ master ▰ ryan mirage ▰▰▰▰ curl -i -N http://192.168.1.100:3000/home/stream HTTP/1.1 200 OK Server: nginx/1.4.5 Date: Sat, 15 Mar 2014 04:02:40 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff X-UA-Compatible: chrome=1 ETag: "a505e0aa3b11b25301a9a704252a519a" Cache-Control: max-age=0, private, must-revalidate Set-Cookie: request_method=GET; path=/ X-Request-Id: 8983d199-026b-4082-a5f1-f1d6c886a3d6 X-Runtime: 0.016516 Streaming: 1 

puma.stdout

 Streaming: 0 [7558] 192.168.1.100 - - [14/Mar/2014 21:02:40] "GET /home/stream HTTP/1.0" 200 - 0.0214 Streaming: 1 Streaming: 2 Streaming: 3 Streaming: 4 

有趣的是,我刚刚注意到,获取请求日志行的位置是:

“GET / home / stream HTTP / 1.0”200

在每个curl调用中是不同的,并且关于多less文本被实际stream传送。

关于这里发生了什么的任何想法? 为什么在使用nginx的时候不能导出整个事物?

解决了

事实证明,我需要的是我的位置指令中的这一行,以便通过nginx进行流式处理:

proxy_http_version 1.1;

我在调查nginx上游模块中的keepalive指令时发现了这个问题:

http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

这段文字尤其引导我:

 For HTTP, the proxy_http_version directive should be set to “1.1” and the “Connection” header field should be cleared: upstream http_backend { server 127.0.0.1:8080; keepalive 16; } server { ... location /http/ { proxy_pass http://http_backend; proxy_http_version 1.1; proxy_set_header Connection ""; ... } } 

看来,nginx默认为,proxy_http_version 1.0;

根据维基百科, http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

HTTP / 1.1引入了分块传输编码,以允许持久连接上的内容流式传输而不是缓存。

所以有我的问题。

TIL