Як створити високомасштабні веб-сервіси на Java?


15

Я створюю деякі веб-сервіси, які б мали 2000 одночасних користувачів. Послуги пропонуються безкоштовно і, отже, очікується, що вони отримають велику базу користувачів. В майбутньому може знадобитися масштабування до 50 000 користувачів.

Є вже кілька інших питань, які стосуються такої проблеми, як - /programming/2567254/building-highly-scalable-web-services

Однак мої вимоги відрізняються від вищезазначеного питання.

Наприклад - у моєї програми немає інтерфейсу користувача, тому зображення, CSS, JavaScript не є проблемою. Це на Java, тому такі пропозиції, як використання HipHop для перекладу PHP на рідний код, марні.

Тому я вирішив задати своє питання окремо.

Це налаштування мого проекту -

  1. Веб-сервіси на основі відпочинку за допомогою Apache CXF
  2. Hibernate 3.0 (з відповідними оптимізаціями, такими як ледача завантаження та спеціальний HQL для налаштування)
  3. Tomcat 6.0
  4. MySql 5.5

Яких найкращих практик слід дотримуватися, щоб зробити додаток на базі Java масштабуваним?


Якщо ви відкриваєте послугу REST, використання зворотного проксі-сервера, такого як Varnish, дуже допоможе. Наскільки свіжі повинні бути дані? Ви впевнені, що вам потрібна реляційна база даних? Не могли б ви розділити дані? Завдяки стеку технологій, який ви описуєте, я б зосередився на тому, щоб якомога менше запитів дійсно потрапляло на вашу кінцеву точку. Чи задумалися ви робити це на пам'ять такими рішеннями, як Hazel cast / Gigaspaces тощо?
ebaxt

@ebaxt дякую за ваші пропозиції. Gigaspaces, здається, є відкритим джерелом. Але Hazel лиття виглядає цікаво.
Кшиті Шарма

1
@ebaxt "Ви впевнені, що вам потрібна реляційна база даних?" Прийняття nosql призведе до кардинальних змін у архітектурі додатків. Ми намагаємося мінімізувати складність. Вартість, хоча для нас не є фактором. Тож ми будемо дотримуватися реляційного підходу.
Kshitiz Sharma

1
Ви можете використовувати Postgres, MySQL або що завгодно. Що з вашою інфраструктурою? Чи можете ви використовувати дискові масиви? Чи розміщені сервери в одному місці? Чи можете ви з'єднати кластер із серцебиттям тощо? Чи можете ви розмістити їх у одній підмережі?
edze

1
Я теж програміст. Але якщо ваша реляційна база даних є вузьким місцем, ви, як правило, з цим питанням. На ринку є бази даних, деякі в деяких ситуаціях працюють краще, ніж інші. Але вони використовують різні рівні ізоляції транзакцій та оптимістичну
конкурентоспроможність

Відповіді:


8

Я займався цим питанням у минулому, але все ще вважаю, що мені є чому навчитися на місцях. Я вважаю, що це одне з найцікавіших сфер у розробці програмного забезпечення в даний час, ось деякі думки з цього приводу:
MySQL є достатньо справедливою базою даних, якщо ви не працюєте з величезно великою кількістю даних, і в цьому випадку ви можете розглянути NoSQL База даних, але слід уважно вивчити, яка найкраща база даних NoSQL для ваших потреб.

Ви повинні впровадити кешування у вашій системі - спробуйте кешувати якомога більше даних, доступних лише для читання, або визначити деякі стратегії кешування - наприклад, у нас був сценарій, коли користувач дійсно бачив "старі дані" як доки останнє оновлення відбулося за останню годину.
Я б розглядав кеш-пам'ять JBoss або, можливо, Infinispan (що більше нагадує розподілену структуру даних) або іншу популярну рамку кешування для цього.
Крім того, як ви вже згадували tomcat, я припускаю, що ви працюєте в якомусь модулі-відповіді на запит. Спробуйте розглянути можливість використання кешу, який існує в області заданого запиту, це може бути навіть звичайний HashMap, який пов'язаний з локальним сховищем потоку .
Моя ідея тут дуже нагадує кеш першого рівня в Hibernate .

Ви повинні пам’ятати, що файли, транзакції та інші ресурси є дорогими з точки зору збереження їх відкритими. Переконайтеся, що ви закриєте файли та транзакції якнайшвидше, або у вас з’являться помилки, які відтворюватимуться у великих масштабах

