Hghload сервер на Сях

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by furang, 30 Sep 2011.

  1. furang

    furang Elder - Старейшина

    Joined:
    7 Apr 2007
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    Добрый день.
    Разрабатываю сейчас серверное ПО для одного популярного сервиса. Нужно чтоб сервер держал одновременно много соединений (5-10 тысяч. может больше). Сервер под никсы естественно.
    Написал на асинхронных сокетах. На каждый accept() вызывается pthread_create() . Сервер держит порядка 1000 конектов. При этом мощный проц загружен на 100% и несколько гигов памяти уходит за здрасте. Сейчас уже понимаю что не совсем грамотно совмещать асинхронные сокеты и многопоточность, Но мне говорили, что и на одних асинхронных сокетах сервер не выдержит столько дескрипторов.
    Где-то читал что есть смысл заюзать epoll. Но с ним еще дела не имел.
    Кто имел дело с подобного рода серверами подскажите пожалуйста какие средства (технологии) применить чтоб удержать столько народу и оптимально использовать ресурсы.
    Заранее благодарен.
     
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    1) epoll тебе поможет. довольно просто всё реализовано. примеров много для него
    2) надо ставить limit на кол-во открытых хендлом. потому что по дефолту 1024. т.е. больше 1020 коннектов ты не сможешь принять
    3) по идее создавай столько потоков сколько ядер в системе * 2.
    т.е. если 2 проца по 4 ядра, то это 8 ядер. и значит 16 потоков.
    в этих потоках делай epoll_wait и там уже побыстрому обрабатывай всё.
    4) делай отложенный accept. т.е. опция на сокете - DEFER_ACCEPT тогда меньше нагруженность будет. т.е. accept вернет сокет только после появляения данных на нем. или после истечения таймаута

    Если правильно всё так сделаешь, то проблем не будет (лично проверял что 8 ядерный сервер держал 200к коннектов)

    Вообще для себя выработал такую схему:
    0) запускается поток приема клиентов.
    1) создается сокет
    2) делается DEFER_ACCEPT на 15 секунд.
    3) гоняю в цикле accept
    4) при появлении клиента делаю recv ( MSG_NOSIGNAL | MSG_DONTWAIT)
    если вернет 0 или -1 то закрываю сокет (значит в течении таймаута после коннекта не пришли данные)
    5) если норм считалось то обрабатываю данные или ставлю в очередь для обработки (очередь обслуживают потока по 2 на ядро) это для одиночных команд. Если сложные команды или большие, то выделяю памяти, всё настраиваю, зафигачиваю туда данные, и добавляю сокет в epoll
    6) в epoll жду событий на сокетах. (также многопоточно)

    главное чтобы обработка была быстрой. тогда не надо дополнительных потоков на обработку каждого клиента
     
    #2 slesh, 30 Sep 2011
    Last edited: 30 Sep 2011
    4 people like this.
  3. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Сам сейчас разбираюсь столкнулся с подобной задачей (но в моем случае это клиент), по поводу epoll первая ссылка - где описана типичная архитектура сервера на epoll.

    Примеров кода куча.

    Ну а по поводу выбора языка - может тебе стоит ознакомиться с возможностями Node.js?
     
    _________________________
    3 people like this.
  4. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Когда используешь ассинхронные сокеты, то не нужно для каждого сокета создавать отдельный поток.
     
  5. furang

    furang Elder - Старейшина

    Joined:
    7 Apr 2007
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    Огромное спасибище slesh. Ответ превзошел все мои ожидания более чем полностью. Все описано очень подробно. Подробнее может быть только с сорцами)).Реализую отпишусь. Просто у меня клиенты будут висеть довольно долго. А общение будет хоть и не часто, но инфой, запршиваемой из БД или записываемой туда.
    Насчет node.js идея хорошая. Читал как-то в обзоре что он позволяет одновременно обслуживать огромное количество клиентов не плодя лишних инстансов, но дело в том, что с JS я слабо знаком, да и фреймворк надо осваивать. Но за совет спасибо. Приму к сведению если мой подход окажется недостаточно эффективным.
     
  6. furang

    furang Elder - Старейшина

    Joined:
    7 Apr 2007
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    Да. Знаю. Об этом я написал в первом посте.