From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS14383 205.234.109.0/24 X-Spam-Status: No, score=-0.5 required=5.0 tests=AWL,MSGID_FROM_MTA_HEADER, RP_MATCHES_RCVD shortcircuit=no autolearn=unavailable version=3.3.2 Path: news.gmane.org!not-for-mail From: Eric Wong Newsgroups: gmane.comp.lang.ruby.unicorn.general Subject: Re: Unicorn and streaming in Rails 3.1 Date: Sat, 25 Jun 2011 20:16:36 +0000 Message-ID: <20110625201636.GA22343@dcvr.yhbt.net> References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1309034838 23157 80.91.229.12 (25 Jun 2011 20:47:18 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 25 Jun 2011 20:47:18 +0000 (UTC) To: unicorn list Original-X-From: mongrel-unicorn-bounces@rubyforge.org Sat Jun 25 22:47:14 2011 Return-path: Envelope-to: gclrug-mongrel-unicorn@m.gmane.org X-Original-To: mongrel-unicorn@rubyforge.org Delivered-To: mongrel-unicorn@rubyforge.org Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) X-BeenThere: mongrel-unicorn@rubyforge.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: mongrel-unicorn-bounces@rubyforge.org Errors-To: mongrel-unicorn-bounces@rubyforge.org Xref: news.gmane.org gmane.comp.lang.ruby.unicorn.general:1022 Archived-At: Received: from rubyforge.org ([205.234.109.19]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1QaZl3-0004At-T5 for gclrug-mongrel-unicorn@m.gmane.org; Sat, 25 Jun 2011 22:47:14 +0200 Received: from rubyforge.org (rubyforge.org [127.0.0.1]) by rubyforge.org (Postfix) with ESMTP id 53DC4167835C; Sat, 25 Jun 2011 16:47:13 -0400 (EDT) Received: from dcvr.yhbt.net (dcvr.yhbt.net [64.71.152.64]) by rubyforge.org (Postfix) with ESMTP id 7BB581858361 for ; Sat, 25 Jun 2011 16:16:37 -0400 (EDT) Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id D967B21739; Sat, 25 Jun 2011 20:16:36 +0000 (UTC) Xavier Noria wrote: > Streaming works with Unicorn + Apache. Both with and without deflating. > > My understanding is that Unicorn + Apache is not a good combination > though because Apache does not buffer, and thus Unicorn has no fast > client in front. (I don't know which is the ultimate technical reason > Unicorn puts such an emphasis on fast clients, but will do some > research about it.) Basically the per-connection overhead of Unicorn is huge, an entire Ruby process (tens to several hundreds of megabytes). The per-connection overhead of nginx is tiny: maybe a few KB in userspace (including buffers), and a few KB in in the kernel. You don't want to maintain connections to Unicorn for a long time because of that cost. OK, if you have any specific questions that aren't answered in the website, please ask. > I have seen in > > http://unicorn.bogomips.org/examples/nginx.conf > > the comment > > "You normally want nginx to buffer responses to slow > clients, even with Rails 3.1 streaming because otherwise a slow > client can become a bottleneck of Unicorn." > > If I understand how this works correctly, nginx buffers the entire > response from Unicorn. First filling what's configured in > proxy_buffer_size and proxy_buffers, and then going to disk if needed > as a last resort. Thus, even if the application streams, I believe the > client will receive the chunked response, but only after it has been > generated by the application and fully buffered by nginx. Which > defeats the purpose of streaming Yes. > in the use case we have in mind in > Rails 3.1, which is to serve HEAD as soon as possible. Small nit: s/HEAD/the response header/ "HEAD" is a /request/ that only expects to receive the response header. nginx only sends HTTP/1.0 requests to unicorn, so Rack::Chunked won't actually send a chunked/streamed response. Rails 3.1 /could/ enable streaming without chunking for HTTP/1.0, but only if the client didn't set a non-standard HTTP/1.0 header to enable keepalive. This is because HTTP/1.0 (w/o keepalive) relies on the server to close the connection to signal the end of a response. > Is that comment in the example configuration file actually saying that > Unicorn with nginx buffering is not broken? I mean, that if your > application has some actions with stream enabled and you put it behind > this setup, the content will be delivered albeit not streamed? Correct. > If that is correct. Is it reasonable to send to nginx the header > X-Accel-Buffering to disable buffering only for streamed responses? Or > is it a very bad idea? If it is a real bad idea, is the recommendation > to Unicorn users that they should just ignore this new feature? You can use "X-Accel-Buffering: no" if you know your responses are small enough to fit into the kernel socket buffers. There's two kernel buffers (Unicorn + nginx), you can get a little more space there. nginx shouldn't make another request to Unicorn if it's blocked writing a response to the client already, so an evil pipelining client should not hurt unicorn in this case: require "socket" host = "example.com" s = TCPSocket.new(host, 80) req = "GET /something/big HTTP/1.1\r\nHost: #{host}\r\n\r\n" # pipeline a large number of requests, nginx won't send another # request to an upstream if it's still writing one 30.times { s.write(req) } # don't read the response, or read it slowly, just keep the socket # open here... sleep -- Eric Wong _______________________________________________ Unicorn mailing list - mongrel-unicorn@rubyforge.org http://rubyforge.org/mailman/listinfo/mongrel-unicorn Do not quote signatures (like this one) or top post when replying