Java'da yüksek düzeyde ölçeklenebilir web hizmetleri nasıl tasarlanır?


15

2000 eşzamanlı kullanıcısı olacak bazı Web Hizmetleri oluşturuyorum. Hizmetler ücretsiz olarak sunulmaktadır ve bu nedenle geniş bir kullanıcı tabanına sahip olması beklenmektedir. Gelecekte 50.000 kullanıcıya kadar ölçeklendirilmesi gerekebilir.

Sorunu ele alan başka sorular da var - /programming/2567254/building-highly-scalable-web-services

Ancak gereksinimlerim yukarıdaki sorudan farklı.

Örneğin - Uygulamamın bir kullanıcı arayüzü yok, bu yüzden görüntüler, CSS, javascript bir sorun değil. Java'da yani PHP'yi yerel koda çevirmek için HipHop kullanma gibi öneriler işe yaramaz.

Bu yüzden sorumu ayrıca sormaya karar verdim.

Bu benim proje kurulumum -

  1. Apache CXF kullanarak dinlenme tabanlı Web hizmetleri
  2. Hibernate 3.0 (Tembel yükleme ve ayarlama için özel HQL gibi ilgili optimizasyonlarla)
  3. Tomcat 6.0
  4. MySql 5.5

Java tabanlı bir uygulamayı ölçeklenebilir hale getirmek için uyulması gereken en iyi uygulamalar nelerdir?


Bir REST hizmeti sunuyorsanız, Vernik gibi bir ters proxy kullanmak çok yardımcı olacaktır. Verilerin ne kadar taze olması gerekir? İlişkisel bir veritabanına ihtiyacınız olduğundan emin misiniz? Verileri bölümlere ayırabilir misiniz? Tanımladığınız teknoloji yığını ile, mümkün olduğunca az isteğin gerçekten uç noktanıza ulaştığından emin olmaya odaklanacağım. Hazel Memory / Gigaspaces vb. Çözümlerle bu bellek içi yapmayı düşündünüz mü?
ebaxt

@ ebaxt önerileriniz için teşekkürler. Gigaspaces açık kaynak gibi görünüyor. Ama Hazel oyuncuları ilginç görünüyor.
Kshitiz Sharma

1
@ebaxt "İlişkisel bir veritabanına ihtiyacınız olduğundan emin misiniz?" Nosql'i benimsemek, uygulama mimarisinde önemli değişikliklere neden olacaktır. Karmaşıklığı minimumda tutmaya çalışıyoruz. Maliyet bizim için bir faktör değildir. Bu yüzden ilişkisel yaklaşıma bağlı kalacağız.
Kshitiz Sharma

1
Postgres, MySQL veya daha fazlasını kullanabilirsiniz. Altyapınız ne olacak? Disk dizileri kullanabilir misiniz? Sunucular aynı konumda mı barındırılıyor? Kümenizi kalp atışı vb. İle bağlayabilir misiniz? Onları aynı alt ağa koyabilir misiniz?
edze

1
Ben de bir programcıyım. Ancak ilişkisel veritabanınız darboğaz ise, bu sorulara yöneleceksiniz. Pazarda bazı durumlarda diğerlerinden daha iyi performans gösteren veritabanları vardır. Ancak farklı varsayılan İşlem İzolasyon Seviyeleri ve İyimser Eşzamanlılık vs Kötümser Eşzamanlılık vb.
Kullanıyorlar

Yanıtlar:


8

Bu konuyu geçmişte ele aldım, ancak yine de sahada öğrenecek çok şeyim olduğunu hissediyorum. Bunu, günümüzde yazılım geliştirmede en ilginç alanlardan biri olarak görüyorum, işte bununla ilgili bazı düşünceler:
MySQL, çok büyük miktarda veri ile çalışmadığınız sürece yeterince adil bir veritabanıdır ve bu durumda NoSQL'i düşünebilirsiniz. veritabanı, ancak dikkatle için en NoSQL veritabanı ne incelemek gerekir sizin ihtiyaçlarınız.

