我正在尝试使用WCF为Oracle构建DAL。我的应用程序在Intranet上,所以我选择了tcp绑定,这应该是最快的。我的要求很简单。我的DAL公开了基于query / sp返回数据集的函数。最初我们使用webservice,一切都很好,除了超时问题。 一些SP请求需要2个多小时才能完成,WCF运行得非常顺畅...如果你设置参数权限没有超时:)
问题来自于我们实时播放,超过150个用户同时访问它。我研究并发现我没有关闭代理。所以我这样做了,情节有所改善,但性能仍然只有web服务的50%,而且用户根本无法连接。
现在很多文章和我经历的很多建议,最典型的答案是它取决于你的要求如何设置参数(它们是如此多...... :()。
根据我的具体要求,有人会帮我提出建议。长时间通话只有10%(那些消耗2-3小时)。
我的服务托管在窗口服务中。请参阅以下行:
命名空间Phoenix { partial class PhoenixDataServiceHost:ServiceBase { public PhoenixDataServiceHost() { 的InitializeComponent(); }
internal static ServiceHost svh;
string IpPort = "8043";
protected override void OnStart(string[] args)
{
NetTcpBinding ntcp = new NetTcpBinding();
ntcp.Security.Mode = SecurityMode.None;
ntcp.MaxBufferPoolSize = 2147483647;
ntcp.MaxReceivedMessageSize = 2147483647;
ntcp.MaxBufferSize = 2147483647;
ntcp.ReaderQuotas.MaxStringContentLength = 2147483647;
ntcp.ReaderQuotas.MaxDepth = 2147483647;
ntcp.ReaderQuotas.MaxBytesPerRead = 2147483647;
ntcp.ReaderQuotas.MaxNameTableCharCount = 2147483647;
ntcp.ReaderQuotas.MaxArrayLength = 2147483647;
ntcp.SendTimeout = new TimeSpan(3, 0, 0);
ntcp.ReceiveTimeout = new TimeSpan(3, 0, 0);
ntcp.OpenTimeout = new TimeSpan(0, 10, 0);
ntcp.CloseTimeout = new TimeSpan(0, 10, 0);
ntcp.MaxConnections = 400;
ntcp.ListenBacklog = 500;
if (svh != null)
{
svh.Close();
}
svh = new ServiceHost(typeof(PhoenixDataService));
((ServiceBehaviorAttribute)svh.Description.Behaviors[0]).MaxItemsInObjectGraph = 2147483647;
((ServiceBehaviorAttribute)svh.Description.Behaviors[0]).IncludeExceptionDetailInFaults = true;
svh.AddServiceEndpoint(
typeof(IPhoenixDataLayer),
ntcp,
"net.tcp://localhost:"+IpPort);
System.ServiceModel.Description.ServiceThrottlingBehavior throttlingBehavior =
new System.ServiceModel.Description.ServiceThrottlingBehavior();
throttlingBehavior.MaxConcurrentCalls = 400;
throttlingBehavior.MaxConcurrentInstances = Int32.MaxValue;
throttlingBehavior.MaxConcurrentSessions = 400;
svh.Description.Behaviors.Add(throttlingBehavior);
svh.Open();
}
protected override void OnStop()
{
if (svh != null)
{
svh.Close();
}
}
}
}
我在客户端使用渠道工厂。请在下面找到代码:
使用System; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text; 用凤凰; 使用System.ServiceModel; 使用System.Data; 使用CustomEnum; 命名空间KIPLProject { 公共类PhoenixDataServerProxy { static ChannelFactory scf; 静态IPhoenixDataLayer客户端;
public void OpenChannel()
{
// client = new PhoenixDataService();
// return;
//if (scf == null)
//{
NetTcpBinding ntcp = new NetTcpBinding();
ntcp.MaxBufferPoolSize = 2147483647;
ntcp.MaxReceivedMessageSize = 2147483647;
ntcp.MaxBufferSize = 2147483647;
ntcp.ReaderQuotas.MaxStringContentLength = 2147483647;
ntcp.ReaderQuotas.MaxDepth = 2147483647;
ntcp.ReaderQuotas.MaxBytesPerRead = 2147483647;
ntcp.ReaderQuotas.MaxNameTableCharCount = 2147483647;
ntcp.ReaderQuotas.MaxArrayLength = 2147483647;
ntcp.SendTimeout = new TimeSpan(3, 0, 0);
ntcp.ReceiveTimeout = new TimeSpan(3, 0, 0);
ntcp.OpenTimeout = new TimeSpan(0, 2, 0);
ntcp.CloseTimeout = new TimeSpan(0, 10, 0);
ntcp.Security.Mode = SecurityMode.None;
scf = new ChannelFactory<IPhoenixDataLayer>(ntcp, "net.tcp://"+Program.wcfPort);
client = scf.CreateChannel();
// }
}
public PhoenixDataServerProxy(string Name, KIPLCommandType Type)
{
SPName = Name;
SPType = Type.ToString();
Index = 0;
}
public PhoenixDataServerProxy()
{
Index = 0;
}
#region proxy for WCF Service Function
public DataSet GetDataSet(string[][] Param, string SpName, string Type, string constr, bool DebugMode)
{
try
{
OpenChannel();
DataSet ds = client.GetDataSet(Param, SpName, Type, constr, DebugMode);
CloseChannel();
return ds;
}
catch (Exception)
{
scf = null;
return null;
}
}
}
现在我的应用程序已经存在并且关闭服务是一个大问题所以我受到太多实验的限制。 PL建议我是否需要以不同的方式设置参数
答案 0 :(得分:0)
您正在为所有请求使用单个客户端。这可能是导致你出现问题的原因。
您可以做的是为每个请求创建一个新的客户端代理。使用“using”语句创建它以确保正确清理/处理它。
在客户端,首先创建一个代理类:
public class PhoenixDataLayerProxy : ClientBase<IPhoenixDataLayer>, IPhoenixDataLayer
{
public DataSet GetDataSet(string[][] Param, string SpName, string Type, string constr, bool DebugMode)
{
return base.Channel.GetDataSet(string[][] Param, string SpName, string Type, string constr, bool DebugMode);
}
}
然后在using语句中使用代理:
using (PhoenixDataLayerProxy client = new PhoenixDataLayerProxy()
{
var result = client.GetDataSet .....
}
也可能是您达到了最大入站连接的限制。参见: