Я создаю несколько веб-служб, которые будут иметь 2000 одновременных пользователей. Услуги предлагаются бесплатно и, следовательно, ожидается, что они получат большую базу пользователей. В будущем может потребоваться масштабирование до 50 000 пользователей.
Уже есть несколько других вопросов, касающихся этой проблемы, например: /programming/2567254/building-highly-scalable-web-services
Однако мои требования отличаются от вопроса выше.
Например - мое приложение не имеет пользовательского интерфейса, поэтому изображения, CSS, javascript не являются проблемой. Это на Java, поэтому такие предложения, как использование HipHop для перевода PHP в нативный код, бесполезны.
Поэтому я решил задать свой вопрос отдельно.
Это мой проект настройки -
- Веб-сервисы, основанные на отдыхе, использующие Apache CXF
- Hibernate 3.0 (с соответствующими оптимизациями, такими как отложенная загрузка и настраиваемый HQL для настройки)
- Tomcat 6.0
- MySql 5.5
Каковы наилучшие практики, чтобы сделать масштабируемое приложение на Java?
источник
Ответы:
Я занимался этой проблемой в прошлом, но все же чувствую, что мне есть чему поучиться на поле. Я считаю, что это одна из самых интересных областей, которые существуют в настоящее время в разработке программного обеспечения, вот некоторые соображения по этому поводу:
MySQL является достаточно справедливой базой данных, если вы не работаете с огромным объемом данных, и в этом случае вы можете рассмотреть NoSQL базы данных, но вы должны тщательно изучить, какая база данных NoSQL лучше всего подходит для ваших нужд.
Вы должны внедрить кеширование в своей системе - попытаться кешировать как можно больше данных только для чтения или определить некоторые стратегии кеширования - например, у нас был сценарий, в котором для пользователя было бы допустимо видеть «старые данные» как пока последнее обновление имело место в последний час.
Я хотел бы рассмотреть JBoss Cache, или, возможно, Infinispan (который больше похож на распределенную структуру данных) или другую популярную инфраструктуру кэширования для этого.
Кроме того, как вы упомянули tomcat, я предполагаю, что вы работаете в каком-то модуле запроса-ответа. Попробуйте рассмотреть возможность использования кэша, который существует в области данного запроса, это может быть даже простой HashMap, связанный с локальным хранилищем потока .
Моя идея здесь очень напоминает кеш первого уровня в Hibernate .
Вы должны помнить, что файлы, транзакции и другие ресурсы стоят дорого с точки зрения их сохранения. Убедитесь, что вы закрываете файлы и транзакции как можно скорее, иначе у вас появятся ошибки, которые будут воспроизводиться при крупномасштабных настройках
Кроме того, вы должны понимать, что 2000 одновременно работающих пользователей - означает ли это, что 2000 пользователей одновременно получают доступ к вашему серверу, или они используют вашу систему? Различают случаи, когда 2000 пользователей пытаются открыть сокет для вашего сервера, и случаи, когда только 500 и 1500 в настоящее время рассматривают результаты заполнения ввода на стороне клиента.
Вы должны рассмотреть возможность использования кластеризации - вам придется иметь дело с такими проблемами, как балансировка нагрузки , зависание сеанса (что означает, что балансировщик нагрузки перенаправит запрос на тот же сервер для того же сеанса) и многое другое.
Если вам нужен код синхронизации - тщательно выбирайте стратегию синхронизации. Я видел некоторые системы, в которых использовалась простая блокировка, но ReaderWriterLockмогло бы улучшить положение вещей, так как большая часть доступа была доступна только для чтения.
Рассмотрите возможность кэширования и проверки на стороне клиента, если это возможно, попробуйте сохранить вызовы на сервере и отправлять только различия данных, если большая часть вашего ответа на запрос с тем же параметром не изменится.
Например, в проекте с открытым исходным кодом oVirt мы запрашиваем статистику данной виртуальной машины. некоторые данные виртуальной машины редко изменяются, поэтому мы отправляем только MD5, если данные изменяются, значение MD5 также изменяется, мы выполняем запрос для получения полных данных, а не только MD5.
Я уже упоминал о спящем режиме - я бы порекомендовал вам тщательно рассмотреть возможность его использования - если вам нужно выполнять много записей и меньше чтений, Hibernate может не подойти вам, и вам следует подумать, возможно, работа с Spring-JDBC в качестве оболочки над JDBC.
Мудро индексируйте свою базу данных и используйте правильную схему БД. Подумайте об использовании слоя хранимых процедур, так как они предварительно скомпилированы и оптимизированы.
Я хотел бы заявить, что в прошлом я имел дело с системой (один узел) на mysql (в основном доступ только для чтения) с jboss 4.2.1 и смог достичь 2000 одновременных пользователи
(не получая доступ сразу с точки зрения открытия 2000 сокетов на нашем сервере), но используя / просматривая нашу систему, используя JBoss Cache и предварительно загружая в кеш некоторые наиболее часто используемые данные, или данные, которые мы поняли, будут «горячими и популярными» «но наше решение было хорошо для нашей архитектуры и наших потоков,
поэтому, как я уже говорил в этих случаях, -
есть еще советы и рекомендации, но они действительно зависят от вашей архитектуры и от того, какие потоки вам нужны в вашей системе». Удачи!
источник
Хороший вопрос. Наверное, сложно сказать, какой подход лучше, но попробую по своему опыту.
Лучший способ масштабировать веб-приложение на основе Java - это написать его как можно без состояний (если вы можете). Это позволяет вам масштабировать приложение по горизонтали, где вы можете добавить серверы tomcat, если есть больше одновременно работающих пользователей.
Однако, как вы заметили, могут быть проблемы с соединениями с базой данных. Но у меня вопрос, как вы получаете данные? Это пользовательский или вы получаете данные от третьих лиц? Это очень важно, потому что, если вы предоставляете сервис своему пользователю с данными, агрегированными из стороннего приложения (например, FB, Twitter и т. Д.), То вы можете выполнить запись в основную базу данных и реплицировать данные в подчиненные базы данных. которые выделяются каждому экземпляру tomcat. Тогда каждый tomcat-сервер может получить из своей собственной подчиненной базы данных.
Вы можете перейти на кластер MySQL, который имеет хранилище данных в памяти. Но остерегайтесь того факта, что приложению могут потребоваться некоторые изменения. Они
sql joins
плохо поддерживаются в кластере MySQL, хотя в последней версии есть улучшения для этого. Если стоимость не является фактором, то вы можете попробовать Oracle.Решение для кэширования определенно улучшит производительность. Но тогда все зависит от архитектуры всего приложения. Вы должны хорошо знать, когда помещать данные в кеш, когда делать их грязными (удалять из кеша).
Что касается распределения нагрузки в многосерверной среде, я бы предложил вам использовать балансировщик нагрузки, а не Apache для балансировки нагрузки.
источник
В настоящее время я настраиваю подобную систему (на профессиональном уровне), и вот дизайн, который я выбрал:
Это позволит создать избыточное масштабируемое решение с высокой доступностью.
Балансировщики нагрузки (на приличном оборудовании) легко загружают насыщенную линию 1 Гбит каждая. Это также отличное место для разгрузки SSL.
Вы можете сохранить информацию о сеансе в memcached. В случае сбоя экземпляра tomcat другой экземпляр tomcat может получить соответствующую информацию о сеансе, и клиенты ничего не заметят. Не забудьте сочетать это с липкими сессиями тоже. (Чтобы снизить сетевой трафик)
В кластерах Tomcat также есть возможность обмениваться информацией о сеансах между кластерами в режиме реального времени без использования memcached. Хотя я думаю, что с точки зрения производительности лучше использовать Memcached.
Если вам нужно больше энергии в любом из этих приложений:
Я не знаю, как строится ваше приложение и каковы большие проблемы с ресурсами, но если вы видите высокую нагрузку на базу данных (во время ваших нагрузочных тестов!), Добавление кеша между приложением и базой данных, безусловно, может значительно повысить производительность. Но не забывайте, что не все кэшируется, если ваши запросы всегда разные, кэширование не поможет (сильно)
Мой совет - скачать VMware Workbench (или программное обеспечение для виртуализации similair) и попытаться создать простую установку. Нет балансировки нагрузки или кластеризации, только основы и работа оттуда. Один за другим добавьте больше функций (балансировка, кэширование, кластеризация и т. Д.) И обязательно проведите некоторые исследования по каждой теме, чтобы вы знали, что сделали правильный выбор.
Если вы продолжаете выполнять одни и те же тесты производительности в течение этого процесса, вы можете сами убедиться, что использование X лучше, чем использование Y в вашей установке, или какое влияние окажет кэширование и т. Д.
В конце концов, такая настройка действительно зависит от требований вашего приложения и его клиентов, все может быть сделано различными способами, каждый со своими сильными и слабыми сторонами.
Есть еще вопросы?
Удачи!
Wesley
источник