Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

высоконагруженный сервер

5.4K
04 марта 2010 года
cursor
114 / / 05.01.2008
Здравствуйте.
У меня теоретический вопрос. Заранее спасибо тем, кто поймет меня и поможет советом.
Мне интересны высоконагруженные системы клиент-сервер. Для повышения своих знаний хочу разобрать такую вещь как мессенджеры (к примеру маил агент, icq).
Реализовал следующее. (кода под рукой нет, напишу вперемешку с русским)

Серверная часть создает поток, который сокеты всех клиентов, переведенные в неблокирующий режим, опрашивает на наличие данных.
 
Код:
DWORD WINAPI loop_recv_proc(LPVOID) {
    client = head->next;
    while(1) {
        client = client->next;
        recv(client->client_s..............);
    }
}

Потом биндит свой серверный сокет и ждет accept (выделено жирным).
Код:
DWORD WINAPI auth_proc(LPVOID my_struct) {
    прием логина_пароля от клиента;
    поиск пользователя в базе ? my_class->AddClient(my_struct->client_s,..........);
    выход;
}

int main() {
    CreateThread(........, &loop_recv_proc, &my_class.........);
    while(1) {
        client_s = accept(accept_s, ........);
        Client_Struct *my_struct = new Client_Struct();
        my_struct->client_s = &client_s;
        CreateThread(......., &auth_proc, &my_struct........);
    }
}

Сокеты всех подключенных клиентов добавляются в связанную структуру, в которой есть указатели Prev и Next.
metka_na_budushee: Если клиент с id=1 передает сообщение клиенту с id=2, то осуществляется поиск по всем связанным структурам в поисках клиента с id=2 и на этот сокет передается сообщение.
Все работает, все отлично.
Думаю при увеличении клиентов запускать еще один процесс loop_recv_proc, чтобы циклы по сокетам пробегались быстрее.

Но, если клиентов станет еще больше, чем может обслужить один сервер, тогда допустим ставим еще одну машину.
Как тогда осуществить то, что в metke_na_budushee? Как найти по id сокет того, кто обслуживается на другом сервере (может их не один, а два или три) и передать ему сообщение?
Может я изначально неправильно строю систему?
Искал в интернете информацию - ничего такого не нашел...
Видимо правильнее будет, если будет сервер А, который принимает клиента на accept, авторизует его, передает ему ip самого наименее загруженного сервера (Б, В, Г, ....) и запоминает в БД кого и кому передал.
При обработке клиента в случае получении сообщения, обслуживающий сервер делает запрос в базу сервера А, узнает на каком сервере обслуживается клиент с id=2 и передает демону того сервера сообщение...
Но мне кажется что вариант с БД - это слишком медленно получится

Эту ситуацию можно как-то грамотнее реализовать?
602
04 марта 2010 года
KPI Student
265 / / 16.12.2006
Я думаю, можно один из серверов сделать "master", остальные - "slave". Если запускается мастер - он просто запускается. Если запускается слейв, то он шлет сообщение мастеру о том, что он запустился и работает себе дальше.

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

При этом любой сервер при возникновении ситуации, когда один аккаунт пишет другому, ищет этот аккаунт у себя, если не находит - дергает другой сервер.
3
04 марта 2010 года
Green
4.8K / / 20.01.2000
Цитата: cursor

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


Зачем?
Используй асинхронные сокеты. Их не надо опрашивать, они сами тебе скажут, когда данные будут готовы.

Цитата: cursor

 
Код:
while(1) {
        client_s = accept(accept_s, ........);
        Client_Struct *my_struct = new Client_Struct();
        my_struct->client_s = &client_s;
        CreateThread(......., &auth_proc, &my_struct........);
    }
}


У тебя сколько соединений столько и потоков?! Ужос...
Используй порты завершения.

Цитата: cursor

Сокеты всех подключенных клиентов добавляются в связанную структуру, в которой есть указатели Prev и Next.


list ? Зачем?
Используй map.

Цитата: cursor

Думаю при увеличении клиентов запускать еще один процесс loop_recv_proc, чтобы циклы по сокетам пробегались быстрее.


Этого вообще не надо.

5.4K
05 марта 2010 года
cursor
114 / / 05.01.2008
Цитата: Green
Зачем?
Используй асинхронные сокеты. Их не надо опрашивать, они сами тебе скажут, когда данные будут готовы.
У тебя сколько соединений столько и потоков?! Ужос...
Используй порты завершения.


Я вроде их и использую.. Это которые переводишь в ioctl?
Один отдельный поток. Он в цикле проверяет все сокеты по очереди на прием.

5.4K
05 марта 2010 года
cursor
114 / / 05.01.2008


Во, то что нужно. Спасибо

3
05 марта 2010 года
Green
4.8K / / 20.01.2000
Цитата: cursor
Я вроде их и использую.. Это которые переводишь в ioctl?
Один отдельный поток. Он в цикле проверяет все сокеты по очереди на прием.


Нет.
асихронные != неблокирующие

Про ассинхронные смотри ф-ции WSA...
Про порты завершения тебе оксотник уже дал ссылочку.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог