2015-09-27 5 views
5

हमारे पास एक सी # डब्ल्यूसीएफ वेब सेवा है जो विंडोज 2008 एसपी 2/आईआईएस 7 पर ओरेकल डेटाबेस तक पहुंच रही है। आम तौर पर डेटा का उपयोग ठीक काम करता है, लेकिन लोड परीक्षण के दौरान, यह अक्सर कई बार बाहर और लॉग और अपवाद कह रही:.NET के लिए ओरेकल डेटा प्रदाता: कनेक्शन अनुरोध

Error occurred when processing XXXXXXXX Web Service 
Oracle.DataAccess.Client.OracleException Connection request timed out at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck) 
    at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src) 
    at Oracle.DataAccess.Client.OracleConnection.Open() 
    at MyWorkspace.WorkForceDataAccess.CheckStaffIdInRSW() 
    at MyWorkspace.MyClass.MyFunction(MyDataType MyData) 

डेटाबेस क्वेरी के लिए, हम कुछ इस तरह का उपयोग करें:

OracleConnection orConn = new OracleConnection(); 
orConn.ConnectionString = "user id=xxx; password=xxx; Connection Timeout=600; Max Pool Size=150; data source= (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = MYHOST.MYDOMAIN.com)(PORT = 1771)) (CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = MYSERVICE.MYDOMAIN.com)))"; 
orConn.Open(); 

using (var cmd = new OracleCommand("MY_UTIL.check_StaffIdInRSW", orConn) { CommandType = CommandType.StoredProcedure }) 
{ 
    cmd.Parameters.Add("P_Staff_Id", OracleDbType.Int32); 
    cmd.Parameters["P_Staff_Id"].Direction = ParameterDirection.Input; 
    cmd.Parameters["P_Staff_Id"].Value = Convert.ToInt32(MyDataObject.StaffId); 

    cmd.Parameters.Add("P_retvalue", OracleDbType.Int32); 
    cmd.Parameters["P_retvalue"].Direction = ParameterDirection.Output; 

    cmd.ExecuteNonQuery(); // Execute the function 

    //obtain result 
    returnVal = int.Parse(cmd.Parameters["P_retvalue"].Value.ToString()); 
} 

मुझे लगता है कि बहुत आश्वस्त हूँ संग्रहीत की जाने वाली संग्रहीत प्रक्रिया हर समय नहीं ले रही है। यह एक बहुत ही सरल प्रक्रिया है जो जल्दी से जांचती है कि क्या P_Staff_Id तालिका में मौजूद है और परिणाम देता है।

इसके अतिरिक्त, यह केवल लोड परीक्षण के दौरान होता है। सामान्य परिचालन के दौरान चीजें ठीक होती हैं लेकिन प्रति सेकंड 1 संदेश के साथ भारी भार के दौरान, यह कुछ समय के लिए चिकनी चलने के बाद होती है।

समाधान के लिए, मैं जोड़ लिया है "कनेक्शन टाइमआउट = 600; अधिकतम पूल आकार = 150" कनेक्शन स्ट्रिंग के लिए, लेकिन यह समस्या का समाधान नहीं

हम एक ही आवेदन एक विकास सर्वर पर चल रहा है। और यह क्या करने की कोशिश करना सराहना की जाएगी करने के लिए के रूप में ठीक काम करता है। हम इस समस्या का सामना करना पड़ा कभी नहीं।

कोई सुझाव। ऐसा लगता है कि मैं विकल्पों में से निकलता जा रहा हूँ।

+0