Крім того, ви повинні зрозуміти, що 2000 одночасних користувачів - це означає, що 2000 користувачів отримують доступ до вашого сервера відразу, або вони використовують вашу систему? Розрізняють випадки, коли 2000 користувачів намагаються відкрити сокет на вашому сервері, і випадок, коли лише 500 є, а 1500 зараз переглядають результати заповнення вводу на стороні клієнта. може покращити речі, оскільки більшість доступ була доступна лише для читання. Поміркуйте, якщо є можливість кешування та перевірки на стороні клієнта, спробуйте зберегти дзвінки на сервер та надсилати лише відмінності даних, якщо більшість ваших відповідей на запит із тим самим параметром не зміниться.

Вам слід подумати про використання кластеризації - вам доведеться вирішувати такі питання, як балансування навантаження , липкий сеанс (а це означає, що балансир завантаження перенаправить запит на той же сервер на той же сеанс) та інше.

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


Наприклад, у проекті з відкритим кодом oVirt ми просимо отримати статистику даної віртуальної машини. деякі дані VM рідко змінюються, тому ми надсилаємо лише MD5 з них, якщо дані змінюють також значення MD5, ми змінюємо запит на отримання повних даних, а не тільки MD5.

Раніше я згадував сплячку - я б рекомендував вас уважно розглянути можливість її використання - якщо вам потрібно виконувати багато записів і менше читати, сплячий режим може бути не ідеальним для вас, і вам слід розглянути можливість роботи з Spring-JDBC як обгортки JDBC.

Індексуйте свою базу даних розумно та використовуйте правильну схему db. Розглянемо можливість використання шару збережених процедур, оскільки вони є попередньо складеними та оптимізованими,

я хотів би зазначити, що в минулому я мав справу з системою (один вузол) на mysql (в основному доступ лише для читання) з jboss 4.2.1 і мені вдалося досягти 2000 одночасних користувачів
(не отримуючи доступ одразу з точки зору відкриття 2000 сокетів проти нашого сервера), але використовуючи / переглядаючи нашу систему, використовуючи кеш JBoss і попередньо завантажуючи в кеш деякі найдоступніші дані або дані, які ми зрозуміли, будуть "гарячими і популярними "але наше рішення було гарним для нашої архітектури та наших потоків,
тому, як я кажу в цих випадках, -
є більше підказок і прийомів, але це дійсно залежить від вашої архітектури та те, які потоки потрібно мати у вашій системі. Удачі!


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

3

Гарне питання. Напевно, важко сказати, який найкращий підхід, але спробую з мого досвіду.

Найкращий спосіб масштабувати веб-додаток на базі Java - написати його якомога більше без громадянства (якщо можна). Це дозволяє горизонтально масштабувати додаток, куди ви можете додавати сервери tomcat, якщо є більше одночасних користувачів.

Однак, як ви зазначали, з підключеннями до бази даних можуть виникнути проблеми. Але питання, яке у мене є, як ви отримуєте дані? Це генерується користувачем або ви отримуєте дані від третьої сторони? Це дуже важливо, тому що, якщо ви надаєте послугу своєму користувачеві з даними, зведеними з додатку третьої сторони (скажімо, FB, Twitter тощо), то, що ви можете слідувати, - це написати в основну базу даних і копіювати дані на підлеглі бази даних які виділяються кожному екземпляру томатів. Тоді кожен сервер tomcat може отримати з власної бази даних рабовласників.

 Are there faster alternatives to Mysql?

Ви можете перейти до кластера MySQL, який має сховище даних в пам'яті. Але остерігайтеся того, що програма може потребувати деяких змін. Thesql joins не підтримуються в кластері MySQL, хоча в останній версії є покращення для того ж. Якщо вартість не є фактором, то можна спробувати Oracle.

Рішення кешування однозначно підвищить продуктивність. Але тоді все залежить від архітектури всього додатка. Ви повинні добре знати, коли висувати дані в кеш, коли забруднити їх (видалити з кеша).

Що стосується розподілу навантаження в середовищі з декількома серверами, я б запропонував вам використовувати балансир навантаження, ніж використовувати Apache для балансування навантаження.


"Я б запропонував вам використовувати балансир навантаження, ніж використовувати Apache для балансування навантаження". Який підхід / програмне забезпечення ви б запропонували, як не Apache?
Kshitiz Sharma

