Tôi đang làm việc trên một thử nghiệm hiệu suất trong đó bao gồm một số khách hàng bắn phá máy chủ với 150 yêu cầu mỗi, nhanh nhất có thể.Tại sao ứng dụng của tôi đợi đồng bộ hóa quá nhiều?
Máy chủ được xây dựng từ 3 dịch vụ WCF, một máy chủ được mở ra bên ngoài với httpbinding, nó nói chuyện với 2 dịch vụ khác thông qua net.pipe (IPC). một trong những dịch vụ chịu trách nhiệm về các kết nối DB (SQL server 2008 R2).
dịch vụ kết nốiDB này sử dụng những nâng cao chuỗi kết nối sau:
Min Pool Size=20; Max Pool Size=1000; Connection Timeout=20;
và là WCF Throttled (giống như tất cả các dịch vụ WCF khác).
Tôi nhận thấy rằng khi tôi kích hoạt 1 ứng dụng, có thể mất 3 giây, nhưng khi tôi kích hoạt 3 khách hàng, nó có thể mất 8-9 hoặc hơn.
Tôi đã kiểm tra với trình lược tả máy chủ SQL để xem có bao nhiêu tiến trình đồng thời được sử dụng và tôi thấy rằng chỉ có khoảng 8 quy trình đang được sử dụng.
Vì vậy, tôi nhận ra rằng ở đâu đó trong máy chủ, các yêu cầu được xếp hàng đợi thay vì đồng thời được xử lý.
Để có được để dưới cùng của nó, tôi đã sử dụng một hồ sơ hoạt động (ANts để được chính xác) mà chỉ cho tôi rằng khoảng 70% thời gian bị lãng phí trên "Chờ đợi để đồng bộ hóa
Khi tôi mở đồ thị gọi tôi thấy hai điều mà trông lạ nhưng tôi không chắc chắn những gì họ có nghĩa là:
- System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke đang được sử dụng ở phía trên cùng của cây, là ok mà để xử lý đồng thời?
- Tất cả sự cố đồng bộ hóa liên quan đến một số loại hoạt động của SQL Server, như ExecuteNonQuery, ExecuteReader và như vậy (Khi tôi đến cuối cây gọi)
Tôi nhận thấy rằng dịch vụ kết nối DB sử dụng dự án DAL (một số mã cũ, thật không may)) hoàn toàn tĩnh.
Sau khi đọc this Tôi không chắc chắn nếu mã của DAL có vấn đề hay không, dưới đây là ví dụ về cuộc gọi thủ tục được lưu trữ.
public static int PerformStoredProcedure(string storedP,string ext,out string msg)
{
msg = "";
SqlCommand command = GetSqlCommand(storedP,ext);
command.Connection.Open();
int result = (int)PerformStoredProcedure(command,out msg);
command.Connection.Close();
return result;
}
Phương pháp này được gọi là thường là từ các dịch vụ kết nối DB:
public static int PerformStoredProcedureWithParams(string storedP,string ext,out string msg, params object[] pars)
{
msg = "";
SqlCommand command = GetSqlCommand(storedP,ext);
UpdateCommandParams(command, pars);
command.Connection.Open();
int result = (int)PerformStoredProcedure(command,out msg);
command.Connection.Close();
return result;
}
Vì vậy, có gì sai ở đây?
Hoặc có lẽ tôi nên tìm một nơi khác?
Edit:
Sau khi bình luận Brijesh của tôi nhận ra tôi đã không thay đổi InstanceContextMode mặc định và ConcurrencyMode của các dịch vụ WCF ... Loại sai lầm mới bắt đầu tôi đoán.
Tôi vẫn không chắc chắn liệu mình có nên sử dụng PerSession/Multiple hoặc PerCall/Single hay không. Như tôi thấy, mỗi dịch vụ sẽ xử lý từng yêu cầu như đối tượng, bất kể khách hàng.
Tôi nên sử dụng thông tin gì?
2 EDIT:
Sau khi sử dụng PerCall và PerSession/Nhiều, tôi nhận thấy rằng vẫn không có thay đổi (ít nhất là trong dịch vụ DB). những gì tôi thấy là dịch vụ điểm vào chính có thể mở ra rất nhiều chủ đề, nhưng chỉ một vài (vẫn còn khoảng 8-10 chủ đề) được mở tại dịch vụ kết nối DB.
có bất kỳ lý do nào khác khiến điều này có thể xảy ra không? Tôi loại trừ khả năng Dal là một vấn đề vì không đủ yêu cầu đi trong dịch vụ DB vì vậy tôi tìm một cái gì đó của mình trong dịch vụ hoặc một cái gì đó trong các khách hàng ...
EDIT 3:
Dưới đây là các tập tin cấu hình :
phần dịch vụ WCF cấu hình của người quản lý: khách hàng
<services>
<service behaviorConfiguration="ServicesBehavior" name="Verifone.GenericPP.GPPManagerService.GPPManagerServiceImpl">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9090/GPPManagerService/"/>
</baseAddresses>
</host>
<endpoint contract="Verifone.GenericPP.GPPManagerService.IGPPManagerService" binding="basicHttpBinding" address="GPPManagerService"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServicesBehavior">
<!--amith 13-05-2012-->
<serviceThrottling
maxConcurrentCalls="1000"
maxConcurrentSessions="1000"
maxConcurrentInstances="1000"
/>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding" maxBufferSize="10000000" maxReceivedMessageSize="10000000">
<readerQuotas maxStringContentLength="10000000" maxArrayLength="10000000"/>
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
Manager:
<endpoint name="endpoint1" contract="IDBConnectionContract" bindingConfiguration="basicHttpBinding" binding="basicHttpBinding" address="http://localhost:9010/DBConnectionService/DBService"></endpoint>
<endpoint name="endpoint2" contract="IGPPService" bindingConfiguration="basicHttpBinding" binding="basicHttpBinding" address="http://localhost:9095/GenericPPService/GenericPPService"></endpoint>
Dịch vụ kết nối DB:
<service behaviorConfiguration="ServicesBehavior" name="Verifone.DBConnectionService.DBConnectionContracImpl">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9010/DBConnectionService/"/>
<add baseAddress="net.pipe://localhost/DBConnectionService/"/>
</baseAddresses>
</host>
<endpoint contract="Verifone.DBConnectionService.IDBConnectionContract" binding="basicHttpBinding" address="DBService"></endpoint>
<endpoint contract="Verifone.DBConnectionService.IDBConnectionContract" binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_Configuration" address="" name="pipeEndpoint"/>
</service>
client Logic dịch vụ của doanh nghiệp là khá nhiều giống như người quản lý của.
Tất cả các dịch vụ đều tự tổ chức và tôi có một lớp DBConnectionProxy tại của người quản lý và mã kinh doanh mà họ kích hoạt như thế này:
DBConnectionContractClient _dbConnectionContractClient = null;
try
{
objDBConnectionContractClient = new DBConnectionContractClient();
objDBConnectionContractClient.ExecuteStoredProcedure(input, out result);
}
bạn đang sử dụng loại chế độ ví dụ và chế độ đồng nhất nào? –
Có vẻ như tôi không đặt chế độ nào, vì vậy cài đặt mặc định được áp dụng ... Tôi nhớ tôi muốn thêm mỗi phiên/nhiều, nhưng có thể đã bỏ lỡ nó bằng cách nào đó, tôi có nên thêm nó không? – Mithir
persession/single là mặc định, hãy thử với chế độ concurency nhiều –