Sisteminizde önbelleğe almayı uygulamalısınız - olabildiğince fazla salt okunur veri önbelleğe almayı deneyin veya bazı önbellek stratejileri tanımlayın - örneğin, bir kullanıcının "eski verileri" şu şekilde görmesinin geçerli olduğu bir senaryomuz vardı son güncelleme son bir saat içinde yapıldığı sürece.
Ben JBoss Cache, ya da belki Infinispan (daha dağıtılmış bir veri yapısı gibi) ya da bunun için diğer popüler önbellek çerçevesi düşünün .
Buna ek olarak, tomcat'ten bahsettiğiniz gibi, talep edilen bazı modüllerde çalıştığınızı varsayıyorum. Belirli bir istek kapsamında bulunan bir önbellek kullanmayı düşünmeye çalışın, iş parçacığı yerel depolamasıyla ilişkili basit bir HashMap bile olabilir .
Buradaki fikrim , Hazırda Bekletme'deki ilk düzey önbelleğe çok benziyor .

Dosyaları, işlemleri ve diğer kaynakları açık tutmak açısından pahalı olduğunu unutmamalısınız. Dosyaları ve işlemleri mümkün olan en kısa sürede kapattığınızdan emin olun, aksi takdirde büyük ölçekli kurulumlarda çoğaltılacak hatalarla karşılaşırsınız

Buna ek olarak, aynı anda hangi 2000 kullanıcının olduğunu anlamalısınız - bu, 2000 kullanıcının sunucunuza aynı anda eriştiği anlamına mı geliyor yoksa sisteminizi mi kullanıyor? 2000 kullanıcının sunucunuza bir soket açmaya çalıştığı durumlar ile istemci tarafında girdilerin doldurulmasının yalnızca 500'ün ve 1500'ün şu anda sonuçlara baktığı bir durum arasında ayrım yapın.

Kümelemeyi kullanmayı düşünmelisiniz - yük dengeleme , yapışkan oturum (yük dengeleyici, aynı oturum için bir isteği aynı sunucuya yönlendirecektir) ve daha fazlası gibi sorunlarla uğraşmanız gerekir.

Senkronizasyon koduna ihtiyacınız varsa - senkronizasyon stratejisini dikkatlice seçin. Basit bir kilidin kullanıldığı bazı sistemleri gördüm, ancak ReaderWriterLockçoğu erişim salt okunur olduğu için bazı şeyleri geliştirebilirdi.

Mümkünse istemci tarafında önbellekleme ve doğrulama yapmayı düşünün, aramaları sunucuya kaydetmeyi deneyin ve aynı parametreye sahip bir istek için yanıtınızın çoğunun değişmemesi durumunda yalnızca veri farklılıkları göndermeyi deneyin.
Örneğin, oVirt açık kaynak projesinde, belirli bir sanal makinenin istatistiklerini almayı talep ediyoruz. VM'nin bazı verileri nadiren değişir, bu yüzden sadece MD5'i göndeririz, veriler MD5 değerini de değiştirirse, sadece MD5'i değil, tüm verileri almak için bir istek yaparız.

Daha önce hazırda bekletme modundan bahsetmiştim - dikkatlice kullanmayı düşünmenizi öneririm - çok sayıda yazma ve daha az okuma yapmanız gerekiyorsa, Hazırda Bekletme sizin için ideal olmayabilir ve belki de bir sarmalayıcı olarak Spring-JDBC ile çalışmayı düşünmelisiniz . JDBC.

Veritabanınızı akıllıca endeksleyin ve doğru bir db şeması kullanın. Önceden derlenmiş ve optimize edilmiş olarak bir saklı yordamlar katmanı kullanmayı düşünün

