Улучшение производительности WCF
От: alex_2371430  
Дата: 17.07.12 09:58
Оценка:
Добрый день! Есть клиент-серверное приложение для передачи торговой информации.Есть две проблемы:
1) Низкая производительность сервиса ( до 1500 колбеков в секунду)
2) Когда один из клиентов начинает зависать(например,проблемы с интернетом) все пользователи начинают медленнее получать данные (до 200 колбеков в секунду)

Server binding:

<netTcpBinding>
<binding name="Net_Tcp_Binding" receiveTimeout="10:00:00" sendTimeout="00:00:30"
maxConnections="100">
<readerQuotas maxArrayLength="2147483647" />
<security mode="None" />
</binding>
</netTcpBinding>


public interface ITradeServiceCallback
{
    [OperationContract(IsOneWay = true)]
    void InstrumentUpdate(InstrumentInfo instrument);

    [OperationContract(IsOneWay = true)]
    void OrderUpdate(OrderInfo order);

    [OperationContract(IsOneWay = true)]
    void OrderFailedUpdate(OrderFailInfo orderFailed);

    [OperationContract(IsOneWay = true)]
    void MyTradeUpdate(MyTradeInfo myTrade);

    [OperationContract(IsOneWay = true)]
    void TradeUpdate(TradeInfo trade);

    [OperationContract(IsOneWay = true)]
    void PortfolioUpdate(DSPortfolioInfo portfolio);

    [OperationContract(IsOneWay = true)]
    void PositionUpdate(PositionInfo position);

    [OperationContract(IsOneWay = true)]
    void MarketDepthUpdate(MarketDepthShortInfo marketDepth);

    [OperationContract(IsOneWay = true)]
    void DisconnectUser();

    [OperationContract(IsOneWay = true)]
    void UserUpdate(UserInfo user);

    [OperationContract(IsOneWay = true)]
    void FileUpdate(FileDataInfo file);

    [OperationContract(IsOneWay = true)]
    void SimulationDataUpdate(SimulationModeData simulationData);

    [OperationContract(IsOneWay = true)]
    void MessageUpdate(MessageId message, params object[] parameters);

    [OperationContract(IsOneWay = true)]
    void EntityUpdate(DataUpdateInfo updateInfo);

    [OperationContract(IsOneWay = true)]
    void Ping();


}


Подскажите,пожалуйста,как можно решить эти проблемы
c# wcf .net
Re: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 10:32
Оценка:
Здравствуйте, alex_2371430, Вы писали:
_>Подскажите,пожалуйста,как можно решить эти проблемы
Никак. Большое количество маленьких сообщений — killing scenario для WCF. Группируй сообщения в пачки и рассылай всем 2-3 раза в секунду — уже станет полегче. С "плохим каналом у одного клиента" из коробки пожалуй ничего не сделаешь — придется ручками реализовывать очередь поставщик-потребитель и писать свой биндинг. И еще наткнешься на ограниченное кол-во одновременно подключенных клиентов — у меня после 2 тысяч одновременных колбеков все становилось совсем плохо и где-то после 4х — все умирало напрочь.
Re[2]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 10:46
Оценка:
Здравствуйте, itslave, Вы писали:

I>Здравствуйте, alex_2371430, Вы писали:

_>>Подскажите,пожалуйста,как можно решить эти проблемы
I>Никак. Большое количество маленьких сообщений — killing scenario для WCF. Группируй сообщения в пачки и рассылай всем 2-3 раза в секунду — уже станет полегче. С "плохим каналом у одного клиента" из коробки пожалуй ничего не сделаешь — придется ручками реализовывать очередь поставщик-потребитель и писать свой биндинг. И еще наткнешься на ограниченное кол-во одновременно подключенных клиентов — у меня после 2 тысяч одновременных колбеков все становилось совсем плохо и где-то после 4х — все умирало напрочь.
Хотя по поводу своего биндинга я погорячился. Достаточно очереди поставщик-потребитель при отправке колбеков.
Re: Улучшение производительности WCF
От: Tom Россия http://www.RSDN.ru
Дата: 17.07.12 12:40
Оценка:
А ты уверен что проблема в WCF? А не в коде который собственно эти колбэки и вызывает? Вызываются они надеюсь не последовательно а паралельно?
Народная мудрось
всем все никому ничего(с).
Re: Улучшение производительности WCF
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 17.07.12 13:44
Оценка:
Здравствуйте, alex_2371430, Вы писали:

