Nginxxy_read_timeout बनामxy_connect_timeout


15

मैंने सर्वर के एक सेट के लिए रिवर्स प्रॉक्सी के रूप में Nginx का उपयोग करना शुरू कर दिया है जो किसी प्रकार की सेवा प्रदान करता है।

सेवा कई बार धीमी हो सकती है (इसके जावा और JVM पर चलने पर कभी-कभी "पूर्ण कचरा संग्रह" में फंस जाता है) जिसमें कई सेकंड लग सकते हैं, इसलिए मैंने proxy_connect_timeout2 सेकंड में सेट किया है, जो Nginx को आंकड़ा बनाने के लिए पर्याप्त समय देगा बाहर सेवा जीसी पर अटक गई है और समय पर जवाब नहीं देगी, और इसे एक अलग सर्वर को अनुरोध पारित करना चाहिए।

मैंने proxy_read_timeoutरिवर्स प्रॉक्सी को अटकने से रोकने के लिए भी सेट किया है यदि सेवा को प्रतिक्रिया की गणना करने में बहुत अधिक समय लगता है - फिर से, इसे दूसरे सर्वर पर अनुरोध को स्थानांतरित करना चाहिए जो समय पर प्रतिक्रिया वापस करने के लिए पर्याप्त मुक्त होना चाहिए।

मैंने कुछ मानदंड चलाए हैं और मैं स्पष्ट रूप से देख सकता हूं कि proxy_connect_timeoutठीक से काम करने वाले कुछ कनेक्शन कनेक्शन टाइमआउट के लिए निर्दिष्ट समय पर वापस आते हैं, क्योंकि सेवा अटकी हुई है और आने वाले कनेक्शन को स्वीकार नहीं करता है (सेवा जेट्टी को एम्बेडेड के रूप में उपयोग कर रही है सर्वलेट कंटेनर)। यह proxy_read_timeoutभी काम करता है, क्योंकि मैं उन अनुरोधों को देख सकता हूं जो वहां निर्दिष्ट टाइमआउट के बाद वापस आते हैं।

समस्या यह है कि मैंने कुछ अनुरोधों को देखने की अपेक्षा की होगी जो समय समाप्त होने के बाद proxy_read_timeout + proxy_connect_timeoutया लगभग उस समय की लंबाई है, यदि सेवा अटक गई है और कनेक्शन को स्वीकार नहीं करेगा, जब निग्नेक्स इसे एक्सेस करने की कोशिश करता है, लेकिन इससे पहले कि निग्नेक्स समय-आउट कर सकता है - यह जारी हो जाता है और प्रसंस्करण शुरू होता है, लेकिन बहुत धीमा है और रीड टाइमआउट की वजह से Nginx गर्भपात करेगा। मेरा मानना ​​है कि सेवा में ऐसे मामले हैं, लेकिन कई बेंचमार्क चलाने के बाद, कई लाखों अनुरोधों को पूरा करने में - मैं एक भी अनुरोध को देखने में विफल रहा proxy_read_timeoutजो ऊपर की किसी भी चीज़ में वापस लौटता है (जो कि बड़ा समय है)।

मैं इस मुद्दे पर किसी भी टिप्पणी की सराहना करता हूं, हालांकि मुझे लगता है कि नग्नेक्स में एक बग के कारण हो सकता है (मुझे अभी तक कोड को देखना है, इसलिए यह सिर्फ एक धारणा है) कि कनेक्शन के बाद टाइमआउट काउंटर को रीसेट नहीं किया जाता है सफल है, अगर नग्नेक्स ने अपस्ट्रीम सर्वर से कुछ भी नहीं पढ़ा।


1
NGINX का क्या संस्करण? मुझे लगता है कि मुझे पुराने संस्करण (लगभग 0.6 / 7 शायद) में ऐसा ही कुछ याद है, लेकिन इसे और अधिक हाल के संस्करण में तय किया गया था (नवीनतम स्थिर संस्करण 1.0.5 है), लेकिन यह गलत हो सकता है। फिर भी आपके संस्करण को जानने में मदद मिलेगी
Smudge

ध्यान दें कि डॉक्स का कहना proxy_read_timeoutहै कि "ग्लोबल टाइमआउट" नहीं है, लेकिन 2 रीड ऑपरेशंस के बीच।
1

@ सलाम: मैं Nginx 1.0.0 का उपयोग कर रहा हूं। @poige - हां, मैं इसके बारे में जानता हूं, यही वजह है कि मुझे कुल टाइमआउट होने की उम्मीद है proxy_read_timeout + proxy_connect_timeout
Guss

