2009-07-28 11 views
6

मैं एक विशिष्ट साइट के लिए एक वेब क्रॉलर लिख रहा हूं। एप्लिकेशन एक वीबी.Net विंडोज फॉर्म एप्लिकेशन है जो एकाधिक थ्रेड का उपयोग नहीं करता है - प्रत्येक वेब अनुरोध लगातार होता है। हालांकि, दस सफल पृष्ठ के बाद हर लगातार अनुरोध समय वापस प्राप्त होता है।दस कंसल्टिव अनुरोधों के बाद HttpWebRequest टाइमआउट

मैं इसी तरह के सवाल पहले से ही इतने पर यहां पोस्ट की समीक्षा की है, और मेरे GetPage दिनचर्या में सिफारिश की तकनीक, नीचे दिखाया गया है को लागू किया है:

Public Function GetPage(ByVal url As String) As String 
    Dim result As String = String.Empty 

    Dim uri As New Uri(url) 
    Dim sp As ServicePoint = ServicePointManager.FindServicePoint(uri) 
    sp.ConnectionLimit = 100 

    Dim request As HttpWebRequest = WebRequest.Create(uri) 
    request.KeepAlive = False 
    request.Timeout = 15000 

    Try 
     Using response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse) 
      Using dataStream As Stream = response.GetResponseStream() 
       Using reader As New StreamReader(dataStream) 
        If response.StatusCode <> HttpStatusCode.OK Then 
         Throw New Exception("Got response status code: " + response.StatusCode) 
        End If 
        result = reader.ReadToEnd() 
       End Using 
      End Using 
      response.Close() 
     End Using 

    Catch ex As Exception 
     Dim msg As String = "Error reading page """ & url & """. " & ex.Message 
     Logger.LogMessage(msg, LogOutputLevel.Diagnostics) 
    End Try 

    Return result 

End Function 

मैं कुछ छूट गया है? क्या मैं किसी ऑब्जेक्ट को बंद या निपटाना नहीं चाहता हूं? यह अजीब लगता है कि यह लगातार दस अनुरोधों के बाद होता है।

नोट्स:

  1. वर्ग के लिए निर्माता जिसमें इस विधि मैं निम्नलिखित है वास:

    ServicePointManager.DefaultConnectionLimit = 100

  2. अगर मैं सच करने के लिए KeepAlive निर्धारित करते हैं, टाइमआउट पांच अनुरोधों के बाद शुरू होता है।

  3. सभी अनुरोध एक ही डोमेन में पृष्ठों के लिए हैं।

संपादित

मैं इतना है कि मैं करने के लिए साइट "चोट" या एक डॉस हमले प्रयास दिखाई नहीं देते हैं दो से सात सेकंड के प्रत्येक वेब अनुरोध के बीच भी विलंब गयी। हालांकि, समस्या अभी भी होती है।

+0

ऐप होस्ट करने वाले वेब सर्वर का उत्पाद नाम और संस्करण क्या है? – David

+0

आईआईएस 5 – David

+0

के लिए 10 कनेक्शन सीमा है मैं उत्सुक हूं - क्या आपने कभी कारण को कम किया है? मैं एक ही समस्या में भाग रहा हूँ। –

उत्तर

3

मुझे लगता है कि साइट में कुछ प्रकार की डॉस सुरक्षा है, जो कई रैपिस अनुरोधों के साथ मारा जाता है। आप Webrequest पर UserAgent को सेट करने का प्रयास करना चाह सकते हैं।

+0

उत्तर के लिए धन्यवाद। यदि डॉस सुरक्षा कारण है, तो KeepAlive गलत है जब KeepAlive सत्य बनाम टाइमआउट में अंतर क्यों है? –

+0

उपयोगकर्ता सेटिंग सेट करने से स्थिति में सुधार हुआ। मुझे अभी भी कुछ टाइमआउट मिल रहा है लेकिन वे अधिक यादृच्छिक हैं और लगभग हमेशा नहीं। तो इससे पहले कि मैं इसे सही के रूप में चिह्नित कर सकूं, क्या आप यह इंगित करने के लिए अपने उत्तर का विस्तार कर सकते हैं कि UserAgent को क्यों सेट करना है? –

+0

आगे परीक्षण के बाद, यह थोड़ा सा मदद करता है लेकिन मुझे अंततः एक पृष्ठ और सभी लगातार पृष्ठों पर एक टाइमआउट मिलता है, इसलिए मैं डॉस सुरक्षा सिद्धांत पर विश्वास करना शुरू कर रहा हूं। –

4

मैं आज इस मुद्दे में भाग गया और मेरा संकल्प यह सुनिश्चित करना था कि प्रतिक्रिया हर समय बंद हो।

मुझे लगता है कि आपको एक प्रतिक्रिया देने की आवश्यकता है। उपयोग करने के अंदर अपना अपवाद फेंकने से पहले() बंद करें।

Using response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse) 
     Using dataStream As Stream = response.GetResponseStream() 
      Using reader As New StreamReader(dataStream) 
       If response.StatusCode <> HttpStatusCode.OK Then 
        response.Close() 
        Throw New Exception("Got response status code: " + response.StatusCode) 
       End If 
       result = reader.ReadToEnd() 
      End Using 
     End Using 
     response.Close() 
    End Using 
+2

@ गीफ: 'प्रतिक्रिया का उपयोग' सुनिश्चित करता है कि प्रतिक्रिया बंद हो जाती है। –

+0

@ गीफ: मैंने इसे किसी भी तरह से आजमाया, लेकिन इससे मदद नहीं मिली। मेरा मानना ​​है कि जॉन सही है - 'प्रतिक्रिया का उपयोग करना' को चीजों को ठीक से बंद करने का ख्याल रखना चाहिए। हालांकि उत्तर के लिए धन्यवाद। –

+0

मुझे बस टिप्पणी करें कि जॉन की टिप्पणी ने मेरे लिए एक समाधान प्रदान किया है (एक ही समस्या है - बाद के अनुरोधों के बाद टाइमआउट)। –

0

myRequest.Connection = "बंद करें"; सर्वर को कनेक्शन बंद कर देगा जिससे कनेक्शन प्रबंधक कनेक्शन को बंद कर देगा।

+0

धन्यवाद Tymek। मैंने इसे अपने कोड में जोड़ा लेकिन यह एक अपवाद फेंकता है जो कहता है "इस संपत्ति का उपयोग करके रखें-जीवित और बंद नहीं किया जा सकता है। पैरामीटर नाम: मान"। मुझे इसका मतलब क्या है इसके बारे में Google के माध्यम से बहुत कम मिला है। क्या आप इस समस्या से गुजर चुके थे? यदि हां, तो आपने इसे कैसे सही किया? –

2

मैंने निम्नलिखित समाधान का उपयोग किया और यह मेरे लिए काम करता है। उम्मीद है कि यह आपको भी मदद करता है।

चर के रूप में "वैश्विक" घोषित करें।

HttpWebRequest myHttpWebRequest; 
HttpWebResponse myHttpWebResponse; 

फिर प्रत्येक कनेक्शन के बाद हमेशा myHttpWebResponse.Close(); का उपयोग करें।

myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); 
myHttpWebResponse.Close(); 
1

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन मैं हाल ही में इस समस्या को अपने आप (4 का उपयोग कर अपने लक्षित वातावरण के कारण था।0 और अनुमति नहीं दे किसी भी बाहरी विधानसभा संदर्भ)

मैं कुछ हालांकि खुदाई किया था और एक तरह के समाधान मिल जाने और एक .NET भीतरी कामकाज परिप्रेक्ष्य

ServicePointManager.DefaultConnectionLimit = 100; 

ServicePointManager आंतरिक रूप से वास्तविक HTTP अनुरोध हैंडल से बहुत ही दिलचस्प है कई HttpWebRequest ऑब्जेक्ट्स द्वारा बनाया गया ..problem है, ये स्वचालित रूप से बंद नहीं होते हैं और HttpWebRequest को तुरंत एकत्रित कचरा नहीं मिलता है

तो मुझे कुछ बहुत ही रोचक मिला - अगर मैं एक उदाहरण स्तर परिवर्तक HttpWebRequest बनाता हूं और मैं कचरा संग्रह को मजबूर करता हूं संदर्भ स्विच करने के बाद बाहर सीई ... यह काम करता है (बिना DefaultConnectionLimit = 100 हैक)

private HttpWebRequest Request { get; set; } 

public void MyMethod() { 
    Request = (HttpWebRequest)HttpWebRequest.Create("http://myUrl"); 
    GC.Collect(); 
    GC.WaitForFullGCComplete(); 
} 

इससे पहले कि मैं एक नया स्थानीय चर विधि में हर बार बनाने गया था। यह मेरी समस्या को ठीक करने के लिए लग रहा था - शायद आपकी मदद करने में बहुत देर हो चुकी है लेकिन सोचा कि अगर कोई और इस

1

पर सर्वर साझा करता है तो सर्वर डेटाबेस का उपयोग कर रहा है और प्रत्येक डेटाबेस कनेक्शन को ठीक से बंद नहीं कर सकता है, तो आप शायद अधिकतम होने पर एक त्रुटि प्राप्त करें (उदाहरण के लिए स्थिति कोड 502)। कनेक्शन सीमित तक पहुंच गया है (डेटाबेस कनेक्शन टाइमआउट तक)। इस मामले में एक समाधान केवल दिए गए समय के लिए वेबरेक्वेट थ्रेड 'नींद' है। इसके अलावा आपको यह सुनिश्चित करना चाहिए कि प्रसंस्करण के बाद प्रत्येक अनुरोध और प्रतिलिपि धारा बंद हो रही है ('उपयोग' कथन का उपयोग करके सर्वोत्तम मामले में):

संबंधित मुद्दे