स्टैकट्रेस सुझाव है कि प्रक्रिया मुद्दा नहीं है। अपवाद को कनेक्शन के निष्पादन से पहले उठाया जाता है। खोलें, तो ऐसा लगता है कि डेटाबेस मशीन ओवरलोड हो गई है, इसलिए यह टाइमआउट अवधि के भीतर ग्राहक को प्रतिक्रिया नहीं दे सकती है। इसे ओरेकल में पूल आकार या प्रक्रिया सीमाओं से संबंधित नहीं होना चाहिए, इन्हें विभिन्न अपवादों को फेंकना चाहिए। इसके अलावा मैं उस पूल आकार के बारे में संदिग्ध होगा क्योंकि यह समझ में नहीं आता कि पूल डेटाबेस की संख्या से काफी बड़ा पूल हो सकता है। या आपके पास कनेक्शन रिसाव कहीं है। – Husqvik

+0

मैंने इस समस्या के बाद कनेक्शन स्ट्रिंग में कनेक्शन टाइमआउट और मैक्स पूल आकार जोड़ा - लेकिन इससे मदद नहीं मिली। वेब सेवा इनके बिना DEV पर्यावरण में ठीक काम कर रही थी। कनेक्शन रिसाव से, क्या आप ओरेकलकनेक्शन ऑब्जेक्ट को बंद करने के बाद स्पष्ट रूप से बंद करने और निपटाने का सुझाव देंगे? – DjD

+0

विज्ञापन कनेक्शन रिसाव - यदि कनेक्शन ऑब्जेक्ट केवल एक ही फ़ंक्शन के भीतर छोटा रहता है तो (var कनेक्शन = ...) {...} निश्चित रूप से सुरक्षित है। लेकिन मुझे उम्मीद नहीं है कि यह मुद्दा है। पूल पूरी तरह से उपयोग होने पर आपको अलग अपवाद मिलेगा। विज्ञापन लोड परीक्षण - मुझे उम्मीद है कि आप समानांतर में एप्लिकेशन या फ़ंक्शन के कई उदाहरण चलाएंगे। यह भी उम्मीद है कि आप समर्पित कनेक्शन का उपयोग करें, साझा सर्वर को ओरेकल सेटिंग के रूप में नहीं। क्या आप जांच सकते हैं कि परीक्षण के दौरान सत्र में डेटाबेस कैसा दिखता है यह देखने के लिए कि कितने सत्र और वास्तव में कितने सक्रिय सत्र हैं। – Husqvik

उत्तर

4

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

मैंने OracleConnection को स्पष्ट रूप से खोलने के लिए डीबीकॉन्टेक्स्ट कन्स्ट्रक्टर को संशोधित किया। मैंने इस कोड को

for (i = 0; i < 5; i++) 
    try { 
     oracleConnection.Open(); 
    } catch (OracleException) { 
    Sleep for 15 ms and retry. 
    On last attempt I also do OracleConnection.ClearAllPools() 
    } 

में सुधार किया, लेकिन यह अभी भी इसे हल नहीं किया गया। मैंने डीबगर से पकड़ में तोड़ दिया, और देखा कि कई धागे खोलने की कोशिश कर रहे हैं और कुछ धागे दूर हो रहे हैं। ओरेकल स्टैक में ओपन पर, ओरेकल अपने आंतरिक उद्देश्य के लिए ThreadPool.QueueUserWorkItem करता है और इसके पूरा होने की प्रतीक्षा करता है। मैं इसके इंतजार के ढेर के शीर्ष पर देख सकता हूं। यहां पूल किए गए कनेक्शन के बहुत सारे उपलब्ध हैं (डिफ़ॉल्ट 100 है), मैं शायद 10 का उपयोग कर रहा हूं। इसलिए यह संसाधन से बाहर नहीं है।

