Bagaimana cara mendesain layanan web yang sangat skalabel di Jawa?

15

Saya membuat beberapa Layanan Web yang akan memiliki 2000 pengguna bersamaan. Layanan ini ditawarkan secara gratis dan karenanya diharapkan untuk mendapatkan basis pengguna yang besar. Di masa depan mungkin diperlukan untuk meningkatkan hingga 50.000 pengguna.

Sudah ada beberapa pertanyaan lain yang mengatasi masalah seperti - /programming/2567254/building-highly-scalable-web-services

Namun persyaratan saya berbeda dari pertanyaan di atas.

Misalnya - Aplikasi saya tidak memiliki antarmuka pengguna, sehingga gambar, CSS, javascript tidak menjadi masalah. Itu di Jawa sehingga saran seperti menggunakan HipHop untuk menerjemahkan PHP ke kode asli tidak berguna.

Karena itu saya memutuskan untuk menanyakan pertanyaan saya secara terpisah.

Ini adalah pengaturan proyek saya -

  1. Layanan Web berbasis istirahat menggunakan Apache CXF
  2. Hibernate 3.0 (Dengan optimasi yang relevan seperti pemuatan malas dan custom HQL untuk penyetelan)
  3. Tomcat 6.0
  4. MySql 5.5

Apa praktik terbaik yang harus dipatuhi untuk membuat aplikasi berbasis Java dapat diskalakan?

Kshitiz Sharma
sumber
Jika Anda mengekspos layanan REST, menggunakan proxy terbalik seperti Varnish akan sangat membantu. Seberapa segar data yang dibutuhkan? Apakah Anda yakin Anda membutuhkan basis data relasional? Bisakah Anda mempartisi data? Dengan tumpukan teknologi yang Anda gambarkan, saya akan fokus untuk memastikan sesedikit mungkin permintaan benar-benar mencapai titik akhir Anda. Sudahkah Anda melihat melakukan ini dalam memori dengan solusi seperti Hazel cast / Gigaspaces dll?
ebaxt
@ebaxt, terima kasih atas saran Anda. Gigaspaces tampaknya merupakan sumber terbuka. Namun pemeran Hazel terlihat menarik.
Kshitiz Sharma
1
@ebaxt "Apakah Anda yakin Anda membutuhkan basis data relasional?" Mengadopsi nosql akan memiliki perubahan drastis pada arsitektur aplikasi. Kami berusaha menjaga kompleksitas seminimal mungkin. Biaya bukan merupakan faktor bagi kami. Jadi kita akan tetap dengan pendekatan relasional.
Kshitiz Sharma
1
Anda dapat menggunakan Postgres, MySQL atau apa pun. Bagaimana dengan infrastruktur Anda? Bisakah Anda menggunakan disk-array? Apakah server di-host di lokasi yang sama? Bisakah Anda menghubungkan cluster Anda dengan detak jantung dll? Bisakah Anda menempatkan mereka di subnet yang sama?
edze
1
Saya seorang programmer juga. Tetapi jika database relasional Anda adalah hambatan, Anda akan cenderung berakhir dengan pertanyaan ini. Ada beberapa database di pasar yang berkinerja lebih baik daripada yang lain dalam beberapa situasi. Tetapi mereka menggunakan Tingkat Isolasi Transaksi default yang berbeda dan Konkurensi Optimis vs
Konkursi

Jawaban:

8

Saya menangani masalah ini di masa lalu, tetapi masih merasa saya harus banyak belajar di lapangan. Saya menemukan ini sebagai salah satu bidang paling menarik yang ada dalam pengembangan perangkat lunak saat ini, berikut adalah beberapa pemikiran tentang ini:
MySQL adalah database yang cukup adil kecuali jika Anda bekerja dengan sejumlah besar data, dan dalam hal ini Anda dapat mempertimbangkan NoSQL database, tetapi Anda harus hati-hati memeriksa apa yang merupakan database NoSQL terbaik untuk kebutuhan Anda .

