WCF DAL для ORACLE: более 150 пользователей - PullRequest
1 голос
/ 25 июня 2009

Я пытаюсь создать DAL для Oracle с использованием WCF. Мое приложение находится в интрасети, поэтому я решил использовать привязку tcp, которая должна быть самой быстрой. Мое требование простое. Мой DAL выставляет функцию, которая возвращает набор данных на основе запроса / sp. Первоначально мы использовали веб-сервис, и все было хорошо, кроме проблем с тайм-аутом. Некоторые из запросов SP занимают более 2 часов, и WCF работает плавно ... без таймаутов, если вы установили параметр right:)

Проблема возникла, когда мы запустили ее в эфир, и более 150 пользователей получили к ней доступ одновременно. Я исследовал и обнаружил, что я не закрывал прокси. Так что я сделал это, и сценарий улучшился, но производительность по-прежнему составляет всего 50% от веб-сервиса, и в то время пользователь вообще не может подключиться.

Теперь много статей и предложений, которые я прошел, и наиболее типичный ответ - от ваших требований зависит, как установить параметры (их так много ... :().

Кто-нибудь, пожалуйста, помогите мне с предложением, учитывая мои конкретные требования. Длинные звонки составляют всего 10% (те, которые потребляют 2-3 часа).

Мой сервис размещен в оконном сервисе. Пожалуйста, посмотрите следующие строки:

Пространство имен Феникс { частичный класс 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();
        }
    }
}

}

Я использую фабрику каналов на клиенте. Пожалуйста, найдите код ниже:

с использованием Системы; using System.Collections.Generic; использование System.Linq; используя System.Text; используя Феникс; using System.ServiceModel; используя System.Data; используя CustomEnum; пространство имен KIPLProject { открытый класс PhoenixDataServerProxy { статическая 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;
        }
    }

} * * тысяча двадцать-один

Теперь Мое приложение уже работает, и отключение службы является большой проблемой, поэтому я ограничен слишком большим количеством экспериментов. PLs предлагают, если мне нужно установить параметры по-другому

1 Ответ

0 голосов
/ 25 июня 2009

Вы используете один клиент для всех запросов. Это может быть причиной проблем.

Что вы можете сделать, это создать новый клиентский прокси для каждого запроса. Создайте его с помощью оператора «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 .....
}

Может также случиться так, что вы превысите ограничение на максимальное количество входящих подключений. См:

http://blogs.msdn.com/drnick/archive/2006/03/10/547568.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...