Из описания совсем-совсем непонятно, кто кого вызывает и как вообще все устроено.

Сервер все время пушит клиентам данные (через callback-интерфейс)? Если да — то по какому принципу? В бесконечном цикле, так часто, как успеет? Или как?

Или клиент что-то спрашивает, а сервер отвечает?
Re[2]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 14:04
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>А ты уверен что проблема в WCF? А не в коде который собственно эти колбэки и вызывает? Вызываются они надеюсь не последовательно а паралельно?

100% у него последовательно.
Однако распареллеливание "в лоб", через ThreadPool, убьет перфоманс быстрей последовательной отправки
И ет я про оверхед трафика молчу
Re[2]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 14:09
Оценка:
Здравствуйте, scale_tone, Вы писали:

_>Из описания совсем-совсем непонятно, кто кого вызывает и как вообще все устроено.

Судя по именам методов, я догадываюсь про предметную область, а судя по постановке вопроса — про "архитектуру"
_>Сервер все время пушит клиентам данные (через callback-интерфейс)? Если да — то по какому принципу? В бесконечном цикле, так часто, как успеет? Или как?
100% сервер оповещает клиентов, по наступлению некоторого события. Достаточно часто, до 300 раз в секунду.
Re[3]: Улучшение производительности WCF
От: Tom Россия http://www.RSDN.ru
Дата: 17.07.12 14:25
Оценка:
Tom>>А ты уверен что проблема в WCF? А не в коде который собственно эти колбэки и вызывает? Вызываются они надеюсь не последовательно а паралельно?
I>100% у него последовательно.
В этом и проблема

I>Однако распареллеливание "в лоб", через ThreadPool, убьет перфоманс быстрей последовательной отправки

Ты попробуй через таски, там не совсем честный ThreadPool.
Есть ещё очереди откуда таск работающий в потоке ThreadPool-а может брать таски.
Должно работать очень эффективно.
По крайней мере стоит проверить.

I>И ет я про оверхед трафика молчу

А причём тут трафик вообще? Я про последовательный/паралельный вызов колбэков...
Народная мудрось
всем все никому ничего(с).
Re[4]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 14:32
Оценка:
Здравствуйте, Tom, Вы писали:

I>>Однако распареллеливание "в лоб", через ThreadPool, убьет перфоманс быстрей последовательной отправки

Tom>Ты попробуй через таски, там не совсем честный ThreadPool.
Tom>Есть ещё очереди откуда таск работающий в потоке ThreadPool-а может брать таски.
Tom>Должно работать очень эффективно.
Tom>По крайней мере стоит проверить.
А там можно выделить максимальное число потоков на обслуживание тасков? Если да — то тот жы поставщик-потребитель, только в профиль. Если нет — на нагрузках ТС(тысячи подключенных клиентов, которых надо оповестить сотни раз в секунду) оно все равно умрет. Может чуть медленее.

Tom>А причём тут трафик вообще? Я про последовательный/паралельный вызов колбэков...

А ет следующий вопрос, который задаст ТС
Re[2]: Улучшение производительности WCF
От: alex_2371430  
Дата: 17.07.12 14:54
Оценка:
Здравствуйте, scale_tone, Вы писали:

_>Здравствуйте, alex_2371430, Вы писали:


_>Из описания совсем-совсем непонятно, кто кого вызывает и как вообще все устроено.


_>Сервер все время пушит клиентам данные (через callback-интерфейс)? Если да — то по какому принципу? В бесконечном цикле, так часто, как успеет? Или как?


_>Или клиент что-то спрашивает, а сервер отвечает?


