আমি কিভাবে ASP.NET এবং SQL সার্ভারের মধ্যে একটি সংযোগ পুল সমস্যা সমাধান করতে পারি?




sql-server sql-server-2005 (16)

আমার কাছে একই সমস্যা ছিল এবং উৎসটি খুঁজে পেতে আমাকে কী সহায়তা করতে চেয়েছিল তা ভাগ করতে চেয়েছিলেন: অ্যাপ্লিকেশন নামটি আপনার সংযোগ স্ট্রিংয়ে যুক্ত করুন এবং তারপরে এসকিউএল সার্ভারের সাথে খোলা সংযোগটি প্রেরণ করুন

select st.text,
    es.*, 
    ec.*
from sys.dm_exec_sessions as es
    inner join sys.dm_exec_connections as ec on es.session_id = ec.session_id
    cross apply sys.dm_exec_sql_text(ec.most_recent_sql_handle) st
where es.program_name = '<your app name here>'

গত কয়েকদিন আমরা আমাদের ওয়েবসাইটে এই ত্রুটি বার্তাটি খুব বেশি দেখি:

"সময়সীমা মেয়াদ শেষ হয়ে গেছে। পুল থেকে সংযোগ প্রাপ্ত করার পূর্বে সময়সীমা শেষ হয়ে গেছে। এটি ঘটেছে কারণ সমস্ত পুলযুক্ত সংযোগগুলি ব্যবহার করা হয়েছিল এবং সর্বাধিক পুল আকার পৌঁছেছে।"

আমরা কিছু সময়ের মধ্যে আমাদের কোড পরিবর্তন করা হয় নি। আমি খোলা সংযোগগুলি বন্ধ করতে কোডটি সংশোধন করেছি যা বন্ধ ছিল না, তবে সবকিছু ঠিকঠাক দেখতে পাওয়া যায়।

  • আমি কিভাবে এই সমাধান করতে পারি?

  • আমি এই পুল সম্পাদনা করতে হবে?

  • আমি কিভাবে এই পুল এর সর্বোচ্চ সংখ্যার সংযোগ সম্পাদনা করতে পারি?

  • একটি উচ্চ ট্রাফিক ওয়েবসাইটের জন্য প্রস্তাবিত মান কি?

হালনাগাদ:

আমি আইআইএস কিছু সম্পাদনা করতে হবে?

হালনাগাদ:

আমি সক্রিয় সংযোগগুলির সংখ্যা 15 থেকে 31 পর্যন্ত কোথাও পেয়েছি, এবং আমি দেখেছি যে SQL সার্ভারে কনফিগার হওয়া সর্বাধিক অনুমোদিত সংযোগগুলি 3200 সংযোগের চেয়ে বেশি, 31 টি বেশি বা আমি ASP.NET কনফিগারেশনে কিছু সম্পাদনা করতে পারি ?


এটা ব্যবহার কর:

finally
{
    connection.Close();
    connection.Dispose();
    SqlConnection.ClearPool();
}

আপনি সংযোগ স্ট্রিং মধ্যে MinPoolSize=xyz এবং / অথবা MaxPoolSize=xyz উল্লেখ করে সর্বনিম্ন এবং সর্বাধিক পুল আকার উল্লেখ করতে পারেন। সমস্যা এই কারণটি যদিও একটি ভিন্ন জিনিস হতে পারে।


আপনিও টাইমআউট সমস্যার সমাধান করতেও চেষ্টা করতে পারেন:

আপনি যদি আপনার ওয়েব কনফিগারে httpRuntime যুক্ত না করেন তবে এটি <system.web> ট্যাগে যুক্ত করুন

<sytem.web>
     <httpRuntime maxRequestLength="20000" executionTimeout="999999"/>
</system.web>

এবং

এই মত আপনার সংযোগ স্ট্রিং সংশোধন করা;

 <add name="connstring" connectionString="Data Source=DSourceName;Initial Catalog=DBName;Integrated Security=True;Max Pool Size=50000;Pooling=True;" providerName="System.Data.SqlClient" />

শেষ ব্যবহার

    try
    {...} 
    catch
    {...} 
    finaly
    {
     connection.close();
    }