Geçmişte, mysql (çoğunlukla salt okunur erişim) üzerinde bir sistem (tek düğüm) ile uğraştığımı ve 2000 eşzamanlı olarak ulaştığımı belirtmek isterim kullanıcılar
(sunucumuza karşı 2000 soketin açılması açısından bir kerede erişmemek), ancak sistemimizi kullanmak / taramak, JBoss Cache kullanarak ve en çok erişilen verilerin bazılarının önbelleğe yüklenmesi veya gerçekleştirdiğimiz veriler "sıcak ve popüler olacak" "ama çözümümüz mimarimiz ve akışlarımız için iyi oldu,
bu yüzden söylediğim gibi -
Daha fazla ipucu ve püf noktası var, ama gerçekten mimarinize ve sisteminizde hangi akışlara ihtiyacınız var. İyi şanslar!


Saklanan procs dışında katılıyorum, saklanan procs kullanmayın. Ve threadsafe yapmak için eşzamanlı bir hashmap ve atomik değerler kullanabilirsiniz
NimChimpsky

3

İyi soru. Muhtemelen hangisinin en iyi yaklaşım olduğunu söylemek zor, ama deneyimlerimden deneyeceğim.

Java tabanlı web uygulamasını ölçeklendirmenin en iyi yolu, uygulamayı olabildiğince vatansız yazmaktır (mümkünse). Bu, uygulamayı eşzamanlı kullanıcı varsa tomcat sunucuları ekleyebileceğiniz yatay olarak ölçeklendirmenize olanak tanır.