1
एक साइड नोट के रूप में, आपको संभवतः अपने जेवीएम के लिए कुछ समवर्ती कचरा संग्रह पर शोध करना चाहिए: en.wikipedia.org/wiki/…
बहुपद

@polynomial: हमने किया, लेकिन हमारे बेंचमार्क के अनुसार "दुनिया को रोकने" जीसी की तुलना में जीसी समग्र के लिए खोए अधिक सीपीयू समय में समवर्ती कचरा संग्रह सुविधा के परिणाम हैं, इसलिए हम नेगनेक्स ट्यूनिंग में निवेश करना पसंद करते हैं :-)
Guss

जवाबों:


18

मैं वास्तव में इस पर पुन: पेश करने में असमर्थ था:

2011/08/20 20:08:43 [notice] 8925#0: nginx/0.8.53
2011/08/20 20:08:43 [notice] 8925#0: built by gcc 4.1.2 20080704 (Red Hat 4.1.2-48)
2011/08/20 20:08:43 [notice] 8925#0: OS: Linux 2.6.39.1-x86_64-linode19

मैंने इसे अपने nginx.conf में सेट किया:

proxy_connect_timeout   10;
proxy_send_timeout      15;
proxy_read_timeout      20;

मैं तो दो परीक्षण सर्वर सेटअप। एक जो SYN पर सिर्फ टाइमआउट करेगा, और एक वह जो कनेक्शन स्वीकार करेगा लेकिन कभी जवाब नहीं देगा:

upstream dev_edge {
  server 127.0.0.1:2280 max_fails=0 fail_timeout=0s; # SYN timeout
  server 10.4.1.1:22 max_fails=0 fail_timeout=0s; # accept but never responds
}

फिर मैंने एक परीक्षण कनेक्शन में भेजा:

[m4@ben conf]$ telnet localhost 2480
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
Host: localhost

HTTP/1.1 504 Gateway Time-out
Server: nginx
Date: Sun, 21 Aug 2011 03:12:03 GMT
Content-Type: text/html
Content-Length: 176
Connection: keep-alive

फिर error_log देखा जिसने यह दिखाया:

2011/08/20 20:11:43 [error] 8927#0: *1 upstream timed out (110: Connection timed out) while connecting to upstream, client: 127.0.0.1, server: ben.dev.b0.lt, request: "GET / HTTP/1.1", upstream: "http://10.4.1.1:22/", host: "localhost"

फिर:

2011/08/20 20:12:03 [error] 8927#0: *1 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 127.0.0.1, server: ben.dev.b0.lt, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:2280/", host: "localhost"

और फिर access.log जिसमें अपेक्षित 30s टाइमआउट (10 + 20) है:

504:32.931:10.003, 20.008:.:176 1 127.0.0.1 localrhost - [20/Aug/2011:20:12:03 -0700] "GET / HTTP/1.1" "-" "-" "-" dev_edge 10.4.1.1:22, 127.0.0.1:2280 -

यहां वह लॉग प्रारूप है जिसका मैं उपयोग कर रहा हूं जिसमें व्यक्तिगत अपस्ट्रीम टाइमआउट शामिल हैं:

log_format  edge  '$status:$request_time:$upstream_response_time:$pipe:$body_bytes_sent $connection $remote_addr $host $remote_user [$time_local] "$request" "$http_referer" "$http_user_agent" "$http_x_forwarded_for" $edge $upstream_addr $upstream_cache_status';

1
मेरे प्रश्न के ऊपर, आपके परिदृश्य में, यह अधिक है: मान लीजिए कि एक परीक्षण सर्वर है जो 0 और 20 सेकंड के बीच यादृच्छिक समय के बाद कनेक्शन को स्वीकार करता है, और फिर उत्तर देने से पहले 19 सेकंड और 21 सेकंड के बीच एक यादृच्छिक समय की प्रतीक्षा करता है। फिर इसके खिलाफ एक साधारण बेंचमार्क चलाएं। मैं 10 सेकंड के समय के साथ अनुरोध परिणाम के लगभग 50% देखने की उम्मीद करता हूं, 20 ~ 30 सेकंड के समय के साथ 25% परिणाम और 25% को एक सफल प्रतिक्रिया प्राप्त होगी। ऐसे मामले में, कितने सफल अनुरोधों को पूरा होने में अधिक 20 सेकंड लगेंगे? मेरे बेंचमार्क में, उनमें से कोई भी नहीं है - और यह मुझे परेशान करता है।
Guss

