Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > Массовая система |
Автор: Platon 8.1.2008, 19:50 |
Здравствуйте, уважаемые. Попробую еще раз поднять свою проблему. Меня интересует как правильно организовать работу серверной сети. К примеру ICQ, как она выдерживает такие огромные нагрузки? Вот мой вариант, смотреть только на первые 5 объектов: клиент, кластер менеджер, кластер сервер, БД http://ipicture.ru/Gallery/Viewfull/190368.html Так вот мне интересно, к примеру я хочу организовать сервис на подобии ICQ, БД, естественно, только в моем владении (неточность картинки, только Кластер-менеджер работает с БД), сервера от сторонних пользователей, как я понимаю допускаются к моему кластер-менеджеру не от балды, а чуть ли не официально подписывая бумаги о непричинении вреда работе сервиса(???) Я так понимаю, сначала идет коннект т кластерменеджеру, он же авторизационный центр, потом приходит сообщение, что пользователь направлен на такой-то сервер. Представим ситуацию: одного пользователя направили на 1 сервер, а другого на другой. И каким образом организуется работа передачи письма от пользователя(отправителя) к пользователю (получатель)? как я понимаю, сначала сервер роется в своих пользователях, нет ли кого, кому предназначается это письмо, если не нашел, запрашивает у кластерменеджера все работающие сервра и начинает спрашивать каждого, нет ли у него такого-то пользователя? если есть, сообщение передается к этому серверу, сервер передает сообщение клиенту, просто ^_^ А если пользователь не в сети? Где должно остаться сообщение? Если все непринятые сообщения перенаправлять кластер-менеджеру, то получится громоздкая работа +_+ для него. Есть вариант: оставлять сообщения на том сервере, с которого отправитель слал письмо. Потом если получатель заходит в сеть, его сервер опрашивает все известные сервера, не оставлял ли кто сообщения этому пользователю? В принципе разряженная система получается, минус такого подхода очевиден, сервер, на котором хранятся непринятые сообщения, может быть отключен от сети, и пользователь сможет получить эти сообщения только когда сервер вновь подключится к сети... И резюмирую в целом по распределенке: каким образом мне защититься в следующем моменте: Сервер общается с серверами чтобы отправить получателю письмо, какие гарантии, что другой сервер не скажет, что этот пользователь у него есть, если его у него на самом деле его нет? - Повторюсь: конечно можно, чуть ли не официально подписывать бумаги о непричинении вреда работе сервиса, но всё-таки, не всегда сработает, думаю... |
Автор: nornad 8.1.2008, 21:02 |
Держать сервера од своим контролем. То есть, не давать чужим серверам возможность работать внутри системы, а предоставлять сервер в пользование. Хотя, в общем-то, можно сделать и несколько иначе. В течение определённого времени следим за новым сервером. Если на него поступают жалобы от пользователей, то разбираемся. Если виноваты - идут лесом, не виноваты - живут дальше. Добавлено через 4 минуты и 31 секунду Можно просто размножить сообщение по всем серверам. Пользователь вошёл в сеть, прочитал сообщения и его сервер (который кластер) разослал остальным, что клиент получил сообщения. |
Автор: Platon 8.1.2008, 23:01 |
888 красивое число. Это ваше предположение? Или общая практика? В принципе весьма логичная схемка. |
Автор: Platon 8.1.2008, 23:16 |
Знаете, наверное это не лучшая практика... я тут прикинул, какая же это каша получится, если всем серверам раздать письма, потом получится чт оу некоторых серверов будет не хватать определенных писем, которые лежат только на другом. И что получается, серверу придется сгребать эту кучу корреспонденции и фильтровать уникальные? что-то я слабо представляю себе такое дело... |
Автор: Platon 8.1.2008, 23:28 | ||
Эх, не озвучил вслух, но мысль такая была. Но выдержит ли сервер такую задачу? Добавлено через 4 минуты и 41 секунду недавно было число зверя ;) |
Автор: nornad 8.1.2008, 23:51 |
А почему не должен? Сомневаюсь, что все разом решат оставить сообщения кому-то, кого нет в системе. А если и решат, то не спасёт уже никакая схема. ![]() Опять же - если нагрузки становятся большими, то делается второй сервер и функции распределяются между ними. |
Автор: Platon 9.1.2008, 09:35 | ||
Речь идет о сторонних пользовательских серверах, которые непредсказуемо вкл/выкл. Я полагаю, есть какой-то костяк всей этой системы: Кластер-менеджер, БД и, как оказалось, сервер приема непрочитаных сообщений, ну, и несколько серверов для первоначальной работы, это всё в штаб-квартире и на замок Об этом и речь. Каким образом должно происходить распределение? |
Автор: nornad 9.1.2008, 11:19 | ||
Ну, не будут же их выключать каждые полчаса, в конце концов. ![]() Например, так. Клиент авторизуется и получает адреса всех вспомогательных серверов (сервер ждущих сообщений, сервера третьих лиц для поиска активных клиентов и т.п.). Если всё на одном сервере - выдаёт клиенту везде свой же адрес, если что-то на другом сервере - его адрес(а). |
Автор: Platon 9.1.2008, 22:06 |
Так, ладно пока пусть будет 1 сервер непринятых сообщений. У меня тут назрели 4 принципиальные схемки работы системы (другие будут копировать друг друга). Прошу оценить, подсказать, что не так? Диаграмма авторизации пользователя http://ipicture.ru/Gallery/Viewfull/299915.html Диаграмма передачи сообщения http://ipicture.ru/Gallery/Viewfull/299923.html http://ipicture.ru/Gallery/Viewfull/299925.html Диаграмма отправки файла http://ipicture.ru/Gallery/Viewfull/304691.html Диаграмма изменения статуса http://ipicture.ru/Gallery/Viewfull/299932.html |
Автор: nornad 9.1.2008, 22:29 |
При передаче сообщения я бы сделал поиск сервера так: Ищем пользователя у себя (это быстро). Если нет - спрашиваем основной сервер (куда пошло сообщение о событии авторизации клиента) о том, на какой сервер он его послал (кстати, и от "подделок" это немного защитит). Таким образом серверу совершенно не обязательно знать, какие кроме него есть сервера. Да, кстати, стоит сделать таблицу клиентов сервера под тип таблиц DNS - и своих там хранить, и чужих туда же пихать на некоторое время (до 15 минут максимум, но лучше на пару минут). При непосредственной отправке сообщение доставлять с сервера не прямо клиенту, а его серверу, который уже и доставит его клиенту. Отправку файла я бы вообще сделал мимо сервера. Пусть клиенты делают между собой туннель - так оно и безопаснее (в плане конфиденциальности), и быстрее. При смене статуса я также изменил бы в сторону унификации. Пусть сервер1 говорит центральному, что его клиент сменил статус. После этого центральный сообщает остальным статус клиента (кому не надо - нет такого клиента в таблице - игнорирует). |
Автор: Platon 9.1.2008, 23:39 | ||||
Боюсь я нагружать основной сервер лишней работой, авторизация то кажется мне весьма массовой, + еще обязательно будут обрабатываться все изменения статусов, анкет и прочей лабуды, не много ли это для 1 сервера? Хотя выглядит куда правильней и безопасней, остается видимо только один вопрос: не многовато ли?*
Совсем не понял как это и к чему?
каламбур какой-то после того что описано выше передача будт следующего вида: клиент1 -> сервер1 -> кластер-менеджер(!)* -> сервер2 -> клиент2 * и тут(!) я понял что можно разделить полномочия: логин-сервера(авторизация) и кластер-менеджера(маршрутизация между клиентами) никак не получится!!! ведь клиенту1 надо знать IP клиента2, а он будет передаваться только в том случае, если клиент2 нажмет на кнопку принять файл. да, согласен. Добавлено через 11 минут и 53 секунды Пришла мысль по упрощению системы: Получается в штабквартире в локальную сеть можно объединить всего 3 разновидности серверов: кластер-сервер и БД (1 .. N), серверы-работники. Мы видим, что тут отсутствует логин-сервер и сервер непринятых сообщений, я подумал, что если нагрузка будет действительно большой, таблицы можно разделить между несколькими СУБД на разных машинах, к примеру СУБД на авторизацию, СУБД на непрочитанные сообщения и прочее. Как на такое смотрите? |
Автор: nornad 10.1.2008, 00:28 | ||||
По сравнению с тем, что ему уже приходится делать в твоей схеме - не много. Информация о том, на какой сервер отправлен клиент, занимает мало места. Получить её - недолго. Кроме того, запросы будут идти всё же не каждый раз - часть запросов отбреет сервер, найдя клиента у себя в кеше. Не смешивай схему получения адреса сервера/клиента и непосредственно передачи. Я тебе это уже давно предложил ![]() Парой строк выше ![]() Добавлено через 8 минут и 46 секунд
Смотри. Клиентов сервера надо где-то хранить, так? Так. Хранить их лучше либо в бд, либо в файле. Я бы выбрал бд - удобнее, да и при большом количестве - быстрее.
P.S. "Вот что крест животворящий делает" (царь Иоан I (с) "Иван Васильевич меняет профессию) ![]() ![]() |
Автор: nornad 10.1.2008, 01:32 | ||
Ну так по нажатию кнопки принятия не приём начинать, а устанавливать туннель и передавать файл. Всё равно пока клиент2 не нажмёт кнопку, файл ему доставлять не стоит (иначе он сильно разозлится и будет кидаться в нас тапочками). |
Автор: Platon 10.1.2008, 09:26 |
А разве по диаграмме у меня не так?! |
Автор: nornad 10.1.2008, 11:08 |
По диаграмме клиенты постоянно работают через серверы, так что не так. |
Автор: Platon 10.1.2008, 12:42 | ||
nornad, ха! а как тогда узнать IP получателя? причем политика системы такова, что отправитель может узнать IP получателя только с его согласия, и как вы предлагаете образовывать какой-то там туннелинг, если не знаете IP? Добавлено через 47 секунд И к тому же семая нижняя стрелочка между двумя клиентами - это и есть туннелинг между пользователями. Добавлено через 11 минут и 40 секунд
ее легко вычленить из моей схемы сервер1 -> кластер-менеджер -> сервер2 уух, прям глаза загораются, можно же сделать елочку ^_^ подробности в новых схемах |
Автор: Platon 10.1.2008, 13:15 |
http://ipicture.ru/Gallery/Viewfull/302608.html |
Автор: Platon 10.1.2008, 14:14 |
При чем ПолуКластерМенеджер реализует функциональность КластерМенеджера и Сервера одновременно. Т.е. серверу нет разницы к кому он коннектится: к истинному кластер-менеджеру, или сурогату. ПолуКластерМенеджер владеет только частью северов, это позволит распределить нагрузку кластер-менеджера. |
Автор: Maksym 10.1.2008, 14:25 | ||
Масштабно. |
Автор: Platon 10.1.2008, 14:33 |
Maksym, ну, на самом деле, я видел подобную схему по предмету ОС, ассоциативная память. Более того, мне кажется, по этой схеме работает сеть Интернет. |
Автор: nornad 10.1.2008, 15:39 | ||||
Ррррррррррррр ![]() Клиент1 жмёт кнопку "послать" (файл, а не клиента ![]()
Вычленить легко, если знаешь, что искать и вычленять. Из трёхколёсного велосипеда тоже можно вычленить двухколёсный, но на нём неудобно ездить, да и не всякий сразу догадается, что автор имел в виду двухколёсный вариант, когда рисовал эскиз с тремя колёсами. ![]() Угу, особенно если добавить ещё пару уровней - ЧетвертьКластерМенеджер и ТриЧетвертиКластерМенеджер. ![]() |
Автор: Platon 10.1.2008, 15:54 | ||||
Рррррррррррр, еще больще А я уже какой пост о чем втираю? У меня на диаграмме всё это описано. и мне непонятно
Философски ![]()
На это и расчитано, вложенность сурогатных кластер-менеджеров будет любая. Вот наглядное изображение: http://ipicture.ru/Gallery/Viewfull/303349.html |
Автор: nornad 10.1.2008, 16:11 | ||
Ну, не вижу я этого на диаграмме. Извините, раз уж не умею читать диаграммы. ![]() Ррр ![]()
Да это-то понятно. Я так, прикалывался. ![]() |
Автор: Platon 10.1.2008, 16:14 |
Я так полагаю первый этап проектировки системы закончен? Пришли к общему мнению по всем вопросам. Теперь Диаграммы классов и следований для каждого из участников коммуникации? |
Автор: Platon 11.1.2008, 13:52 |
Это фантастика какая-то, получается, что на уровне серверов нужно реализовать только 2 принципиально разные схемы (подразумеваю функции) взаимодействия: передачи протокольного сообщения и оповещения о изменении какого-либо статуса!!! Добавлено @ 14:07 Приватное сообщение http://ipicture.ru/Gallery/Viewfull/308554.html Сообщение-уведомление http://ipicture.ru/Gallery/Viewfull/308120.html |
Автор: Platon 11.1.2008, 14:11 |
Я так полагаю, на основе этой систеиы могут работать несколько систем с разными протоколами. Получается, что тут образуется некая платформа для любого разного вида протоколов. Единственое условие в префиксе сообщения должен быть тип сообщения (приватное, уведомление), если оно приватное, то за ним сразу серийный номер получателя. Дальше идет бинарный протокол любого вида. Единственный минус что клиенты к примеру Протокола1 не смогут взаимодействовать с клиентами Протокола2, но тут конечно можно с бубном поплясать и на уровне сервера сделать конвертацию в нужный протокол, если протокол известен системе. Сервер может догадаться с какими протоколами ему надо будет работать из авторизационной информации. Всё, ваши предложения и замечания ^_^ nornad, так как ты единственный мой дельный собеседник, к тебе и обращаюсь ^_^ |
Автор: Platon 11.1.2008, 15:06 |
Черт подери!!! Серверу по сути не надо искать пользователя!!! Тепрь я понимаю силу проектирования, если бы я стал сразу кодить, то система бы получилась бы совсем ущербная. |
Автор: nornad 11.1.2008, 15:11 | ||
Ну, почему же не смогут? Если сервер между ними возьмёт на себя функции шлюза - запросто. И никаких плясок с бубном не потребуется. В итоге все протоколы передачи служат именно для передачи и нужно лишь создать на основе одного сообщения другое (в другом протоколе). Для этого при желании можно даже собственный "системный" конвертер накалякать, который будет учитывать особенности твоей системы (чтобы быстрее искать, кому доставить и т.п.). И поставлять этот конвертер третьим сторонам, которые держат свои сервера. |
Автор: Platon 11.1.2008, 15:27 | ||
Вот эта мысль не ясна. У меня в принципе нет никакого протокола, сторонние разработчики смогут сделать всё, что захотят, игры One-On-One, IM, голосовую штуку, и прочее. конвертировать эти вещи 1 в другое сложно и нет смысла. Добавлено через 2 минуты и 45 секунд Моя текущая задача заключается в том, чтобы разыскать пользователей онлайн. Правда появляется проблема того, что пользователю могут приходить голосовые сообщения, когда он сам не имеет такой возможности, клиент не поддерживает такое. Добавлено через 6 минут и 6 секунд мда, я что-то уже перегибаю палочку... это тупиковая ветка. Добавлено через 13 минут и 59 секунд это заставляет поменять протокол отправки приватного сообщения, добавляется флажек, оставлять сообщение на сервере или нет. К примеру , если пользователь отправил запрос на принятие файла, то его не нужно сохранять в БД, а обычные сообщения надо оставить в БД. ЗЫ: можно куда-нибудь поприватней нас переправить, чтоб не весь инет видел, что мы тут обсуждаем... |
Автор: Platon 11.1.2008, 16:18 |
Пришла мысль по упрощению схемы авторизации пользователя. В принципе, почти тоже самое, но теперь нет passKey, уже легче работать. Более того, в этой схеме, если пользователь знает, к какому серверу ему выгодно подключиться, то он необязательно будет подключаться к главнейшему серверу ^_^ http://ipicture.ru/Gallery/Viewfull/308923.html |
Автор: nornad 11.1.2008, 16:35 | ||
Здрасте. А как тогда передаются сообщения и узнаётся статус пользователей? Откуда вообще сервер будет знать о других серверах и о том, пользователи как сущности вообще существуют? Для чего вообще авторизационный сервер, если нет протокола и никто не может обратится к серверу (потому что не знает, как)? Что-то я тебя не пойму - то нет протокола, то его придётся уже поменять... ![]()
Да вока, вроде, ничего секретного. |
Автор: Platon 11.1.2008, 17:12 | ||
Имею ввиду, что сторонний разработчик в части протокольного сообщения волен писать всё, что захочет. Протокол текущей системы заключается в слудующих несложных базовых операциях: - авторизация - отправка сообщения - сообщение оповещения всех в контакт листе - манипулирование контакт листом (добавление, удаление) - уровень видимости Извиняюсь, что туго излагаю мысли. А пользовательский протокол имею ввиду к примеру: сообщение пользователю обволакивает пользовательский протокол (игры, голос, просто сообщения). |
Автор: Platon 12.1.2008, 16:22 |
Должен признать, всё-таки непринятые сообщения лучше хранить на серверах, но не на главном. |
Автор: nornad 12.1.2008, 17:41 |
Почему? |
Автор: Platon 12.1.2008, 17:58 |
Наверно, ты прав, это не в стиле сервера включаться-выключаться каждые 30 минут, если сервак нестабилен, кикаем его из системы, ты всё это всё уже предлагал. Я так сказать, принял к сведению, а теперь должен признать что так будет лучше, нагрузка на систему получится распределенной. |
Автор: Platon 13.1.2008, 00:59 |
Я тут накидал диаграмму классов сервера. Жиденько, не спорю, руки пока не доходят почитать нужные книжки, сегодня закачаю, почитаю, а пока представляю вашему вниманию текущую версию. http://ipicture.ru/Gallery/Viewfull/319111.html |
Автор: Platon 13.1.2008, 12:00 |
Так, еще весьма интересный вопрос встал... При взаимодействии серверов должен ли обмен данными быть синхронным? В диаграмме видно, что авторизация проходит асинхронно, это конечно хорошо, не надо ждать. Теперь представим ситуацию отправка сообщения. сервер не нашел у себя получателя, обращается к главному серверу с просьбой доставить сообщение. (Супер-сервер содержит много серверов) он должен опросить сервера, у кого находится получатель? И вот тут проблема, как лучше сделать синхронно или асинхронно? Синхронно: + не надо делать лишних сообщений, + легче реализовать, прозрачность действий - итоговое ожидание получения ответа ниже, чем при асинхронном, что является, наверно, самым главным фактором |
Автор: v2v 13.1.2008, 12:10 |
господа вы же протокол XMPP обсуждаете. xmpp.org/rfcs - открываем, читаем - всё уже придумали до нас). |
Автор: batigoal 13.1.2008, 12:14 |
Platon, я не очень понимаю твой UML. Connection действительно является частью User и вне его существовать не может? И вообще, у тебя тут столь массово встречается отношение агрегации... Это необычно. Пунктирная линия с треугольной стрелкой, насколько я помню, означает реализацию интерфейса. Но у тебя в неё явно вложен какой-то иной смысл. |
Автор: Platon 13.1.2008, 12:18 | ||||||
v2v, на самом деле я не спорю, что эта идея не новая, и что ее уже реализовали. Но мне хочется попробовать свои силы в проектировании сетевой распределенной системы, так что намеренно не лезу гуглить, Прокачиваю свой моск. А то за нас и так всё сделали, моск вообще в отключке, а таким образом хоть размышляем... поможет при нетривиальной проблеме. Добавлено через 2 минуты и 44 секунды
На сколько я понят ты про стрелку которая идет от AuthManager к User? Это стрелочка инстанцирования. Добавлено через 4 минуты и 13 секунд
Ну, на самом деле может. Connection существует и без User, но потом прикрепляется к нему. Добавлено через 6 минут и 48 секунд
Хм, извиняюсь, я слабоват в UML, а какие связи должны быть? Чувствую, что система сильно связная, но легче придумать не могу. |
Автор: nornad 13.1.2008, 13:32 |
Ну вот, не дадут человеку велосипед изобрести. ![]() |
Автор: Platon 13.1.2008, 13:35 |
nornad, кратко, лаконично, а главное в точку ![]() |
Автор: batigoal 13.1.2008, 13:40 | ||
Тогда это не агрегация, а обычная ассоциация, на мой взгляд. Со стереотипом uses, который обычно не указывается.
Нет, я про ту, которая, например, идёт от MinaConnection к Connection. А та стрелка, которую ты назвал "инстанцированием" по стандарту называется "зависимость" ![]() Это тема для обширной дискуссии, желательно - устной. Предлагаю сейчас в неё не вдаваться, потому что это скорее вопрос к изучению UML, чем к твоей системе. А обычно на схемах самый популярный вид связи - это обычная ассоциация, сплошная линия. |
Автор: Platon 13.1.2008, 13:41 |
Более того я хочу пройти весь процесс разработки ПО. От проектирования до реализации |
Автор: batigoal 13.1.2008, 13:42 |
По поводу сильной связности: её, конечно, следут избегать, но это не самоцель. Желательно исключить циклы (их у тебя вроде нет) и, по возможности, альтернативные пути (которые наличествуют). |
Автор: Platon 13.1.2008, 13:51 |
как раз над ними думал, я в принципе, могу весь функционал перенести в медиатор, и схема намного упрощается: http://ipicture.ru/Gallery/Viewfull/319862.html |
Автор: Platon 13.1.2008, 14:25 | ||
Вот основная диаграмма главного сервера: http://ipicture.ru/Gallery/Viewfull/319847.html Чего то мои сообщения не добавляются, придется редактировать сообщение...
Всё таки я не могу понять в чем тут иной смысл? выдишь, я специально отметил их другим цветом, говоря, что это мой план разработки, если я хоть что-то понимаю в шаблонах, то это паттерн Мост, т.е. у меня могут поддерживаться несколько реализаций: как с использованием Apache Mina, используя голые сокеты, или работа непосредственно с NIO. |
Автор: Platon 13.1.2008, 14:42 |
да, но, не стоит буквально в диаграмме воспринимать Bridge как паттерн, просто это сетевая связка. |
Автор: batigoal 13.1.2008, 15:02 |
Ну например, у тебя сейчас написано, что MinaSuperManagerHandler реализует интерфейс SuperManagerHandler (который даже и не интерфейс). Значит, этой стрелкой ты хотел сказать что-то другое. К слову, абстрактные методы пишутся на схемах курсивом, а статические - подчеркиваются, Together это всё умеет. http://www.flickr.com/photos/15961621@N00/2188714879/ Засим предлагаю курс UML'а свернуть ![]() |
Автор: Platon 13.1.2008, 15:17 |
![]() Вот кстати, я понял что можно еще упростить схемку. Всё равно сервер будет компоноваться в строителе, так, что исходя из этого я понял, что можно обойтись и без интерфейсов: http://ipicture.ru/Gallery/Viewfull/320155.html |
Автор: Platon 13.1.2008, 17:35 |
А вот диаграммка клиента, получилась более интересной чем остальные. http://ipicture.ru/Gallery/Viewfull/320973.html |
Автор: Platon 13.1.2008, 18:57 |
Ну, раз ни у кого нет нареканий по диаграммам классов то время браться за реализацию всего. |
Автор: Platon 24.1.2008, 13:19 |
Если кому-то еще интересна судьба моего "велосипеда", то рад сообщить, что разработка на беседах не закончилась, и к концу недели будет готова альфа версия. |
Автор: Platon 27.1.2008, 00:28 |
Как я и обещал, к концу недели сделал. Желающие потестировать обращайтесь в тему, в ПМ, кину исходники. |