Я в основному рекомендував апаратне забезпечення балансування завантаження, яке повинен налаштувати ваш мережевий адміністратор. Це, звичайно, має додаткові витрати на проект. Цей балансир завантаження матиме свій власний IP (також його називають віртуальним IP), і в основному ви будете призначати цей IP для вашого домену. Коли запит надходить, це спрямовуватиме його до всього підключеного сервера в круговому режимі (також інші алгоритми, доступні). Ви можете використовувати apache для цієї мети, якщо обладнання не є варіантом, але я вважаю за краще апаратне обладнання, оскільки вам не потрібно налаштовувати apache лише для цієї мети.

Ми використовуємо виділений сервер з httpd, щоб зробити те саме. Обладнання - це не проблема.
Kshitiz Sharma

Ви можете використовувати httpd та mod_cluster, якщо я правильно пам’ятаю. Я б уважно подумав, перш ніж перейти до рішення "overkill" апаратного LB, перед тим, як перевірити httpd та mod_cluster

@zaske - Ви, напевно, маєте рацію, що балансир завантаження обладнання, можливо, перевитрата. Але якщо вам потрібно розширити масштаб, це легко зробити, додавши більше серверів.

2

Зараз я налаштовую подібну систему (на професійному рівні), і ось такий дизайн я вибрав:

  • Два балансири вантажу Nginx (обидва активні, обидва відмовні для іншого, збалансовані з круглої роботою DNS)
  • Дві бази даних MySQL в режимі майстер-реплікації
  • Два екземпляри Tomcat як кластер tomcat
  • Два екземпляри Memcached і для кешування, і для спільного використання сеансу для кластера Tomcat

Це дозволить досягти надмірного, високої доступності, масштабованого рішення.

Балансири навантаження (на пристойному обладнання) легко завантажують насичений 1 гбітовий рядок кожен. Це також чудове місце для розвантаження SSL.

Ви можете зберегти інформацію про сеанс у пам'яті. У випадку відмови екземпляра tomcat інший екземпляр tomcat може отримати відповідну інформацію про сеанс, і клієнти нічого не помітять. Не забувайте поєднувати це і з липкими сеансами. (Щоб зменшити мережевий трафік)

Кластеризація Tomcat також має можливість ділитися інформацією про сеанси між кластером у режимі реального часу, не використовуючи запам’ятовується. Хоча я думаю, що ефективність розумна, використання Memcached буде кращим.

Якщо вам потрібно більше енергії в будь-якому з цих додатків:

  • Nginx: Додайте більше балансирів, хоча я не думаю, що це буде вузьким місцем дуже скоро.
  • Tomcat: ви можете легко збільшити розмір кластера Tomcat або додати більше кластерів
  • Mysql: Додайте кілька невільників для читання або збільште розмір кластера (залежно від вашої програми, але оскільки ви написали додаток на основі REST, це не повинно бути проблемою)
  • Memcached: Додайте більше вузлів, Memcached ваги досить добре я вважаю.

Я не знаю, як будується ваше додаток і які великі вивіски для ресурсів, але якщо ви бачите велике завантаження бази даних (під час ваших навантажень!), Додавання кешу між програмою та базою даних, безумовно, може значно підвищити продуктивність. Але не забувайте, що не все є кешованим, якщо запити завжди різні, кешування не допоможе (сильно)

Моєю порадою буде завантажити VMware Workbench (або програмне забезпечення для віртуалізації similair) і спробувати створити просту настройку. Ніякого балансування навантаження або кластеризації, лише основи та робота звідти. Один за одним додайте більше функцій (балансування, кешування, кластеризація тощо) та переконайтесь, що провести деякі дослідження з кожної теми, щоб ви знали, що зробили правильний вибір.

Якщо ви продовжуєте виконувати ті ж тести на ефективність під час цього процесу, ви можете переконатися, чи використовувати X краще, ніж використовувати Y у ваших налаштуваннях, або яке кешування впливом матиме тощо.

Зрештою, така настройка дійсно залежить від вимог вашої програми та її клієнтів, все можна зробити різними способами, кожен має свої сильні та слабкі сторони.

Є ще запитання?

Удачі!

Веслі


фундук? hazelcast.com
NimChimpsky

Ви використовуєте рамку для шару кешування, або просто купу ручних хешей для запитів SQL?
djechlin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.