मैंने SYN पर रैंडम लॉस सेट करके परीक्षण किया और फिर लगभग 50 सेकंड के लिए वास्तव में धीरे-धीरे लाइनों को थूकने वाला एक CGI किया। मैं दोनों टाइमआउट की तुलना में संयुक्त रूप से बहुत लंबे समय तक अनुरोधों को देखने में सक्षम था, लेकिन अभी भी सफल रहा: box.access.log 200: 69.814: 67.100:।: 1579 33 127.0.0.1 test.host - [21 / अगस्त / 2011: 20)। 30:52 -0700] "GET / हग्स HTTP / 1.1" "-" "-" "-" dev_edge 127.0.0.1.12280 -
बहुपद

ठीक है, कि एक अलग अलग स्तर पर अजीब है :-)। एक संभावित व्याख्या यह है कि निगनेक्स को अनुरोध लिखने के लिए समय लगता है ( proxy_send_timeout) और जैसा कि आपने इसे उच्चतर पर सेट किया है proxy_connection_timeout, यह वास्तव में 20 सेकंड से अधिक देरी के लिए जिम्मेदार हो सकता है proxy_read_timeout। जब आप कहते हैं "थूक आउट लाइनें वास्तव में धीरे-धीरे" - आपका क्या मतलब है?
Guss

प्रतिक्रिया के शरीर में HTML की छपाई लाइनों के बीच 1 सो जाओ। केवल यह पढ़कर कि प्रॉक्सी_ड्रेड_आउट कैसे है, पूरे रीड को नहीं पढ़ता है।
बहुपद

1
ओह समझा। खैर, यह निश्चित रूप से मेरा मामला नहीं है और मुझे अपने ओपी में स्पष्ट नहीं करने के लिए खेद है। मेरे मामले में, एप्लिकेशन सर्वर किसी भी प्रकार की प्रतिक्रिया देने से पहले पूरी प्रक्रिया को पूरा करता है, और फिर एक ही बार में सब कुछ वापस कर देता है - इसलिए proxy_read_timeoutया तो अनुरोध पूरी तरह से विफल हो जाता है या इसे पूरी तरह से अनुमति देता है। यह आपके द्वारा देखे जाने वाले व्यवहार और मेरे द्वारा देखे जाने वाले व्यवहार के बीच का अंतर भी बताता है।
Guss

3

समस्या यह है कि मैंने कुछ अनुरोधों को देखने की अपेक्षा की होगी जो कि प्रॉक्सी_ड्रेड / टाइमआउट + प्रॉक्सी_कनेक्ट_टाइम के बाद, या लगभग उस समय की लंबाई, यदि सर्विस अटक गई है और जब निनेक्स इसे एक्सेस करने का प्रयास करता है, तो कनेक्शन स्वीकार नहीं करेगा, लेकिन इससे पहले कि Nginx को टाइमआउट कर सकें - यह रिलीज़ हो जाता है और प्रसंस्करण शुरू कर देता है, लेकिन बहुत धीमा है और रीड टाइमआउट के कारण Nginx गर्भपात कर देगा।

कनेक्ट टाइमआउट का मतलब है जब हाथ मिलाना (उदाहरण के लिए, कोई SYN_ACKs नहीं थे) टीसीपी स्टॉल। टीसीपी SYN भेजने की फिर से कोशिश करेगा, लेकिन आपने केवल 2 सेकंड दिए हैं। Nginx को किसी अन्य सर्वर का उपयोग करने के लिए जाना है, इसलिए इसके पास SYNs को फिर से भेजने का समय नहीं है।

युपीडी। : डॉक्स में नहीं मिल सकता है, लेकिन tcpdump से पता चलता है कि 3 सेकंड है। 1 भेजे गए SYN और SYN भेजने के दूसरे प्रयास के बीच देरी।


मुझे नहीं लगता कि यह ठीक है कि मैं पूछ रहा हूं - सवाल यह है कि अगर अपस्ट्रीम अटक जाती है और 1.999 सेकंड के बाद SYN_ACK लौटाती है, तो वर्तमान अपस्ट्रीम के साथ प्रक्रिया के साथ nginx जारी क्यों नहीं रहेगा?
Guss

ठीक है, आप स्निफर का उपयोग कर सकते हैं यदि आप बिल्कुल सटीक होना चाहते हैं। यह पता चल सकता है कि वहाँ कोई ACK हैं <2 सेकंड में बिल्कुल नहीं।
दोपहर

मैं वास्तव में एक स्निफर का उपयोग नहीं कर सकता क्योंकि मैं इस व्यवहार को देखने की उम्मीद करता हूं जहां सिस्टम पर एक उच्च भार है। वहाँ की व्याख्या बाद में कभी ACK तो कभी कुछ X लेकिन पहले 2 सेकंड, तब भी जब लाखों अनुरोधों पर विचार किया जाता है, गैर-प्रशंसनीय लगता है।
Guss
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.