Ancak, belirttiğiniz gibi, veritabanı bağlantılarında bir sorun olabilir. Ama sorum şu: Verileri nasıl elde ediyorsunuz? Kullanıcı oluşturulmuş veya verileri üçüncü taraflardan mı alıyorsunuz? Bu çok önemlidir, çünkü üçüncü taraf uygulamasından (FB, Twitter vb. bunlar her tomcat örneğine tahsis edilir. Sonra her tomcat sunucusu kendi bağımlı veritabanından alabilir.

 Are there faster alternatives to Mysql?

Bellek içi veri deposuna sahip MySQL kümesine gidebilirsiniz. Ancak uygulamanın bazı değişikliklere ihtiyacı olabileceğine dikkat edin. sql joinsSon sürümde aynı yönelik iyileştirmeler olmasına rağmen iyi MySQL kümede desteklenmez. Maliyet bir faktör değilse, Oracle'ı deneyebilirsiniz.

Önbellek çözümü kesinlikle performansı artıracaktır. Ama sonra, tüm uygulama mimarisine bağlıdır. Verileri önbelleğe ne zaman iteceğiniz, ne zaman kirletileceği konusunda dikkatli olmalısınız (önbellekten kaldır).

Yükün çoklu sunucu ortamında dağıtılmasıyla ilgili olarak, yük dengeleme için Apache'yi kullanmaktan ziyade yük dengeleyici kullanmanızı öneririm.


"Yük dengeleme için Apache kullanmaktan ziyade yük dengeleyici kullanmanızı öneririm" Apache değilse hangi yaklaşımı / yazılımı önerirsiniz?
Kshitiz Sharma

Temel olarak ağ yöneticinizin yapılandırması gereken yük dengeleyici donanımını öneriyordum. Bu tablonun projeye ek maliyeti vardır. Bu yük dengeleyicinin kendi IP'si (sanal IP olarak da bilinir) olacaktır ve temel olarak bu IP'yi alan adınıza atayacaksınız. İstek geldiğinde, bu işlem, bağlı tüm sunucuya round robin (diğer algoritmalar da kullanılabilir) şeklinde yönlendirir. Donanım bir seçenek değilse apache'yi bu amaçla kullanabilirsiniz, ancak apache'yi yalnızca bu amaç için ayarlamanız gerekmediği için donanımı tercih ederim.

Aynı şeyi yapmak için httpd ile özel bir sunucu kullanıyoruz. Donanım bir sorun değil.
Kshitiz Sharma

Doğru hatırlıyorsam httpd ve mod_cluster kullanabilirsiniz. Ben httpd ve mod_cluster kontrol önce donanım LB "overkill" çözüm gitmeden önce dikkatlice düşünün

@zaske - Muhtemelen donanım yük dengeleyicisinin aşırıya kaçmış olması konusunda haklısınız. Ancak ölçeklendirmeniz gerektiğinde, daha fazla sunucu ekleyerek bunu yapmak kolaydır.

2

Şu anda benzer bir sistem kuruyorum (profesyonel düzeyde) ve bu benim seçtiğim tasarım:

  • İki Nginx yük dengeleyici (ikisi de aktif, diğeri için yük devretme, DNS round robin ile dengeli)
  • Ana master çoğaltma modunda iki MySQL Veri Tabanı
  • Tomcat kümesi olarak iki Tomcat örneği
  • Tomcat kümesi için hem önbellekleme hem de oturum durumu paylaşımı için iki Memcached örneği

Bu, yedekli, yüksek kullanılabilirlikli, ölçeklenebilir bir çözüme ulaşacaktır.

Yük dengeleyicileri (iyi donanımda), her biri doymuş 1 gbit'lik bir çizgiyi kolayca yükler. Bu aynı zamanda SSL boşaltma için harika bir yerdir.

Oturum bilgilerinizi memcached'a kaydedebilirsiniz. Bir tomcat örneğinin başarısız olması durumunda, başka bir tomcat örneği ilgili oturum bilgilerini alabilir ve istemciler bir şey fark etmez. Bunu yapışkan oturumlarla da birleştirmeyi unutmayın. (Ağ trafiğini düşük tutmak için)

Tomcat kümeleme, memcached kullanmadan oturum bilgilerini gerçek zamanlı olarak küme arasında paylaşma seçeneğine de sahiptir. Performansı akıllıca bulsam da Memcached kullanmak daha iyi olacaktır.

Bu uygulamalardan herhangi birinde daha fazla güce ihtiyacınız varsa:

  • Nginx: Daha fazla yük dengeleyici ekle, ancak bunun çok yakında darboğaz olacağını düşünmüyorum.
  • Tomcat: Tomcat kümesinin boyutunu kolayca artırabilir veya daha fazla küme ekleyebilirsiniz
  • Mysql: Bazı salt okunur slave'ler ekleyin veya küme boyutunu artırın (uygulamanıza bağlı olarak, ancak REST tabanlı bir uygulama yazdığınızdan bu sorun olmamalı)
  • Memcached: Daha fazla düğüm ekleyin, Memcached ölçeklerinin oldukça iyi olduğuna inanıyorum.

Uygulamanızın nasıl oluşturulduğunu ve büyük kaynak domuzlarının ne olduğunu bilmiyorum, ancak yüksek bir veritabanı yükü görüyorsanız (yük testleriniz sırasında!), Uygulama ve veritabanı arasında bir önbellek eklemek kesinlikle performansı çok artırabilir. Ancak unutmayın, her şey önlenebilir değildir, sorgularınız her zaman farklıysa, önbellekleme yardımcı olmaz (çok)

Benim tavsiyem VMware Workbench'i (veya similair sanallaştırma yazılımını) indirmek ve basit bir kurulum oluşturmaya çalışmak olacaktır. Yük dengeleme veya kümeleme yok, sadece temel bilgiler ve oradan çalışır. Tek tek daha fazla özellik (dengeleme, önbellekleme, kümeleme vb.) Ekleyin ve her bir konuda biraz araştırma yaptığınızdan emin olun, böylece doğru seçimi yaptığınızı bileceksiniz.

Bu işlem sırasında aynı performans testlerini yapmaya devam ederseniz, X kullanmanın kurulumunuzda Y'yi kullanmaktan daha iyi olup olmadığını veya hangi etki önbelleğe almanın vb. Olacağını kendiniz görebilirsiniz .

Sonunda, böyle bir kurulum gerçekten uygulamanızın ve müşterilerinin gereksinimlerine bağlıdır, her şey çeşitli şekillerde yapılabilir, her birinin kendi güçlü ve zayıf yanları vardır.

Başka soru?

İyi şanslar!

Wesley



Önbellek katmanı için bir çerçeve mi yoksa SQL sorgularında yalnızca bir grup manuel karma mı kullanıyorsunuz?
djechlin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.