Да,сервер рассылает клиентам данные (через callback-интерфейс).
Если упустить подробности:есть BlockingCollection<T> в нее добавляются объекты для отправки,есть 8 Task'ов которые обрабатывают её примерно следующим:
factory.StartNew(() => Sending(DeliveryBuffer));
public void Sending( BlockingCollection<ConvertedEntity> sendBuff)
{
    foreach(var ent in sendBuff.GetConsumingEnumerable() )
    { 
       //send update..
    }
}
Re[3]: Улучшение производительности WCF
От: alex_2371430  
Дата: 17.07.12 15:02
Оценка:
Решение которое мы приняли — отказ от WCF и переход на Socket'ы и ProtoBuff .NET для сериализации.Результат — до 30к апдейтов в секунду.Думаю тема более не актуальна
Re[3]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 15:04
Оценка:
Здравствуйте, alex_2371430, Вы писали:

_>Здравствуйте, scale_tone, Вы писали:


_>>Здравствуйте, alex_2371430, Вы писали:


_>>Из описания совсем-совсем непонятно, кто кого вызывает и как вообще все устроено.


_>>Сервер все время пушит клиентам данные (через callback-интерфейс)? Если да — то по какому принципу? В бесконечном цикле, так часто, как успеет? Или как?


_>>Или клиент что-то спрашивает, а сервер отвечает?


_>Да,сервер рассылает клиентам данные (через callback-интерфейс).

_>Если упустить подробности:есть BlockingCollection<T> в нее добавляются объекты для отправки,есть 8 Task'ов которые обрабатывают её примерно следующим:
_>
_>factory.StartNew(() => Sending(DeliveryBuffer));
_>public void Sending( BlockingCollection<ConvertedEntity> sendBuff)
_>{
_>    foreach(var ent in sendBuff.GetConsumingEnumerable() )
_>    { 
_>       //send update..
_>    }
_>}
_>


Есть подозрение что в foreach у тебя лочится вся коллекция и все потоки дружно ждут, пока один из них не пробежит целый цикл.
Надо отправку одного сообщения одному клиенту выделять в отдельную задачу — тогда будет могопоточность. Но ет имха тебя не сильно спасет. Озвучь требования к количеству одновременно подключенных клиентов и к количеству событий в секунду, о которых надо оповестить клиентов.
Re[4]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 15:09
Оценка: +2
Здравствуйте, alex_2371430, Вы писали:

_>Решение которое мы приняли — отказ от WCF и переход на Socket'ы и ProtoBuff .NET для сериализации.Результат — до 30к апдейтов в секунду.Думаю тема более не актуальна

Самопальные протоколы — это тот еще геморой. Затрахаетесь с "допиливанием" — поддержкой безопасного соединения, масштабируемость и т.д.
Поэтому, я бы рекомендовал
1. Найти низкоуровневую сетевую "сокетную" библиотеку. Они есть.
2. Реализовать на ней высоконагруженную часть, т.е. колбеки.
3. Все остальное оставить на WCF. Потом придется прикручивать секурити, ssl и т.д. — в WCF ет делается просто и легко.
Re[4]: Улучшение производительности WCF
От: alex_2371430  
Дата: 17.07.12 15:11
Оценка:
I>Надо отправку одного сообщения одному клиенту выделять в отдельную задачу — тогда будет могопоточность.

Изначально так было,но отказались от такого варианта — слишком большое количество потоков,производительность была только хуже
Re[5]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 15:14
Оценка:
Здравствуйте, alex_2371430, Вы писали:

I>>Надо отправку одного сообщения одному клиенту выделять в отдельную задачу — тогда будет могопоточность.


_>Изначально так было,но отказались от такого варианта — слишком большое количество потоков,производительность была только хуже

3й раз: очередь поставщик-потребитель, специально для такого придумана...
Re[5]: Улучшение производительности WCF
От: alex_2371430  
Дата: 17.07.12 15:15
Оценка:
Здравствуйте, itslave, Вы писали:

I>Здравствуйте, alex_2371430, Вы писали:


_>>Решение которое мы приняли — отказ от WCF и переход на Socket'ы и ProtoBuff .NET для сериализации.Результат — до 30к апдейтов в секунду.Думаю тема более не актуальна