Anda harus menerapkan caching di sistem Anda - coba cache sebanyak mungkin data read-only sebanyak mungkin, atau tentukan beberapa strategi caching - misalnya, kami memiliki skenario di mana valid bagi pengguna untuk melihat "data lama" sebagai selama pembaruan terakhir terjadi dalam satu jam terakhir.
Saya akan mempertimbangkan JBoss Cache, atau mungkin Infinispan (yang lebih mirip struktur data terdistribusi) atau kerangka kerja caching populer lainnya untuk ini.
Selain itu, seperti yang Anda sebutkan kucing jantan, saya berasumsi Anda bekerja di beberapa modul permintaan-respons. Cobalah untuk mempertimbangkan menggunakan cache yang ada dalam ruang lingkup permintaan yang diberikan, ini bahkan bisa menjadi HashMap sederhana yang dikaitkan dengan utas penyimpanan lokal .
Ide saya di sini sangat mirip dengan cache tingkat pertama di Hibernate .

Anda harus ingat bahwa file, transaksi, dan sumber daya lainnya mahal untuk membuatnya tetap terbuka. Pastikan Anda menutup file dan transaksi sesegera mungkin, atau Anda akan berakhir dengan bug yang akan mereproduksi pada pengaturan skala besar

Selain itu, Anda harus memahami apa yang dilakukan oleh 2000 pengguna bersamaan - apakah ini berarti bahwa 2000 pengguna mengakses server Anda sekaligus, atau apakah mereka menggunakan sistem Anda? Bedakan antara kasus di mana 2000 pengguna mencoba membuka soket ke server Anda, dan kasus di mana hanya 500, dan 1500 saat ini melihat hasil, dari mengisi input di sisi klien.

Anda harus mempertimbangkan untuk menggunakan pengelompokan - Anda harus berurusan dengan masalah seperti load balancing , sticky session (yang berarti load balancer akan mengarahkan permintaan ke server yang sama untuk sesi yang sama) dan banyak lagi.

Jika Anda perlu memiliki kode sinkronisasi - pilih strategi sinkronisasi dengan hati-hati. Saya melihat beberapa sistem di mana kunci sederhana digunakan, tetapi ReaderWriterLockdapat meningkatkan hal-hal, karena sebagian besar akses hanya baca.

Pertimbangkan untuk melakukan caching dan validasi pihak klien jika memungkinkan, cobalah untuk menyimpan panggilan ke server, dan hanya mengirim perbedaan data, jika sebagian besar respons Anda untuk permintaan dengan parameter yang sama tidak berubah.
Misalnya, di proyek open source oVirt kami meminta untuk mendapatkan statistik dari mesin virtual yang diberikan. beberapa data VM jarang berubah, jadi kami hanya mengirim MD5, jika data mengubah nilai MD5 juga diubah, kami melakukan permintaan untuk mendapatkan data lengkap, dan bukan hanya MD5.

saya menyebutkan hibernate sebelumnya - saya akan merekomendasikan Anda untuk mempertimbangkan menggunakannya - jika Anda perlu melakukan banyak penulisan, dan kurang membaca, Hibernate mungkin tidak ideal untuk Anda, dan Anda harus mempertimbangkan untuk bekerja dengan Spring-JDBC sebagai pembungkus di atas JDBC.

Buat indeks basis data Anda dengan bijak, dan gunakan skema db yang benar. Pertimbangkan untuk menggunakan lapisan prosedur tersimpan karena sudah dikompilasi dan dioptimalkan

Saya ingin menyatakan bahwa di masa lalu, saya berurusan dengan sistem (single node) di mysql (kebanyakan read only access) dengan jboss 4.2.1 dan berhasil mencapai 2000 bersamaan. pengguna
(tidak mengakses sekaligus dalam hal membuka 2.000 soket terhadap server kami), tetapi menggunakan / menelusuri sistem kami, menggunakan JBoss Cache dan preloading ke cache beberapa data yang paling banyak diakses, atau data yang kami sadari akan "panas dan populer" "tetapi solusi kami baik untuk arsitektur dan aliran kami,
jadi seperti yang saya katakan dalam kasus ini -
Ada lebih banyak tips dan trik, tetapi itu benar-benar tergantung pada arsitektur Anda, dan aliran apa yang Anda perlu miliki di sistem Anda. Semoga berhasil!


