Горизонтальное масштабирование небольших Web-приложений на Java (вопросы собеседований)

  • Tutorial
Эта тема была поднята в ходе нескольких (3+) собеседований который я прошёл за последние полтора месяца — в разных вариациях но примерно об одном. Казалось бы, известные вещи — но собрав все ответы и объяснения какие я давал (и кое-что что нашёл позже в гугле), решил сохранить их не у себя в гугл-драйве, а написать краткий обзор.

Речь шла о небольших и типовых приложениях Enterprise / Web на Java, каких пишется множество (ну такие, на 10-100 тысяч клиентов, миллион посещений и т.п.). Пусть это будет обобщённый диалог в виде вопросов и ответов.

 

В: Допустим, у вас есть приложение (самое обычное — JSP, Spring, Hibernate например) развернутое на томкате (Apache Tomcat) и вы однажды замечаете что сервер с томкатом загружен на 80% в среднем. Что делать?



О: Поставим несколько томкатов на отдельных серверах в паралель. Они будут по-прежнему использовать одну базу на одном сервере.

 

В: Но как же пользователь будет заходить на ваши несколько серверов?

О: Используем load-balancer, например перед томкатами может стоять апач (Apache httpd) с mod_proxy — он будет распределять (проксировать) запросы приходящие к нему между всеми нашими томкатами.

 

В: Но ведь может получиться что пользователь залогинится на одном томкате, а следующий запрос load-balancer пошлёт на другой, где пользователь не залогинен!

О: Это мы говорим о том как организовать сессию. Например, делаем sticky sessions (например когда load-balancer добавляет к запросу куку с указанием на какой томкат он этот запрос проксирует — а все последующие запросы с этой кукой направляет обязательно на тот же самый сервер. Таким образом каждый отдельный пользователь будет работать только с одним сервером.

 

В: А если этот конкретный сервер упадёт?

О: Сессия пользователя потеряется. Поэтому лучше использовать хранение сессий в кэше. Томкат «из коробки» умеет хранить их в memcached например. То есть мы дописываем строчку в конфиг и на отдельном сервере запускаем memcached — теперь все томкаты хранят сессии на нём и если пользователь попал с очередным запросом на другой сервер, он этого не заметит — сессия будет работать все равно.

 

В: Какие ещё преимущества у кэша для сессий?

О: Например, можно деплоить новую версию приложения только на один из нескольких томкатов, так что скажем 25% пользователей видят новую страницу входа и успеют высказать нам пожелания если им это не нравится, т.е. они невольно поработают бета-тестерами :)

 

В: Но если версии приложения по-разному используют базу?

О: Мы можем проектировать изменения базы так чтобы поддерживать обратную совместимость между двумя соседними версиями. Это нетрудно. Добавлять колонки, например, нужно вместе с новой версией, а вот удалять ненужные только при следующем релизе.

 

В: Хорошо, теперь у нас узким местом становится база. Что мы будем делать при возрастании нагрузки на неё?

О: В первую очередь между базой и томкатами полезно сделать кэш. Ещё раньше вероятно мы используем кэш на уровне ORM (например, второй уровень кеша в Hibernate). Общий смысл в том что в течение сессии пользователь использует ограниченный набор данных, поэтому их удобно кэшировать.

 

В: Ну а всё-таки, допустим даже кэш нас не спасает. Как можно уменьшить нагрузку на базу?

О: У нас есть несколько путей. Например можно часть базы (какую-нибудь особо насосную таблицу допустим) выделить в другую базу на отдельном сервере, может даже в NoSQL хранилище или какой-нибудь специальный кэш. Конечно, лучше это разделение сделать ещё при проектировании :)

 

В: А какие есть другие пути? Какие решения на уровне самой базы данных?

О: Можно использовать шардинг — при этом таблицы разбиваются на несколько серверов и обращение к нужному происходит, например, по части id-шника. В некоторых случаях можно разделить сразу, допустим, сделки, транзакции, электронные документы и т.п. касающиеся одного пользователя поскольку обычно пользователь не работает с чужими документами — а значит все его данные можно удобно хранить на одном сервере.

 

В: Какой недостаток этого подхода?

О: С такими таблицами впоследствии будет сложнее работать — join с таблицей лежащей на нескольких серверах очевидно будет менее эффективен — вообще усложняется индексирование, запросы по критериям и т.п. Вообще само проектирование ощутимо усложняется.

 

В: Хорошо, знаете ли вы ещё варианты?

О: Самый простой это настроить репликацию, например так что база содержит копии на нескольких серверах, из них один используется для записи, а остальные для чтения. Эти последние быстро синхронизируют своё содержимое при апдейтах. Получается что общее количетсво запросов к базе теперь распределяется по нескольким машинам. Конечно это полезно именно когда чтения больше чем записи.

 

В: Какие дальнейшие пути масштабирования вы могли бы предложить?

О: Например, очереди сообщений. Скажем, пользователь сохраняет новую транзакцию — но мы не пишем её в базу сами. Вместо этого отсылаем сообщение в очередь (скажем RabbitMQ) что такие-то данные должны быть сохранены. Это сообщение будет выдано одному из нескольких серверов осуществляющих обработку и сохранение в базу. Наращивать количество таких серверов (при использовании распределённой / реплицированной базы или кеша) вообще очень легко. Однако сама по себе архитектура на таком уровне уже требует больше внимания и размышлений — возможно даже это тот момент когда приложение стоит переписать целиком :)

 

В: Ладно, с этим ясно, давайте поговорим о другом… (и тут могут начать про гарбаж-коллекторы, или попросить написать двоичный поиск в массиве — проверка на вшивость — но это уже не важно)

 