लेकिन समस्या हमारे कोड में भी है, हमने थ्रेडपूल का उपयोग किया। QueueUserWorkItem बिना अतिरिक्त थ्रॉटलिंग के। मैंने सोचा कि बस उन सभी नौकरियों को कतारबद्ध करने के लिए अच्छा था जो हमें करने की ज़रूरत है, हमें इसकी कितनी आवश्यकता है, और .NET को इसका ख्याल रखना चाहिए। लेकिन इसमें सूक्ष्म मुद्दा है। हमारी सभी नौकरियों ने पूरी कतार गणना का उपभोग किया है। जब ओरेकलकनेक्शन पूल से पूल कनेक्शन प्राप्त करना चाहता है, तो यह थ्रेड पूल में भी कतार में आता है। लेकिन यह कभी पूरा नहीं होगा। हमारी नौकरियां सभी OracleConnection के लिए प्रतीक्षा कर रही हैं। खोलें, और इसकी कतारबद्ध थ्रेड प्रो अभी भी कतार में होगी। तो अंत में इंतजार टाइमआउट से बाहर निकल जाएगा। यह एक दयालु बात है कि भले ही बहुत सारे पूल कनेक्शन उपलब्ध हैं, हमने सभी थ्रेडपूल प्रो का उपभोग किया है, और ओरेकल के थ्रेडपूल को भी मौका नहीं मिला। यहां थ्रेडपूल सेट करना है। मेटमैक्स थ्रेड भी मदद नहीं करेगा। मुद्दा अभी भी वही है। हम सभी थ्रेड पूल संसाधनों को हॉग करते हैं, और ऑर्केल एक नहीं ढूंढ पाएगा और अभी भी कतार में होगा।

फ़िक्स केवल थ्रेडपूल पर भरोसा नहीं करना है, लेकिन हम अपनी खुद की थ्रॉटलिंग भी जोड़ते हैं। मैंने ब्लॉकिंग कोलेक्शन और सेम्पाहोर्स का इस्तेमाल किया और थ्रेडपूल में समवर्ती नौकरियों की केवल कुछ सीमा संख्या जोड़ दी, 5 कहें। इस तरह ओरेकलकनेक्शन हमेशा थ्रेडपूल थ्रेड उपलब्ध होगा, और असफल नहीं होगा।

1

अंत में कनेक्शन.क्लोज़() जोड़ने का प्रयास करें। मुझे आपके कोड में कनेक्शन जारी करने और उन्हें स्पष्ट रूप से कनेक्शन पूल में वापस नहीं दिख रहा है। तो जीसी शुरू होने पर ही कनेक्शन पूल में कनेक्शन वापस किया जा रहा है।

+0

हमने इस कनेक्शन की तरह कुछ लागू किया। कनेक्शन को बंद करने के लिए बंद करें() और यह काम करने लग रहा था। आपकी मदद के लिए आप सभी को शुक्रिया। – DjD

1

मुझे भी Connection.Close()

के उपयोग के एक लंबे विश्लेषण मैं कुछ बात सीखा है के रूप में नीचे

  1. Connection.Close (उल्लेख के बाद के बाद भी, और अक्सर इस मुद्दे को पाने के लिए इस्तेमाल किया) नहीं करता db कनेक्शन निपटाने
  2. कनेक्शन समय बाहर नहीं करता है कि इस मुद्दे को मतलब केवल डाटाबेस क्वेरी के साथ है
  3. कनेक्शन समय बाहर भी कनेक्शन पूल में संपूर्ण कनेक्शन (जो मेरे लिए अपराधी था की वजह के रूप में यह अधिकतम पर पहुंच गया हो सकता है डाटाबेस कनेक्शन की imum सत्र)

फिक्स: - विश्लेषण काफी समय लगा लेकिन ठीक सिर्फ 2 मिनट

using(DbConnection instance) 
{ 

} 

का उदाहरण है: -

using (DbConnection objDbConnection = new DbConnection()) 
{ 
    ojDbConnection.PersistData(); 
} 

के तहत PersistData(); ओपन, क्लोज़ ईटीसी जैसे सभी डीबी ऑपरेशंस

हम सब जानता है प्रदर्शन किया जाएगा "का उपयोग करना"

try 
{ 

} 
catch() 
{ 

} 
Finally 
{ 
    Dispose objDbConnection; 
} 

का संक्षिप्त रूप आशा है कि यह मदद करता है, के रूप में यह मुझे मदद की

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