আপনি সংযোগ বা একটি datareader বন্ধ করার আগে বন্ধ না হয় এবং respond.redirects যে DataReaders জন্য চেক করেছেন। আপনি পুনঃনির্দেশের আগে তাদের বন্ধ না সংযোগ সংযোগ খোলা।


এই প্রধানত সংযোগ কারণে অ্যাপ্লিকেশন বন্ধ করা হয় না। সংযোগ স্ট্রিংয়ে "MinPoolSize" এবং "MaxPoolSize" ব্যবহার করুন।


আমার ক্ষেত্রে, আমার কাছে অসীম লুপ ছিল (ডেটাবেস থেকে মূল্য পেতে চেষ্টা করে সম্পত্তিটি পেতে) যা কয়েকটি এসকিউএল সংযোগ খুলতে থাকে।

while (true)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        someCall(connection);
    }
}

আপনি আপনার কোড সংযোগ সংযোগ আছে। আপনি তাদের বন্ধ করছেন তা প্রত্যয়িত করার জন্য ব্যবহার করার চেষ্টা করতে পারেন।

 Using (SqlConnection sqlconnection1 = new SqlConnection(“Server=.\\SQLEXPRESS ;Integrated security=sspi;connection timeout=5”)) {
                          sqlconnection1.Open();
                          SqlCommand sqlcommand1 = sqlconnection1.CreateCommand();
                          sqlcommand1.CommandText = raiserror (‘This is a fake exception’, 17,1)”;
                          sqlcommand1.ExecuteNonQuery();  //this throws a SqlException every time it is called.
                          sqlconnection1.Close(); //Still never gets called.
              } // Here sqlconnection1.Dispose is _guaranteed_

https://blogs.msdn.microsoft.com/angelsb/2004/08/25/connection-pooling-and-the-timeout-expired-exception-faq/


আমিও আমার এই সমস্যাটি মোকাবেলা করেছি, যখন আমার .নেট অ্যাপ্লিকেশনগুলিতে কোন তৃতীয় পক্ষের ডাটা স্তর ব্যবহার করা হয়। সমস্যাটি ছিল লেয়ারটি সঠিকভাবে সংযোগ বন্ধ করে নি।

আমরা স্তরটি ছুঁড়ে ফেলেছি এবং নিজের তৈরি করেছি, যা সবসময় সংযোগ বন্ধ করে এবং সংযোগগুলিকে নিষ্পত্তি করে। তারপর থেকে আমরা আর ভুল পাবেন না।


আমরা পাশাপাশি আমাদের ওয়েব সাইটে সময় এই সমস্যা সম্মুখীন। আমাদের ক্ষেত্রে অপরাধী, আমাদের পরিসংখ্যান / সূচী তারিখ খুঁজে পেয়ে। এটি একটি দ্রুত চলমান ক্যোয়ারী (অবশেষে) ধীরে ধীরে এবং সময় হয়ে ওঠে।

পরিসংখ্যান আপডেট করা এবং / অথবা প্রশ্নের দ্বারা প্রভাবিত টেবিলে সূচী পুনর্নির্মাণের চেষ্টা করুন এবং দেখুন যে এটি সাহায্য করে।