sumber
Saya setuju kecuali untuk procs yang disimpan, jangan gunakan procs yang disimpan. Dan Anda dapat menggunakan hashmap dan nilai atom secara bersamaan, untuk membuat threadsafe
NimChimpsky
3

Pertanyaan bagus. Mungkin sulit untuk mengatakan pendekatan mana yang terbaik, tetapi akan mencoba dari pengalaman saya.

Cara terbaik untuk mengukur aplikasi web berbasis Java adalah dengan menuliskannya tanpa status kewarganegaraan (jika Anda bisa). Ini memungkinkan Anda untuk skala aplikasi secara horizontal, di mana Anda dapat menambahkan server kucing jantan jika ada lebih banyak pengguna bersamaan.

Namun, seperti yang Anda catat, mungkin ada masalah dengan koneksi database. Tetapi pertanyaan saya adalah, bagaimana Anda mendapatkan data? Apakah pengguna dibuat atau Anda mendapatkan data dari pihak ketiga? Ini sangat penting karena, jika Anda memberikan layanan kepada pengguna Anda dengan data yang dikumpulkan dari aplikasi pihak ketiga (katakanlah FB, Twitter, dll), maka apa yang dapat Anda ikuti, adalah menulis untuk menguasai basis data dan mereplikasi data ke database budak yang dialokasikan untuk setiap instance kucing jantan. Kemudian masing-masing server kucing jantan bisa dapatkan dari database slave-nya sendiri.

 Are there faster alternatives to Mysql?

Anda bisa menggunakan MySQL cluster yang memiliki datastore di memori. Namun waspadalah terhadap kenyataan bahwa aplikasi tersebut mungkin memerlukan beberapa perubahan. Tidak sql joinsdidukung dengan baik di MySQL cluster meskipun dalam versi terbaru ada perbaikan untuk hal yang sama. Jika biaya bukan merupakan faktor, maka Anda dapat mencoba Oracle.

Solusi caching pasti akan meningkatkan kinerja. Tapi kemudian, itu semua tergantung pada arsitektur seluruh aplikasi. Anda harus mengetahui kapan harus mendorong data ke cache, kapan membuatnya kotor (hapus dari cache).

Mengenai mendistribusikan beban di lingkungan multi server, saya akan menyarankan Anda untuk menggunakan load balancer daripada menggunakan Apache untuk load balancing.

Chandra
sumber
"Saya akan menyarankan Anda untuk menggunakan load balancer daripada menggunakan Apache untuk load balancing" Pendekatan / perangkat lunak mana yang akan Anda sarankan jika bukan Apache?
Kshitiz Sharma
Saya pada dasarnya merekomendasikan perangkat keras penyeimbang beban, yang harus dapat dikonfigurasi oleh administrator jaringan Anda. Kursus ini memiliki biaya tambahan untuk proyek. Penyeimbang beban ini akan memiliki IP sendiri (juga disebut IP virtual) dan pada dasarnya Anda akan menetapkan IP ini ke domain Anda. Ketika permintaan datang, ini akan merutekannya ke semua server yang terhubung dalam mode round robin (juga algoritma lain yang tersedia). Anda dapat menggunakan apache untuk tujuan ini jika perangkat keras bukan opsi, tetapi saya lebih suka perangkat keras karena Anda tidak perlu menyetel apache untuk tujuan ini saja.
Kami menggunakan server khusus dengan httpd untuk melakukan hal yang sama. Perangkat keras bukan masalah.
Kshitiz Sharma
Anda dapat menggunakan httpd dan mod_cluster, jika saya ingat dengan benar. Saya akan mempertimbangkan dengan hati-hati sebelum pergi ke solusi "berlebihan" dari perangkat keras LB, sebelum memeriksa httpd dan mod_cluster
@zaske - Anda mungkin benar bahwa penyeimbang beban perangkat keras mungkin berlebihan. Tetapi jika Anda perlu meningkatkan, itu mudah dilakukan dengan menambahkan lebih banyak server.
2