I>Самопальные протоколы — это тот еще геморой. Затрахаетесь с "допиливанием" — поддержкой безопасного соединения, масштабируемость и т.д.
I>Поэтому, я бы рекомендовал
I>1. Найти низкоуровневую сетевую "сокетную" библиотеку. Они есть.
I>2. Реализовать на ней высоконагруженную часть, т.е. колбеки.
I>3. Все остальное оставить на WCF. Потом придется прикручивать секурити, ssl и т.д. — в WCF ет делается просто и легко.

Примерно так и сделали) Только:
I>1. Найти низкоуровневую сетевую "сокетную" библиотеку. Они есть.
А чем плохие обычные System.Net.Sockets?
I>Самопальные протоколы — это тот еще геморой. Затрахаетесь с "допиливанием" — поддержкой безопасного соединения, масштабируемость и т.д.

ProtoBuf .net — не самопальный протокол,а протокол для сериализации от Google. http://code.google.com/p/protobuf-net/
Re[6]: Улучшение производительности WCF
От: itslave СССР  
Дата: 17.07.12 15:23
Оценка:
Здравствуйте, alex_2371430, Вы писали:
_>А чем плохие обычные System.Net.Sockets?
Тем что прийдется очень многие веще реализовывать вручную. Ту же очередь поставщик-потребитель, поддержку безопасного соединения, хождение через прокси сервера, обработку ошибок, передачу креденшналов, обработку обрывов соединений и многое другое. Другими словами вы построите кучу велосипедов с квадратными колесами, убьете дофига сил и времени, чтобы сделать колеса восьмиугольными и будете жутко гордиться своими достижениями.
_>ProtoBuf .net — не самопальный протокол,а протокол для сериализации от Google. http://code.google.com/p/protobuf-net/
Это я в курсе, мой камент был про использование сокетов. Померяйте оверхед сериализации ProtoBuf, я думаю он не сильно будет больше оверхеда стандартных сериализаторов. Кстате можно ышо и паковать на лету перед отправкой. Но ет уже детали.
В любом случае, если я правильно понимаю предметную область, раздачу котировок "в лоб с одного сервера на 10 000 клиентов" сделать не получится. Ни с сокетами ни с WCF.
Re[4]: Улучшение производительности WCF
От: alex_2371430  
Дата: 17.07.12 18:17
Оценка:
I>Есть подозрение что в foreach у тебя лочится вся коллекция и все потоки дружно ждут, пока один из них не пробежит целый цикл.
Нет,после вызова GetConsumingEnumerable коллекция не лочится.Одновременно несколько потоков пихают в нее данные,и несколько обрабатывают.
Я не думаю что проблема в коде,скорее дело в конфигурации или каких-то хитростях WCF.При локальном подключении (сервер и клиент запущен на одной машине) скорость возрастает в 2-3 раза.
Предметную область ты понял правильно,нужно отдавать маркетдату клиентам, цель — хотя-бы 3-4к апдейтов на всех пользователей.
Re[7]: Улучшение производительности WCF
От: alex_2371430  
Дата: 17.07.12 18:19
Оценка:
Здравствуйте, itslave, Вы писали:

I>Здравствуйте, alex_2371430, Вы писали:

_>>А чем плохие обычные System.Net.Sockets?
I>Тем что прийдется очень многие веще реализовывать вручную. Ту же очередь поставщик-потребитель, поддержку безопасного соединения, хождение через прокси сервера, обработку ошибок, передачу креденшналов, обработку обрывов соединений и многое другое. Другими словами вы построите кучу велосипедов с квадратными колесами, убьете дофига сил и времени, чтобы сделать колеса восьмиугольными и будете жутко гордиться своими достижениями.

Не посоветуешь библиотеку с указанным тобой функционалом?
Re[8]: Улучшение производительности WCF
От: ldarcy  
Дата: 17.07.12 18:40
Оценка:
Здравствуйте, alex_2371430, Вы писали:

_>Не посоветуешь библиотеку с указанным тобой функционалом?


я бы посмотрел на rabbitmq

http://www.rabbitmq.com/blog/2012/04/25/rabbitmq-performance-measurements-part-2/
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.