2011-12-04 34 views
5

Tôi đang tạo hệ thống thống kê web có tải trọng cao thông qua nhúng <img> thẻ vào trang web. Điều tôi muốn làm là:Làm cách nào để nginx trả về phản hồi tĩnh và gửi tiêu đề yêu cầu đến ứng dụng?

  1. nginx nhận được yêu cầu cho một hình ảnh từ một số máy chủ
  2. nó mang lại là câu trả lời để lưu trữ ít 1px hình ảnh tĩnh từ hệ thống tập tin
  3. vào thời điểm này nó bằng cách nào đó chuyển tiêu đề yêu cầu để ứng dụng và đóng kết nối với máy chủ

Tôi đang làm việc với Ruby và tôi sẽ tạo một ứng dụng thuần túy để lấy tiêu đề và đặt chúng vào hàng đợi để tính toán thêm.

Vấn đề tôi không thể giải quyết là, làm cách nào tôi có thể định cấu hình nhân sư để cung cấp tiêu đề cho ứng dụng Giá và trả về hình ảnh tĩnh làm trả lời mà không phải chờ phản hồi từ ứng dụng Rack?

Ngoài ra, Rack là không cần thiết nếu có Ruby-giải pháp phổ biến hơn.

+1

Đây không phải là thực sự là một câu trả lời cho câu hỏi _specific_ của bạn, nhưng nếu bạn don' t tìm giải pháp khác, bạn có thể cân nhắc việc ghi lại các yêu cầu vào một tệp và sau đó phân tích cú pháp tệp đó sau bằng Ruby –

+0

Brandon, cảm ơn, giải pháp này khá thú vị, nhưng tôi e là nó có khả năng mở rộng. – sandrew

+0

Tại sao bạn cần phản hồi ngay lập tức từ máy chủ?Ý tôi là khách hàng đang đợi hình ảnh GIF 1x1px trong suốt, vì vậy trải nghiệm người dùng cuối không đáng kể ... – lwe

Trả lời

1

Bạn có thể thực hiện điều này với post_action (Tôi không hoàn toàn chắc chắn điều này sẽ làm việc, nhưng đó là điều duy nhất tôi có thể nghĩ đến)

server { 
    location/{ 
    post_action @post; 
    rewrite^/1px.gif break; 
    } 

    location @post { 
    # Pass the request to the backend. 
    proxy_pass http://backend$request_uri; 

    # Using $request_uri with the proxy_pass will preserve the original request, 
    # if you use (fastcgi|scgi|uwsgi)_pass, this would need to be changed. 
    # I believe the original headers will automatically be preserved. 
    } 
} 
+0

Tôi làm điều này với post_action. http://wiki.nginx.org/HttpEmptyGifModule nhanh hơn để phân phối gif 1x1. – greg

2

Một lựa chọn đơn giản là chấm dứt kết nối khách hàng CÀNG SỚM CÀNG TỐT trong khi tiếp tục với quá trình phụ trợ.

server { 
    location /test { 
     # map 402 error to backend named location 
     error_page 402 = @backend; 

     # pass request to backend 
     return 402; 
    } 

    location @backend { 
     # close client connection after 1 second 
     # Not bothering with sending gif 
     send_timeout 1; 

     # Pass the request to the backend. 
     proxy_pass http://127.0.0.1:8080; 
    } 
} 

Các tùy chọn ở trên, trong khi đơn giản, thể kết quả trong các khách hàng nhận được một thông báo lỗi khi kết nối được giảm xuống. Chỉ thị ngx.say sẽ đảm bảo rằng tiêu đề "200 OK" được gửi và vì đó là một cuộc gọi không đồng bộ, sẽ không giữ mọi thứ. Điều này cần mô-đun ngx_lua.

server { 
    location /test { 
     content_by_lua ' 
      -- send a dot to the user and transfer request to backend 
      -- ngx.say is an async call so processing continues after without waiting 
      ngx.say(".") 
      res = ngx.location.capture("/backend") 

     '; 
    } 

    location /backend { 
     # named locations not allowed for ngx.location.capture 
     # needs "internal" if not to be public 
     internal; 

     # Pass the request to the backend. 
     proxy_pass http://127.0.0.1:8080; 
    } 

} 

Một gọn gàng hơn tùy chọn Lua dựa trên:

server { 
    location /test { 
     rewrite_by_lua ' 
      -- send a dot to the user 
      ngx.say(".") 

      -- exit rewrite_by_lua and continue the normal event loop 
      ngx.exit(ngx.OK) 
     '; 
     proxy_pass http://127.0.0.1:8080; 
    } 
} 

Chắc chắn một thách thức thú vị.

0

Tại sao không sử dụng X-Accel-Redirect, http://wiki.nginx.org/XSendfile, vì vậy bạn có thể chuyển tiếp yêu cầu tới ứng dụng ruby ​​của bạn và sau đó chỉ cần đặt tiêu đề phản hồi và nginx trả về tệp.

Cập nhật, tốt cho tệp GIF trong suốt 1x1px, có thể dễ dàng lưu trữ dữ liệu trong biến và trả lại trực tiếp cho khách hàng, vì vậy tôi nghĩ rằng X-Accel-Redirect có thể là quá mức cần thiết trong trường hợp này.

2

Sau khi đọc ở đây về post_action và đọc "Phục vụ Static Content Via POST Từ Nginx" http://invalidlogic.com/2011/04/12/serving-static-content-via-post-from-nginx/ Tôi đã thực hiện điều này bằng:

server { 
    # this is to serve a 200.txt static file 
    listen 8888; 
    root /usr/share/nginx/html/; 
} 
server { 
    listen 8999; 
    location/{ 
    rewrite^/200.txt break; 
    } 

    error_page 405 =200 @405; 
    location @405 { 
    # post_action, after this, do @post 
    post_action @post; 
    # this nginx serving a static file 200.txt 
    proxy_method GET; 
    proxy_pass http://127.0.0.1:8888; 
    } 

    location @post { 
    # this will go to an apache-backend server. 
    # it will take a long time to process this request 
    proxy_method POST; 
    proxy_pass http://127.0.0.1/$request_uri; 
    } 
} 
Các vấn đề liên quan