Saat ini saya sedang menyiapkan sistem yang serupa (pada tingkat profesional) dan ini adalah desain yang saya pilih:

  • Dua loadbalancers Nginx (keduanya aktif, keduanya failover untuk yang lain, diseimbangkan dengan DNS round robin)
  • Dua Database MySQL dalam mode replikasi master master
  • Dua contoh Tomcat sebagai tomcat cluster
  • Dua instance Memcached untuk caching dan berbagi status sesi untuk gugus Tomcat

Ini akan mencapai solusi yang terukur, ketersediaan tinggi, dan dapat diskalakan.

Loadbalancers (pada perangkat keras yang layak) akan dengan mudah memuat masing-masing garis 1gbit jenuh. Ini juga merupakan tempat yang bagus untuk pembongkaran SSL.

Anda dapat menyimpan info sesi Anda di memcached. Dalam hal turunan kucing jantan gagal, turunan kucing jantan lain dapat mengambil informasi sesi yang relevan dan klien tidak akan melihat apa pun. Jangan lupa untuk menggabungkan ini dengan sesi lengket juga. (Untuk menjaga lalu lintas jaringan tetap rendah)

Tomcat clustering juga memiliki opsi untuk berbagi informasi sesi antar cluster secara real time, tanpa menggunakan memcached. Meskipun saya pikir kinerja bijaksana, menggunakan Memcached akan lebih baik.

Jika Anda membutuhkan lebih banyak daya di salah satu aplikasi ini:

  • Nginx: Tambahkan lebih banyak loadbalancers, meskipun saya tidak berpikir ini akan menjadi hambatan segera.
  • Tomcat: Anda dapat dengan mudah meningkatkan ukuran cluster Tomcat atau menambahkan lebih banyak kluster
  • Mysql: Tambahkan beberapa budak read-only atau menambah ukuran cluster (tergantung pada aplikasi Anda, tetapi karena Anda menulis aplikasi berbasis REST, ini seharusnya tidak menjadi masalah)
  • Memcached: Tambahkan lebih banyak node, skala Memcached cukup baik saya percaya.

Saya tidak tahu bagaimana aplikasi Anda dibuat dan apa sumber daya babi yang besar, tetapi jika Anda melihat beban basis data yang tinggi (selama uji beban Anda!), Menambahkan cache antara aplikasi dan basis data tentu dapat meningkatkan banyak kinerja. Tapi jangan lupa bahwa tidak semuanya bisa di-cache, jika pertanyaan Anda selalu berbeda, caching tidak akan membantu (banyak)

Saran saya adalah mengunduh VMware Workbench (atau perangkat lunak virtualisasi similair) dan mencoba membuat pengaturan sederhana. Tidak ada loadbalancing atau clustering, hanya dasar-dasarnya dan bekerja dari sana. Satu per satu menambahkan lebih banyak fitur (menyeimbangkan, caching, pengelompokan, dll.) Dan pastikan untuk melakukan riset pada setiap topik, sehingga Anda akan tahu bahwa Anda telah mengambil keputusan yang tepat.

Jika Anda terus menjalankan tes kinerja yang sama selama proses ini, Anda dapat melihat sendiri apakah menggunakan X lebih baik daripada menggunakan Y dalam pengaturan Anda, atau apa dampak caching, dll.

Pada akhirnya, pengaturan seperti ini sangat tergantung pada persyaratan aplikasi Anda dan kliennya, semuanya dapat dilakukan dengan berbagai cara, masing-masing dengan kekuatan dan kelemahannya sendiri.

Ada pertanyaan lagi?

Semoga berhasil!

Wesley

Wesley
sumber
hazelcast? hazelcast.com
NimChimpsky
Apakah Anda menggunakan kerangka kerja untuk lapisan caching, atau hanya sekelompok hash manual pada query SQL?
djechlin