Поделившись своими «наблюдениями» по собеседованиям я буду рад конечно дополнениям, исправлениям и т.п. которые могут оказаться полезными и мне и другим коллегам :)
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 87

    +19
    если бы меня после всего этого попросили написать двоичный поиск в массиве — я бы сразу встал и ушёл, работать с клоунами себе дороже
      +14
      Приходит человек, ему задают уровни EA/Senior, а потом так сразу: «Ну, вообще, нам нужен не какой-то вшивый EA, а джуниор. Напишите-как нам binary search, пожалуйста».

      Болезнь русского ИТ-сообщества.
        0
        ох, как хорошо подмечено!
          –9
          > binary search / двоичный поиск

          Сначала минут 5 пытался вспомнить, что это такое. Не удалось, испугался. Погуглил, и выяснил, что это, оказывается, так теперь называют метод поиска дихотомией.
            +3
            это вопросы уровня Senior? вы смеетесь верно. вот этот расплывчатый раслывчатый набор «load balancing -> шардинг/репликация -> job queueing», если про всю эту абстрактную теорию человек, который вроде как занимается веб-бэкэндом, не читал вообще ничего — он какой-то странный, о чем он вообще думает тогда?..
            +5
            reprog.wordpress.com/2010/04/19/are-you-one-of-the-10-percent/

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

            Если вкратце то вот основные проблемы:

            1. Зацикливание, например если middle присваивать (left + right) / 2 а потом left = middle (при переходе к старшей половине).

            2. Ошибка переполнения при (left + right) / 2 если массив большой

            3. Находит не первый индекс если есть дублирующие элементы.

            Думаю я ещё забыл кое-что :)

            Так что гордо сказать «не хочу работать с клоунами» это мало. Нужно попасть в эти 10% :D
              +4
              и тут вы такой доставляете задачу, которую надо решать сеньёру с помощью самописаного бинарного поиска
                0
                Это проверка на умение не допускать типичных ошибок.
                А не на решение задач. Решение задач, как правило, проверяют испытательным сроком.
                +5
                Попробуйте после полугода architect-работы над чем-нибудь типа scalable entity framework (название просто для понимания проблематики и примерного уровня технологических решений) с ходу без единой компиляции написать, например, примитивнейшую реализацию алгоритма Ли. Со стоящим за спиной весельчаком.

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

                Если человек может вам на пальцах простыми словами, доходчиво, с рисунками и нужной степенью абстрагирования на низком старте рассказать за enterprise scalable web (можно даже не в контексте java-стека), то этого человека, как мне кажется, надо брать на работу, не парясь тем, сможет ли он написать прямо сейчас tier0-задачу или нет.

                Если ему прижмёт, он напишет хороший tier0+.
                Но, как мне кажется, для tier0 можно найти более дешёвых и менее взрослых в профессиональном плане людей.
                  +5
                  вот, об этом я и говорю
                  мой опыт позволяет мне не заниматься написанием самописных реализаций сортировок\поисков\что там ещё реализовано везде где только можно
                  потому, когда я собеседовался несколько лет назад на должность сениора в одной конторе меня послушали, задали вопросы по проектам, а потом стали спрашивать методы класса object и как написать join в sql. После этого я сразу сказал, что работать я тут не буду и просто вышел.
                  во второй конторе у меня спрашивали о проектах, как и что делал, почему именно так, каким образом выбирались пути решения тех или иных задач, были вопросы о проектировании, а не о том, чем отличается интерфейс от абстрактного класса. Вот с ними то я и работаю до сих пор
                    0
                    В персоналиях всё так. И обидно, что люди, не понимая простых вещей, продолжают масштабировать такую модель рекрутинга.

                    Может, это какой-то механизм компенсации, чёрт его не знает.
                    Но так делать не надо.

                    Адекватных людей, которых можно нанять, и так мало.
                      +2
                      были вопросы о проектировании, а не о том, чем отличается интерфейс от абстрактного класса. Вот с ними то я и работаю до сих пор


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

                      Сам я на предложение реализовать двоичный поиск говорю «да-да, я тоже знаю этот подкол», после чего все могут дружно посмеяться и двигаться дальше.

                      мой опыт позволяет мне не заниматься написанием самописных реализаций сортировок\поисков\что
                        0
                        да-да, я тоже в одной такой работал как раз до сих пор — там очень много говорили о проектировании, парадигмах, паттернах и почему-то писали гуанокод и не отличали интеграционных тестов от юнит.

                        это уже другой выверт
                        я, когда шёл работать в эту контору, всё же изучил, чем они занимаются, и где их софт (я не хотел снова повторять свою ошибку и идти в «активно развивающийся» стартап), поговорил с другом, который там работает
                          +2
                          Да… «активно развивающийся стартап» где на коленке изобретают заново десяток уже написанных фреймворков это трэш, согласен стопроцентно :)

                          Как на собеседовании в Яндексе однажды насмешили:

                          Мы разработали за эти четыре года с нуля высоконагруженную распределенную систему для тестирования, снятия метрик, оценок… Здесь используются многие «ноу-хау» созданные сотрудниками… Хм… Короче сейчас мы ищем людей чтобы этот «велосипед» переписать
                      0
                      Странно, но почему-то мне показалось, что когда человек грамотно расписывает на собеседовании «за enterprise scalable web», это отпугивает собеседующих(может я не там их проходил?).

                      Или тимлиды ищут себе людей не выше своего уровня, опасаясь карьерной конкуренции, не знаю…

                      Прошел около 15ти собеседований в Новосибирске, почти везде слушали с открытыми ртами, но «извините, нашли другого»(отшивают стандартно, даже не перевыпуская вакансии на hh-like ресурсах, а одна из компаний после такого «нашли другого», даже умудрилась мне написать письмо с приглашением на собеседование)…

                      В итоге забил на все, перестал умничать, и устроился в мелкую конторку, (в которой мне пришлось выбивать для себя php5.3 вместо 5.2 и git вместо svn)…
                        +2
                        Гадать, почему отпугивает, без понимания вашего бэкграунда и расшифровки собеседований другому человеку нереально.

                        Enterprise scalable web — штука крайне многогранная и линейно зависящая от духа времени.

                        Десять лет назад это был портальный ад с 1000 clients. Сейчас, по сравнению с теми годами, это вполне себе мир rich-content платформ с достаточной степенью интерактивности для отражения задач, которые тогда были desktop-only. Соответственно, и clients поднялись с 1000 до 100000. Это нормально.

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

                        В любом случае, если 15 собеседований закончились мягким отказом, то я бы начал анализировать свои личностные и профессиональные качества на момент собеседования. Ну не умеет монетка при прочих благоприятных условиях падать 15 раз на одну сторону.
                          0
                          Да видимо я не в теме… вот не понимаю, что это у Вас за clients :) Я привык к терминологии connects(одновременные подключения)/rps(запросы в секунду); И что за число 100000? Scalable, он на то и scalable, что предела нет. Сейчас один сервер без проблем может держать миллион соединений… Или clients это показатель ЦА?

                          По поводу личностных качеств ничего не скажу, не мне об этом судить, но там где я работал, никто никогда не жаловался :)
                          По поводу профессиональных, к слову, ни один из ответов этой статьи для меня не является новостью, более того, есть много чего добавить.
                          Также я смог бы ответить на вопрос, что делать, если «вы однажды замечаете что load-balancer загружен на 80% в среднем.» Хотя вообще говоря, об этом нужно думать гораздо раньше, так как система с одним балансировщиком нагрузки в принципе ненадежна.

                          Скорее всего в моем случае все намного проще, рынку нужны «средние» специалисты со «средними» зарплатами… А также опыт работы всего в 2года в моем резюме не вяжется с запрашиваемым уровнем. Но я прошу меньше, чем готова платить моя бывшая компания, в которую я не хочу возвращаться из геополитических соображений.
                            0
                            > Сейчас один сервер без проблем может держать миллион соединений

                            ну немудрено, что вас отшивают повсюду и берут максимум на похапешечки пописывать :)
                              0
                              В нагрузочном тесте для одного сервиса push-нотификаций, значится именно это число, а именно 1e6 одновременных коннектов… На время теста создаются 50 временных инстансов по 20000 соединений… И все(в синтетическом тесте, разумеется) работает хорошо.
                              Что я делаю не так?
                              Другое дело, что в продакшне, порог для автоматического развертывания нового инстанса — 20000 соединений(по умолчанию, легко меняется из админки)…
                              Хотя я релиза так и не увидел, аутсорс такой аутсорс…

                              Не затруднит ли Вас уточнить, почему именно это «немудрено», мне было бы очень полезно понять основания для Вашего мнения…
                            0
                            Ну не умеет монетка при прочих благоприятных условиях падать 15 раз на одну сторону

                            Не хочется подробностей, но умеет
                          0
                          Я, проводя собеседования, неоднократно сталкивался с людьми, которые могли вполне грамотно и красиво рассказать про масштабирование и архитектуру, но при этом оказывались не в состоянии написать простейший код. Я обычно просил написать что-то вроде функции, выдающей N-ое число Фибоначчи ( при этом, естественно, объясняя, что такое числа Фибоначчи), или даже давал пресловутый FizzBuzz. Результаты были удручающими.

                          Я глубоко убеждён в том, что выполнение таких заданий — это проверка на самые основы разработки, на, так сказать, знание алфавита: умение по заданному алгоритму написать код. Если у кандидата этого навыка нет, то брать его нежелательно, поскольку потом с результатами его деятельности будут проблемы.
                            0
                            Вполне логично ожидать от соискателя на вакансию «программист» умения писать код, иногда пример кода, или простое тестовое задание просят сделать до собеседования.

                            Объяснять что такое Фибоначчи действительно естественно?
                            Рекурсивный вариант О(Ф^n) засчитывался как фейл? А O(n)?
                              0
                              Мне, честно говоря, было всё равно, помнит соискатель определение последовательности Фибоначчи или нет, я проверял не это, поэтому, на всякий случай, напоминал.

                              Никакой вариант не засчитывался как фейл, если он давал верный результат.

                              В том-то и ужас… Люди, только что уверенно и напористо рассказывавшие мне про серверную архитектуру, путались в цикле, возвращали массив вместо одного результата, теряли промежуточные значения… Беда.
                                –2
                                Ну я вот не помню, что такое числовой ряд Фибоначчи… ну без интернета, разумеется, не помню.
                                  +1
                                  Меня скорее интересует, как это вообще можно забыть. :-) Особенно имея за спиной высшее техническое образование.
                                    0
                                    Как? Ну в общем-то не сложно. Это не критичная для меня информация. И на практике никогда не пригождалась. Потому и не было стимула запоминать (тем более что именных числовых рядов куда больше, чем один...).
                            0
                            Человек всегда имеет право на ошибку. Заставлять его писать complicated код на собеседовании без возможности промежуточной работы над ошибками (особенно в условиях стресса и наблюдения) — лучший путь к тому, чтобы человека от себя оттолкнуть.

                            Есть более адекватные способы выстроить иерархию «ведущий-ведомый».

                            Вы же понимаете, что разместив статью на хабрахабре создали самомасштабирующийся прецедент? Ведь наверняка найдётся кто-нибудь, кто после достаточно адекватного guided-tour'а из вопросов влепит унижающее junior-bullshit, которое сам (ну, если его поставить в подобную ситуацию) с нуля не напишет.

                            Надеюсь, я смог объяснить, почему не надо делать так.
                              +1
                              без возможности промежуточной работы над ошибками


                              Хм. Когда меня просят на бумажке какой-то код написать я ни в коем случае не готов писать его синтаксически корректно и т.п. Да по-моему этого никто и не ждёт. :)

                              Скорее просто хотят оценить — понимает ли вообще человек что надо писать-то…
                                +1
                                Может я плохо разбираюсь в психологии, но это та самая постфактум-уловка. Можно сказать всё, что угодно про «не ждёт» и «не готов», но на самом деле это не так. Бумага не редактируется, человек ограничен в своей предиктивности, а ошибка ложится на интервьюируемого и интервьюирующего и никуда уже не денется.

                                Вместо этого лучше задайте человеку вопрос за манхэттенское расстояние или окрестность Фон Неймана.
                                Это вам даст гораздо больше информации для размышления (или для рисования на бумаге).

                                А если хочется поиздеваться над человеком в tier0, то вместо бинарного поиска попросите его реализовать сложение двух чисел в двоичном виде на сети Петри. Смысл тот же, кайфа больше.
                                  +1
                                  А вы уверены, что над вами именно издеваются?

                                  Задача на программирование на бумажке — это хороший «тест на вшивость», как и указано в статье. Во-вторых, возможно даже не важно, будет ли код компилироваться или что-то делать правильно. Это источник информации для интервьюера (например, чисто психологически — как соискатель реагирует на критику или на задачу, с которой, возможно, не справится). У интервьюера времени — час. У него нет времени всматриваться в хрупкий, но богатый внутренний мир соискателя. Поэтому важна любая крупица информации.

                                  Если собеседуется программист, то я не понимаю, почему простая задача может его оскорбить.
                                    0
                                    Согласен, я задачи на бумажке или вопросы «скомпилируется ли этот код» расцениваю как «приглашение начать беседу» со стороны интервьюера.
                                      +1
                                      Я уверен, что я никогда не «издевался» над сотрудниками, которых нанимал к себе в проекты.
                                      Мне, например, наплевать на то, что человек выродит на бумажке — мне нужен человек в команду, который сможет там ужиться.

                                      Поверьте, за час вы не узнаете человека. Неважно, бросите ли вы его в джунгли или дадите ему написать на бумажке какую-нибудь задачку, которую он не в состоянии нервотрёпки от собеседования, а в более спокойной обстановке решит за пять минут с нужными вам оптимизациями.

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

                                      Впрочем, поточным компаниям — поточные методы обработки поточных студентов :)
                                        0
                                        В поточке, ага :-)
                                      0
                                      сложение двух чисел в двоичном виде на сети Петри


                                      Чтобы реализовать такое, придется немного подумать :-) Определения все помню, принципы тоже…
                                      Вы имеете в виду многопоточный вариант с заданным числом потоков? :-)
                                        +1
                                        Я имею в виду надругательство над человеком путём постановки ему недостаточно специфицированной задачи, предметная область которой точно не встречалась ему в нормальном продакшене.

                                        Спорим, без чтения специфической литературы с низкого старта на бумажке никто из треда к статье такую задачу не решит?

                                        Вроде и про сети Петри все слышали, и бинарные числа все представляют, а не решит — и всё.
                                        Унижение джуниоров прекращается через унижение сеньоров. :)
                                +1
                                У меня на одном собеседовании была забавная ситуация. Сначала спросили про собственные проекты, которые я указал в резюме — там было два .net-совместимых компилятора и мобильная игра на собственном движке. А потом попросили написать FizzBuzz…
                                  0
                                  Никто не ставит под сомнение ваши профессиональные скиллы, но, как говорится, бумага все стерпит. FizzBuzz сразу выведет недобросовестного претендента на чистую воду, а таких, к сожалению, много (например, любят писать проекты, в которых собеседуемый соучаствовал, но совершенно на второстепенных ролях). А сама задача займет в нормальном случае от силы минуту.
                                  +7
                                  Может мы и клоуны… Но tier0 вопросы задаем всем и всегда. К сожалению уже выросло два поколения EA которые начитались книжек, любят рассуждать про best practices, наслушались семинаров, покатались по всяким тусам и т.д. Эта братия умеет феерично скручивать фреймворки но (внезапно!) плывет в OO дизайне и алгоритмах. Потому как серьезный код не писала никогда. Но понты имеет с избытком. Соответственно дев. команда быстро теряет всякое уважение к такому EA и перестает воспринимать его серьезно. И его приходится увольнять после 2 месяцев работы, несмотря на то, что он говорит в общем правильные вещи. А это $10-15K в трубу. Поэтому наем такого EA не желателен, хотя бы чисто экономически. Отсюда и вопросы tier0 на интервью.
                                  0
                                  Скажите пожалуйста, эта статья про собеседование на какую позицию? Потому что больше похоже на человека, который будет работать архитектором по проектированию таких систем. Потому что обычный junior будет работать только с конкретным узлом ни дальше, ни больше.

                                  Расчитываете ли вы на то, что у человека уже есть опыт работы с похожими распределёнными серверами приложений?
                                    0
                                    Я менял работу с Senior-ской на Senior-скую. Хотя кто-то может сказать что это ближе к Lead-ским вопросам.

                                    Особого опыта с похожими системами у меня не было, но это всё-таки «простейший» если можно так выразиться вариант «распределённости».

                                    Есть более «хардкорные» проекты, где пишут низкоуровневый бэкенд… Там будут много спрашивать про multi-threading и garbage collector например, даже про JVM — даже если позиция middle… А про веб их вообще не интересует.
                                      0
                                      Мне больше всего нравится беседа на тему транзакций БД и JTA в разрезе EJB-контейнера.
                                      Столько всего узнаешь нового.
                                      :-)
                                    +1
                                    честно говоря уже на первый вопрос ответ в корне не верный — Если вы случайно вдруг обнаружили, что tomcat стал есть 80%, то надо разбираться почему он стал их есть,
                                    а не поднимать новые сервера.
                                    Причина в 90% случаев в архитектуре и балансинг тут ничем не поможет.

                                    За знанием названий технологий и их назначения часто скрывается белая пелена их практического применения.
                                    Потому подобные общие вопросы на собеседовании — пальцем в небо.
                                    Лучше спросить меньше но глубже.

                                      +2
                                      Если вы случайно вдруг обнаружили, что tomcat стал есть 80%


                                      Ну не будем горячиться :)

                                      Мы не «случайно вдруг обнаружили». По крайней мере я этот вопрос понимаю скорее так что «мы написали приложение которое сначала юзали 2 тысячи клиентов в день, а через год 20 тысяч клиентов — и нагрузка возросла».

                                      Безусловно если мы просто придя утром обнаружили что всё зависло и упало — это уже вопросы из другой области :D
                                        0
                                        Если «случайно обнаружили», то, стало быть, либо раньше не следили (что печально), либо что-то случилось (и нужно разбираться). Иначе это не случайность, а вполне ожидаемая закономерность, которую можно обнаружить намного раньше достижения этих самых 80%.
                                      +3
                                      Я не знаю Java & Tomcat, по этому мои советы могут показаться глупыми…
                                      1) роль load_balanser хорошо выполняет nginx, он более шустрый, чем аппач и меньше занимает памяти
                                      2) чтоб попадать на одну и ту же WEB морду, достаточно использовать модуль ip-hash
                                      3) храниить сессии можно не только в мемкеше, но и в редисе например. Плюс редиса, например, в том, что если случайно упадет сервер, а ни кто от этого не застрахован, то сессии сохрранятся.
                                      4) я бы на собеседовании задал еще такой вопрос — а что делать — если для сессий не хватает места в мемкеше?
                                      5) про шардинг лучше рассказывать после репликации. В большинстве случаев репликации хватает.
                                      6) рассказывая про шардинг, необходимо пояснить его недостатки.
                                      7) рассказывая про масштабирование необходимо два слова сказать про архитектуру SOA. Тем более, что SOA родилась в недрах JAVA
                                      8) ну, и если все же позиция промежуточноая между сеньёр-помидор и сустем-архитект, то тут как-то вообще куцо с ответами. Если требуется масштабирование, то исходя из поставленных условий сервер не справляется с нагрузкой. Что для этого нужно:
                                      — сделать быстрый фронтэнд сервер с минимальной логикой
                                      — если есть какие-то значительные задержки бэкенда — то можно для опроса использовать аякс, а в это время пользователя развлекать тулбаром (ваша задача решается… осталось 75%)
                                      — часть задач фронтэнда (WEB-морда) должна передать внутренним сервисам (это ближе к SOA).
                                      — как вариант, передачи задач можно использовать специализированные средства: сервера очередей (ActiveMQ, RabbitMR, redis etc) или задач ( zookeeper, Gearman )
                                      — для опроса готовности можно использовать например memcached, не тягая тяжелый Tomcat, а брать информацию напрямую через nginx используя ngx_memcached, я чтоб защитьть прямой доступ к мемкешед от плохих парней — использовать ngx_acces_key
                                      иногда, применяя парочку хорошо-зарекомендовавших себя трюков можно вообще избежать проблемы масштабирования.
                                        0
                                        Советы, думаю, весьма ценны :)

                                        1) про nginx — согласен!
                                        2) ip-hash — если речь про sticky-sessions по IP то ко всем недостаткам sticky-sessions добавляется ещё и проблема захода двух юзеров в одну сессию в некоторых случаях — так ведь?
                                        3) про редис согласен абсолютно! (правда томкат из коробки умеет именно memcache, который становится bottle-neck — надеюсь позже ситуация улучшится)
                                        4) пожалуй добавлю-ка этот вопрос в пост — его ни разу не задали, но имхо он оч важный
                                        5,6) про шардинг — и вообще лучше его не трогать если про него не спросят :)
                                        7) да, я думал было добавить ещё про разделение приложений «по вертикали» на фронт-енд и бэк-енд, но похоже это надо в отдельную статью вообще
                                        8) этот пункт мне вообще оч понравился — было бы неплохо если бы вы его может в маленькую статью хотя бы сделали — кажется, будет много пользы — а то потеряется, жалко! :)
                                          0
                                          2) это с чего вы взяли?
                                          ip-hash — это те же sticky, разве что нигде не нужно хранить на какой сервер мы посылали пользователя, сервер определяется хешем от IP

                                          даже не так, ip-hash вообще не имеет непосредственного отношения к сессиям, он просто гарантирует, что запросы одного и того же клиента будут всегда передаваться на один и тот же сервер.
                                            0
                                            1) про nginx — согласен!
                                            Я как -то столкнулся с ситуацией, что nginx не захотел отдавать картинки при запросе POST.
                                            Была задача генерации картинок сервером.
                                            Так и не понял можно ли это обойти.

                                            Насчет memcached, есть его аналог написанный на ерланге. Он умеет кластерится. ErlyCache. Поддерживает протокол memcached

                                              0
                                              мемкеш тоже умеет кластерится, только на клиенте :)
                                              0
                                              > 8 пункт
                                              кажется когда-то давно где-то писал, но написать еще раз -не проблема %)
                                              только статья получится маленькая :)
                                            0
                                            Ответы хороши, но кое-что устарело лет на 5.
                                            Лучше всего не делать сессию вовсе (только stateless сервисы), но если все же нужно — то делать ее через какой-нибудь распределенный кэш типа Hazelcast — отпадает проблема «а что если упадет memcached».
                                            Для некоторых задач SQL база — излишество.
                                            Можно еще отделять крупные компоненты в отдельные приложения с простым API (например, REST) и проксировать запросы к ним через балансировщик. Тогда при увеличении нагрузки можно быстро добавить именно те компоненты, которые тормозят.
                                              –1
                                              Начать видимо стоит с того, что использование JSP в высоконагруженном сервисе само по себе так себе решение. Я бы смотрел в сторону клиент-сайд логики…
                                                0
                                                Ну почему же, JSP работает быстро. Оно же компилируется в обычный класс.
                                                Другое дело, что это источник ошибок и сложно поддерживать. В общем, не круто :)
                                                  0
                                                  Ну так обычный класс тоже работает медленно :). Всё равно он для каждого клиента выполняет какие-то операции, а значит автоматически нагружает сервер. Я джавист, но считаю, что то, что можно — надо выносить на клиент-сайд. Если не хочится учить JS — можно хотя бы GWT освоить.
                                                    0
                                                    Да, конечно. Но при этом довольно легко нарушить ту хрупкую грань, за которой быстрая и легкая страница превращается в тормозящего монстра.
                                                    Самое ужасное (по моему личному мнению) — single page app.
                                                      0
                                                      Я разрабатываю Single page app. В том числе сложные. И они работают быстро. «Сложные» в моём понимании — это тысячи объектов на странице (не в смысле виджетов, а именно объектов).
                                                        0
                                                        Это было мое личное мнение. В некоторых областях одностраничное приложение незаменимо.
                                                        В некоторых — не сильно удобно. Иногда бесит невозможность открыть в отдельной вкладке.
                                                          0
                                                          Ну это уже как обычно речь по правильно выбранном подходе. Single page app используется тогда, когда могли бы сделать десктоп приложение, но решили сделать не-десктоп. Кстати, на тех же тысячах объектах на странице при тысячах пользователей JSP будет куда как медленнее, думается.
                                                            0
                                                            Соглашусь, что моя фраза про «самое ужасное» была слишком категоричной :)
                                                              0
                                                              Любопытно, что вы-то со мной согласились, а вот кто-то другой по доброте душевной решил комментарий минусануть :).
                                                        –2
                                                        вообще говоря, single page app — это то, к чему сегодня нужно стремиться…
                                                        Ибо не дело это заставлять сервер GUI отрисовывать…
                                                        Клиентский GUI должен строиться на клиенте, а на сервере должны храниться только данные…

                                                        Самый главный профит, который я в этом вижу — возможность одному серверу работать с самыми разными клиентами, от веб и мобильных приложений до десктопных приложений(различные ОСи сюда же)…

                                                        А тормозящим монстром проще сделать как раз таки многостраничное приложение, у нас же весь DOM все время перестраивается при переходах, заново поднимается весь environment…
                                                          +1
                                                          Стремиться следует к удобству и быстроте. Бесит, когда на сайте не могу открыть что-то в новой вкладке. Ну т.е. я к тому, что приложение обязано открываться с любой точки, не нужно заставлять пользователя прокликивать до нужного окошка.
                                                          А как именно это реализовано — дело десятое. Говоря про single page, я имел ввиду именно эту проблему. Не очень понятно выразился изначально.
                                                            0
                                                            Не понимаю, в чем проблема открыть что-то в новой вкладке…

                                                            В приложении обычно есть роутер, только не наружу, а внутри приложения,
                                                            и урлы вроде //example.com/#store/checkout задают необходимый набор состояний…
                                                              0
                                                              Проблема эта встречается часто. Вот пример www.booking.com/hotel/nl/okura.ru.html (отель взял от балды, не реклама)
                                                              Попробуйте открыть карту в новой вкладке.
                                                                +1
                                                                Вообще говоря, согласен с тем, что это жутко неудобно :)
                                                                Сам все время открываю в новой вкладке, а там javascript:void(0);
                                                                К этому не нужно стремиться, да.
                                                              0
                                                              Стремиться следует к удобству и быстроте


                                                              Вот это правильно!
                                                              Только тут дело не в single page или не single page.
                                                              ИМХО, можно и так, и эдак, но если не single page, то лучше REST.
                                                              И POST-запросы лучше AJAX'ом с обновлением контента или redirect'ом, чтобы URL всегда можно было скопировать и потом открыть то же самое, что и было :-)
                                                            0
                                                            В single page app самое трудное — правильно организовать кеширование на клиенте + асинхронно подготавливать DOM немного раньше, чем пользователь выбрал действие. :-) Это, конечно, серьезный технический вызов, но если сразу об этом думать, все вполне получается.
                                                    0
                                                    1. AFAIK, в томкате нет поддержки memcached «из коробки», видимо, речь все же про расширение
                                                    2. IMHO, лучший ответ на код бинарного поиска — Arrays.binarySearch, про сортировку — Arrays.sort, если собеседуемый на пальцах объяснит как оно работает, этого как правило достаточно. Но и задавать этот вопрос, наверно, все же стоит как-то иначе, например, проанализировать кусок кода и предложить оптимизации.
                                                    3. Я провел с полсотни собеседований и наслушался вдоволь «диванных экспертов» по архитектуре. Как уже заметили — лучше копнуть вглубь конкретной темы, чем бежать по поверхности — такие знания можно получить с ресурсов вроде википедии. Пожалуй, неплохая задача — это FizzBuzz на бумаге, один из претендентов (насчет которого появились серьезные сомнения) на системного архитектора java-проекта не смог написать 10 строк синтаксически правильного кода, объяснив это тем, что «idea же пишет за меня код». На этом мы и распрощались. Я лично считаю, что java синтаксически очень ясный и простой язык и в данном случае не требовал 100% компилируемости, но и эта задача оказалась непосильной претенденту. А насчет порядка — сначала архитектура, потом код — тоже объяснимо, т.к. при пессимистичной стратегии проведения собеседований (которые иначе занимают просто массу времени обеих сторон) позволит на более раннем этапе отсечь претендента (если мы говорим про архитектора, конечно). Конечная цель, естественно, не отсечь, но нужно иметь баланс затрачиваемых на процедуру ресурсов. А действительно крутые ребята как правило выкупаются за первые 5 минут, особенно те, с которыми впоследствии еще и приятно работать. А кто гордо встал и ушел не будет остановлен.
                                                      0
                                                      У меня после прочтения возник вопрос. Сперва оговорюсь — это не стёб и не попытка сумничать, это действительно вопрос. Почему в заголовке статьи говорится именно о Java? Сама статья, как по мне, показывает вопросы и ответы на них не специалиста по Java, а администратора либо архитектора. Как по мне все эти решения можно применять и при реализации на других языках. Тот же томкат поддерживает тот же PHP. Я не большой специалист в этом самом Java, поэтому мне интересно — это всё действительно должен знать именно джавист?
                                                        0
                                                        Это вопросы больш подходят к должности синьёр-програмист крупного или очень нагруженного проекта или системный архитектор.
                                                        Если вы специалист по РНР, то эти вопросы вас могут спросить на собеседовании в мамбу или Баду и то, на них зацикливаться не будут.

                                                        если вы не знаете, что такое шардинг — это не значить, что вы плохой программист…
                                                        но если вы не знаете основных недостатков и преимуществ РНР, то увы…
                                                          0
                                                          Ну для PHP свои ведь нюансы — надо как-то с пулом коннектов решать вопросы и т.п. — всего этого я как джава-программист не знаю :)

                                                          Поэтому хотя часть действительно не относится к java — я постеснялся вылезать за рамки своей компетенции…
                                                            0
                                                            Спасибо, коменты прояснили ситуацию. Я и не PHPшник. Просто не сразу осознал что все эти решения делаются на уровне языка. Я был уверен что конект к базе данных — это вопрос системного драйвера и соответственно программа работает с драйвером, а сисадмин или админ БД настраивает этот драйвер на работу с множеством БД. Но картинка с бобром чуть ниже прояснила для меня ситуацию.

                                                            То-есть всё описанное действительно делается прямо в джаве. Видимо и балансировщик и размножение серверов обработки тоже как-то связаны непосредственно с джавой.

                                                            Вы разрушили мой идеальный мир :)
                                                          0
                                                          Базу можно разгрузить с помощью jdbc-middleware типа SEQUOIA
                                                          тогда ни строчки кода не придется переписывать, а нод добавите сколько нужно.
                                                            0
                                                            А вот хрен там было (простите меня за выражение)… Еесли база шардится, то все ваши джоины летят в одно место. А это переписывание ни одной тонны кода.

                                                            А кода без джоинов я практически не видел (за исключением своего конечно ;)
                                                              0
                                                              sequoia — это же про репликацию, не?
                                                                0
                                                                C-JDBC is an open source (LGPL) database cluster middleware that allows any Java application (standalone application, servlet or EJB container, ...) to transparently access a cluster of databases through JDBC(tm). The database is distributed and replicated among several nodes and C-JDBC balances the queries among these nodes. C-JDBC handles node failures and provides support for checkpointing and hot recovery.
                                                                Sequoia is a new version of C-JDBC available under an Apache license. You can download Sequoia from the Continuent.org Forge.

                                                                image

                                                                Ну как-то так

                                                                Типа, меняешь jdbc на ихнии и прога продолжает работать. А сам добавляешь ноды. inserts по всем нодам, селекты по случайной
                                                                  0
                                                                  ну да, репликация, о шардинге речь не идет, стало быть ни к чему негодование по поводу джойнов…
                                                                    0
                                                                    При нагрузке по insert'ам придется серьезно думать. :-)
                                                                    Конечно, не самый типичный случай, но тем не менее.
                                                              +2
                                                              Отвечаю на все эти вопросы без проблем, да еще и сверху добавить могу прилично. Тем не менее, считаю себя intermediate dev в Java. Пора поработать над самооценкой?
                                                                0
                                                                Я тоже считаю себя весьма intermediate — потому что знаю много людей гораздо более опытных и сведущих.

                                                                Тем не менее по ходу собеседований оказывается что это поди ж ты не middle вопросы :)

                                                                Ну мне не жалко — если хотят больше платить — так и ладно.
                                                                  0
                                                                  intermediate, senior…
                                                                  Ребята (и да простите мне это выражение!), это все спор о словах.
                                                                  Вся соль в широте охвата (знать о том, что такое уже есть и где оно есть), в его глубине (знание деталей, тонкостей, частых ошибок и т.д.) и в умении интегрировать эти знания по разным областям.
                                                                  Остальное — либо лирика и разговор ни о чем, либо конкретика.
                                                                0
                                                                Хорошо, что Вы не начали масштабировать с кеширования, хоть слово встречается в статье 9 раз. Этим часто грешат новички, которым невдомек, что кеш это — база данных, еще один компонент архитектуры, усложняющих и удорожающий решение, со своей системой управления, часто нетривиальной и трудно тестируемой. Кеш — всего лишь реализация основополагающего принципа горизонтального масштабирования — «держи обработку данных рядом с данными». Таким образом, хороший кеш либо проектируется сразу как билт-ин база, либо это «последний патрон» архитектуры перед ее сливом. Все посередине есть костыль, иногда модный с бриллиантовым набалдашником, иногда в виде суковатой палки.
                                                                  +1
                                                                  А не могли бы вы подробнее описать как кэш поможет в выборочном тестировании? Мне кажется, что если вы хотите на 25% пользователей протестировать новую версию, вам как раз нужно что-то вроде sticky-sessions, чтобы пользователь однажды зайдя на сервер с новой версией на ней и оставался. А с кэшом сессий пользователь с каждым запросом может попадать на новый сервер.
                                                                    0
                                                                    Кстати косяк, да. Это я явно в помутнении рассудка написал или не то имел в виду.

                                                                    Примечательно что кроме вас никто не заметил а бросились binarySort обсуждать :)
                                                                    +1
                                                                    > В: Допустим, у вас есть приложение (самое обычное — JSP, Spring, Hibernate например) развернутое на томкате (Apache Tomcat) и вы однажды замечаете что сервер с томкатом загружен на 80% в среднем. Что делать?

                                                                    В первую очередь понять, почему мы загружены на 80%. Побенчмаркать цифры на реальном продакшене. А после этого предлагать решения. И кстати не факт, что два томкета будут быстрее. Вдруг проблема в БД. Или даже приложение написано так, что не может быть развернуто на двух томкетах. В общем в первую очередь понять почему, что можно с этим сделать, и сколько это будет стоить (в том числе последствия).

                                                                    > В: Но как же пользователь будет заходить на ваши несколько серверов?

                                                                    Про это надо было сразу сказать, когда описывалась «архитектура с двумя томкетами». Картинку там нарисовать от руки. Странный вопрос.

                                                                    > В: Но ведь может получиться что пользователь залогиниться на одном томкате, а следующий запрос load-balancer пошлёт на другой, где пользователь не залогинен!

                                                                    А собственно почему сразу про липкие сессии? Разве не надо рассказать, что при этом будет для начала? Что сессия живет по умолчанию только на одном томкете. Хотя опять же про это можно сразу рассказать в «архитектура с двумя томкетами». И самое главное, почему вы не говорите про то, что можно не хранить в сессии ничего. А поднимать все сессионные данные из внешнего хранилища (мемкеш или бд какая).

                                                                    > В: А если этот конкретный сервер упадёт?

                                                                    Ну упадет сервер, да и ладно. Но если вы храните в сессии толстые объекты, то не факт что кеш вас спасет. Сериализация не для всех работает из коробки. Вот вы всегда проверяете что объект может быть сериализован, когда пишете приложение? А если это объект из сторонней скомпилированной библиотеки?

                                                                    > В: Какие ещё преимущества у кэша для сессий?

                                                                    А где самый главный вопрос про недостатки? По мне, так преимуществ от кеша сессий почти нет, лишь лишняя сущность для понимания работы системы. И вы точно уверенны, что стратегия бета-тестирования имеет прямое отношение к преимуществам кеша сессий?

                                                                    > В: Хорошо, теперь у нас узким местом становится база. Что мы будем делать при возрастании нагрузки на неё?

                                                                    Почему все время архитектурные решения? Вы боитесь читать код? Вот почему бы не проанализировать построение запросов? Да, кеш хибернейта сделать чуть лучше, но ведь есть еще и фетчи связанных данных (на случай если все лениво инициализированно). Может быть слой хранения мигрировать c hibernate на jdbc? В общем, в первую очередь надо понять какую проблему мы имеем, как ее можно решить, и сколько это будет стоить.

                                                                    > В: А какие есть другие пути? Какие решения на уровне самой базы данных?

                                                                    А как же хранимые процедуры, прекомпиленные вью, временные таблицы, ну или наконец банальные индексы? Почему мы сразу в бой? Ведь расфигачивание БД по разным машинкам это всегда дорого.

                                                                    p/s надо не боятся читать и понимать код, а также иметь представление к чему приведет его выполнение. А все эти шардирования-кеши-ноэскуэли-архитектуры, придуманы маркетоидами, и перед их использование надо хорошо подумать. Раз семь, минимум!
                                                                      –2
                                                                      Почему все время архитектурные решения? Вы боитесь читать код?


                                                                      Может, потому что речь о вопросах собеседований? И если спрашивают о подходах к масштабированию, то отвечать в духе «ваше приложение надо рефакторить» несколько неуместно?

                                                                      Ведь расфигачивание БД по разным машинкам это всегда дорого.


                                                                      А что переписывать слой dao с JPA на JDBC например будет быстрее и дешевле чем репликацию настроить? А хранимые процедуры — их ведь потом ещё поддерживать придётся — пойди найди программистов которым охота этим заниматься. А юнит-тесты вы на них пишете? А как вы потом БД с хранимыми процедурами мигрировать будете?

                                                                      Но впрочем я не собираюсь препятствовать любителям мужественно преодолевать самими собой созданные трудности. :)
                                                                        +1
                                                                        Во первых уместно, надо уметь сказать что иногда подходы к масштабированию не нужны. Во вторых, вы умеете без переписывания кода любое продакшен решение развернуть на двух томкетах с мемкешем сессий? Все равно нужна фаза анализа и подготовки кода.

                                                                        Иногда дешевле, иногда дороже, все зависит от ситуации. А кстати репликацию настраивать не надо? И собирать отвалившиеся не надо, все само работает? Вы правда верите что без приглядывания это всегда будет работать? И вы тчоно уверены, что тот кто нос воротит от эскуэль процедур, нормально пишет java код? Язык имеет настолько большое значение? Юнит тесты прекрасно пишутся, миграция тоже возможна при помоши уже почти стандартных подходов (например в рамках java: flyway, liquibase).

                                                                        И пожалуйста не путайте героическое преодолевание трудностей, с решениями созданными для высокой нагрузки. Я не против двух-томкетов, ноуэскуля, или другой фигни. Но где в вашем опусе мысль, что надо проанализировать ситуацию, прежде чем принимать решения. Тем более если вы претендуете на сеньора, то вы должны не просто предлагать что-то, но объяснять почему вы это предлагает, и чем это грозит.

                                                                    Only users with full accounts can post comments. Log in, please.