যতক্ষণ না আপনার ব্যবহার অনেক বেড়ে যায়, ততক্ষণ মনে হয় যে এটি কেবলমাত্র একটি কাজের কাজ। আইএমও, সবচেয়ে সম্ভবত বিকল্পটি হল যে সংযোগগুলি ব্যবহার করা হচ্ছে এবং তা অবিলম্বে প্রকাশ করা হচ্ছে না। আপনি সব ক্ষেত্রে ব্যবহার using নিশ্চিত করছেন? অথবা (যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা যাহা য


এই সমস্যা আমি আমার কোড ছিল। আমি কিছু উদাহরণ কোড পেস্ট করব আমি উপরে ত্রুটি নিচে এসেছেন। পুল থেকে সংযোগ পাওয়ার পূর্বে মেয়াদ শেষ হয়ে গেছে। এটি ঘটেছে কারণ সমস্ত পুলযুক্ত সংযোগগুলি ব্যবহার করা হয়েছিল এবং সর্বাধিক পুল আকার পৌঁছেছে।

 String query = "insert into STATION2(ID,CITY,STATE,LAT_N,LONG_W) values('" + a1 + "','" + b1 + "','" + c1 + "','" + d1 + "','" + f1 + "')";
    //,'" + d1 + "','" + f1 + "','" + g1 + "'

    SqlConnection con = new SqlConnection(mycon);
    con.Open();
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = query;
    cmd.Connection = con;
    cmd.ExecuteNonQuery();
    **con.Close();**

আপনি প্রতিটি সময় সংযোগ বন্ধ করতে চান। এর আগে আমি আমাদের সাথে ঘনিষ্ঠ সংযোগটি না করেই ভুল করেছি। বন্ধ বিবৃতি যোগ করার পরে আমি এই ত্রুটি এসেছেন


অধিকাংশ ক্ষেত্রে সংযোগ পুলিং সমস্যা "সংযোগ লিক্স" সাথে সম্পর্কিত হয়। আপনার অ্যাপ্লিকেশন সম্ভবত সঠিকভাবে এবং ধারাবাহিকভাবে তার ডাটাবেস সংযোগ বন্ধ করে না। যখন আপনি সংযোগগুলিকে খোলা রাখেন, তখন তারা তাদের Finalize() পদ্ধতি কল করে আপনার জন্য .NET আবর্জনা সংগ্রাহক তাদের বন্ধ করে না হওয়া পর্যন্ত অবরুদ্ধ থাকে।

আপনি সত্যিই সংযোগ বন্ধ করা হয় তা নিশ্চিত করতে চান। উদাহরণস্বরূপ নিম্নলিখিত কোডটি একটি সংযোগ লিক হতে পারে, যদি কোডটি .Open এবং .Open মধ্যে ব্যতিক্রম .Open দেয় তবে:

var connection = new SqlConnection(connectionString);
connection.Open();
// some code
connection.Close();                

সঠিক উপায় এই হতে হবে:

var connection = new SqlConnection(ConnectionString);
try
{
     connection.Open();
     someCall (connection);
}
finally
{
     connection.Close();                
}

অথবা

using (SqlConnection connection = new SqlConnection(connectionString))
{
     connection.Open();
     someCall(connection);
}

যখন আপনার ফাংশন কোন ক্লাস পদ্ধতি থেকে একটি সংযোগ প্রদান করে তখন নিশ্চিত করুন যে আপনি এটি স্থানীয়ভাবে ক্যাশ করুন এবং তার Close পদ্ধতিটি কল Close । উদাহরণস্বরূপ আপনি এই কোড ব্যবহার করে একটি সংযোগ লিক করব:

var command = new OleDbCommand(someUpdateQuery, getConnection());
result = command.ExecuteNonQuery();
connection().Close(); 

getConnection() থেকে প্রথম কল থেকে পাওয়া getConnection() বন্ধ হচ্ছে না। আপনার সংযোগ বন্ধ করার পরিবর্তে, এই লাইন একটি নতুন তৈরি করে এবং এটি বন্ধ করার চেষ্টা করে।

যদি আপনি SqlDataReader বা SqlDataReader ব্যবহার করেন, তবে তাদের বন্ধ করুন। যদিও সংযোগটি বন্ধ করে দেওয়ার মতো মনে হয় তবে এটি ব্যবহার করার সময় আপনার ডেটা রিডার অবজেক্টগুলিকে স্পষ্টভাবে বন্ধ করার জন্য অতিরিক্ত প্রচেষ্টা রাখুন।

এমএসডিএন / এসকিউএল ম্যাগাজিন থেকে এই নিবন্ধটি " একটি সংযোগ পুল ওভারফ্লো কেন? " অনেকগুলি বিশদ ব্যাখ্যা করে এবং কিছু ডিবাগিং কৌশল প্রস্তাব করে:

  • sp_who বা sp_who2 চালান। এই সিস্টেম সঞ্চিত পদ্ধতি sysprocesses সিস্টেম সারণী থেকে তথ্য ফেরত দেয় যা সমস্ত কাজের প্রক্রিয়াগুলির অবস্থা এবং তথ্য দেখায়। সাধারণত, আপনি সংযোগ প্রতি একটি সার্ভার প্রক্রিয়া আইডি (SPID) দেখতে পাবেন। সংযোগ স্ট্রিংয়ে অ্যাপ্লিকেশন নাম যুক্তি ব্যবহার করে আপনি যদি আপনার সংযোগ নামকরণ করেন, তবে আপনার কাজের সংযোগগুলি খুঁজে পাওয়া সহজ হবে।
  • এসকিউএল সার্ফাই প্রোফাইলার ব্যবহার করুন এসকিউএল প্রোফাইলে TSQL_Replay টেমপ্লেট খোলা সংযোগ ট্রেস। আপনি যদি প্রোফাইলারের সাথে পরিচিত হন, তবে sp_who ব্যবহার করে এই পদ্ধতিটি ভোটের চেয়ে সহজ।
  • পুল এবং সংযোগ নিরীক্ষণ করার জন্য পারফরম্যান্স মনিটর ব্যবহার করুন। আমি একটি মুহূর্ত এই পদ্ধতি আলোচনা।
  • কোডে কর্মক্ষমতা কাউন্টার মনিটর। আপনি কাউন্টারগুলি বা নতুন .NET পারফরম্যান্স কাউন্টার নিয়ন্ত্রণগুলি ব্যবহার করে রুটিনগুলি ব্যবহার করে আপনার সংযোগ পুলের স্বাস্থ্য এবং প্রতিষ্ঠিত সংযোগগুলির সংখ্যা নিরীক্ষণ করতে পারেন।

যদি আপনি জটিল লিগ্যাসি কোডে কাজ করছেন যেখানে সহজ ব্যবহার (..) {..} সম্ভব নয় - যেমন আমি ছিলাম - আপনি এই সোস্যাল্টে পোস্ট করা কোড স্নিপেটটি দেখতে চাইলে এটি নির্ধারণ করতে পারেন একটি সংযোগ সম্ভাব্য লিক হয় যখন সংযোগ সৃষ্টি স্ট্যাক কল (একটি নির্দিষ্ট সময়সীমার পরে বন্ধ না)। এই লিক কারণ স্পট মোটামুটি সহজ করে তোলে।


পোস্ট সমাধান ছাড়াও ....

লিগ্যাসি কোডের 1000 পৃষ্ঠাগুলির সাথে ডিল করার ক্ষেত্রে, প্রতিটি একটি সাধারণ GetRS একাধিক বার কল করে, এখানে সমস্যাটির সমাধান করার আরেকটি উপায় রয়েছে:

একটি বিদ্যমান সাধারণ DLL তে, আমরা কমান্ড বিহাইভার্স ক্লোজকোনেশন বিকল্প যোগ করেছিলাম:

    static public IDataReader GetRS(String Sql)
    {
        SqlConnection dbconn = new SqlConnection(DB.GetDBConn());
        dbconn.Open();
        SqlCommand cmd = new SqlCommand(Sql, dbconn);
        return cmd.ExecuteReader(CommandBehavior.CloseConnection);   
    }

তারপরে প্রতিটি পৃষ্ঠায়, যতক্ষণ আপনি ডাটা রিডার বন্ধ করেন, সংযোগটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায় যাতে সংযোগ লিকগুলি প্রতিরোধ করা হয়।

    IDataReader rs = CommonDLL.GetRS("select * from table");
    while (rs.Read())
    {
        // do something
    }
    rs.Close();   // this also closes the connection

.নেট ফ্রেমওয়ার্ক ভি 4.6.1 ইনস্টল করার পরে একটি রিমোট ডাটাবেসের সাথে আমাদের সংযোগগুলি এই পরিবর্তনের কারণে সময় শেষ হয়ে গেছে

সংযোগ স্ট্রিংয়ে TransparentNetworkIPResolution প্যারামিটারটি ঠিক করতে ঠিক করুন এবং এটি মিথ্যাতে সেট করুন:

সার্ভার = myServerName; ডাটাবেস = myDataBase; Trusted_Connection = true; TransparentNetworkIPResolution = মিথ্যা





sql-server-2005