Mengapa JSF menyimpan status komponen UI di server?

108
  1. Sampai titik berapa JSF menyimpan status komponen UI di sisi server & kapan tepatnya informasi status komponen UI dihapus dari memori server? Saat pengguna yang masuk pada aplikasi menavigasi halaman, apakah status komponen akan terus terakumulasi di server?

  2. Saya tidak mengerti apa manfaat mempertahankan status komponen UI di server!? Tidak cukupkah meneruskan data yang divalidasi / dikonversi secara langsung ke kacang yang dikelola? Dapatkah saya atau haruskah saya mencoba menghindarinya?

  3. Bukankah itu memakan terlalu banyak memori di sisi server, jika ada ribuan sesi pengguna secara bersamaan? Saya memiliki aplikasi tempat pengguna dapat memposting blog tentang topik tertentu. Blog ini berukuran cukup besar. Ketika akan ada posting kembali atau permintaan untuk melihat blog, apakah data halaman besar ini akan disimpan sebagai bagian dari status komponen? Ini akan memakan terlalu banyak memori. Bukankah ini masalah?


Pembaruan 1:

Sekarang, tidak perlu lagi menyimpan status saat menggunakan JSF. Implementasi JSF Stateless berperforma tinggi tersedia untuk digunakan. Lihat blog ini & pertanyaan ini untuk detail & diskusi yang relevan. Selain itu, ada masalah terbuka untuk disertakan dalam spesifikasi JSF, opsi untuk menyediakan mode stateless untuk JSF. (PS Pertimbangkan untuk memilih masalah ini & ini jika ini adalah fitur yang berguna untuk Anda.)


Perbarui 2 (24-02-2013):

Kabar baik bahwa Mojarra 2.1.19 keluar dengan mode stateless !

Lihat disini:

http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

Rajat Gupta
sumber

Jawaban:

199

Mengapa JSF perlu menyimpan status komponen UI di sisi server?

Karena HTTP bersifat stateless dan JSF stateful. Pohon komponen JSF tunduk pada perubahan dinamis (terprogram). JSF hanya perlu mengetahui keadaan persisnya seperti ketika formulir telah ditampilkan ke pengguna akhir, sehingga dapat berhasil memproses seluruh siklus hidup JSF berdasarkan informasi yang diberikan oleh pohon komponen JSF asli ketika formulir telah dikirim kembali ke server. Pohon komponen menyediakan informasi tentang nama parameter permintaan, konverter / validator yang diperlukan, properti kacang terkelola yang terikat, dan metode tindakan.


Sampai titik mana JSF menyimpan status komponen UI di sisi server dan kapan tepatnya informasi status komponen UI dihapus dari memori server?

Kedua pertanyaan itu tampaknya bermuara pada hal yang sama. Bagaimanapun, ini adalah implementasi khusus dan juga tergantung pada apakah status disimpan di server atau klien. Implementasi yang sedikit layak akan menghapusnya ketika telah kedaluwarsa atau ketika antrian penuh. Mojarra misalnya memiliki batas default 15 tampilan logis saat penyimpanan negara diatur ke sesi. Ini dapat dikonfigurasi dengan parameter konteks berikut di web.xml:

<context-param>
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>15</param-value>
</context-param>

Lihat juga FAQ Mojarra untuk parameter khusus Mojarra lainnya dan jawaban terkait com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews


Saat pengguna yang masuk pada aplikasi menavigasi halaman, apakah status komponen akan terus terakumulasi di server?

Secara teknis, itu tergantung implementasinya. Jika Anda berbicara tentang navigasi halaman-ke-halaman (hanya DAPATKAN permintaan) maka Mojarra tidak akan menyimpan apa pun dalam sesi. Namun jika itu adalah permintaan POST (formulir dengan tautan perintah / tombol), maka Mojarra akan menyimpan status setiap formulir dalam sesi hingga batas maksimal. Hal ini memungkinkan pengguna akhir untuk membuka berbagai formulir di tab browser yang berbeda dalam sesi yang sama.

Atau, ketika penyimpanan negara diatur ke klien, maka JSF tidak akan menyimpan apa pun dalam sesi. Anda dapat melakukannya dengan parameter konteks berikut di web.xml:

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

Ini kemudian akan diserialkan ke string terenkripsi di bidang input tersembunyi dengan nama javax.faces.ViewStateformulir.


Saya tidak mengerti apa manfaat dari mempertahankan status komponen UI di sisi server. Tidak cukupkah meneruskan data yang divalidasi / dikonversi secara langsung ke kacang yang dikelola? Bisakah / haruskah saya mencoba menghindarinya?

Itu tidak cukup untuk memastikan integritas dan ketahanan JSF. JSF adalah kerangka kerja dinamis dengan satu titik kontrol masuk. Tanpa manajemen negara, seseorang akan dapat memalsukan / meretas permintaan HTTP dengan cara tertentu (misalnya memanipulasi disabled, readonlydan renderedatribut), untuk membiarkan JSF melakukan hal-hal yang berbeda -dan berpotensi berbahaya-. Bahkan rentan terhadap serangan CSRF dan phishing.


Dan bukankah itu akan menghabiskan terlalu banyak memori di sisi server, jika ada ribuan sesi pengguna secara bersamaan? Saya memiliki aplikasi tempat pengguna dapat memposting blog tentang topik tertentu. Blog ini berukuran cukup besar. Ketika akan ada posting balik atau permintaan untuk melihat blog, blog besar akan disimpan sebagai bagian dari komponen keadaan. Ini akan menghabiskan terlalu banyak memori. Bukankah ini masalah?

Memori sangat murah. Berikan saja memori yang cukup kepada server aplikasi. Atau jika bandwidth jaringan lebih murah bagi Anda, cukup alihkan penyimpanan status ke sisi klien. Untuk menemukan kecocokan terbaik, cukup uji stres dan buat profil aplikasi web Anda dengan jumlah maksimum pengguna bersamaan yang diharapkan dan kemudian berikan server aplikasi 125% ~ 150% dari memori terukur maksimum.

Perhatikan bahwa JSF 2.0 telah meningkat pesat dalam manajemen status. Hal ini dimungkinkan untuk menyimpan keadaan parsial (misalnya hanya yang <h:form>akan disimpan, bukan seluruh hal dari <html>semua jalan sampai akhir). Mojarra misalnya melakukan itu. Bentuk rata-rata dengan 10 bidang masukan (masing-masing dengan label dan pesan) dan 2 tombol akan membutuhkan waktu tidak lebih dari 1KB. Dengan 15 tampilan dalam sesi, itu tidak boleh lebih dari 15 KB per sesi. Dengan ~ 1000 sesi pengguna bersamaan, ukurannya tidak boleh lebih dari 15MB.

Perhatian Anda harus lebih difokuskan pada objek nyata (kacang yang dikelola dan / atau bahkan entitas DB) dalam ruang lingkup sesi atau aplikasi. Saya telah melihat banyak kode dan proyek yang tidak perlu menduplikasi seluruh tabel database ke dalam memori Java dalam bentuk kacang cakupan sesi di mana Java digunakan sebagai pengganti SQL untuk memfilter / mengelompokkan / mengatur catatan. Dengan ~ 1000 catatan, itu akan dengan mudah melebihi 10MB per sesi pengguna .

BalusC
sumber
1
Bisakah Anda menjelaskan # 2? Mengapa pohon komponen tidak bisa dibuat ulang pada setiap permintaan? Status apa yang sebenarnya perlu disimpan di antara permintaan dan mengapa? Sepertinya satu-satunya alasan untuk menyimpan pohon komponen di antara permintaan adalah untuk performa.
Ryan
Pertanyaan yang lebih terfokus di sini: stackoverflow.com/questions/7349174/…
Ryan
Jawaban Anda sangat jelas bagi saya! Masalah tentang kinerja dan skalabilitas JSF memiliki hubungan intrinsik dengan implementasi pemrogram! Perlu diketahui menggunakan teknologi dengan cara yang benar!
Lucas Batistussi
"Beri saja appserver cukup memori." Eh, saya mendapat kesan bahwa kita sedang membicarakan hal-hal tingkat perusahaan di sini, jika kita berbicara tentang ribuan sesi pengguna secara bersamaan. Jika Anda memiliki peralatan tingkat perusahaan di suatu perusahaan, Anda tidak bisa hanya "memberikan memori yang cukup kepada server aplikasi" seperti yang dapat Anda lakukan di kotak linux Anda di rumah.
stu
Jawaban Anda sangat jelas dan terima kasih untuk itu. Mengapa cakupan flash JSF hilang jika javax.faces.PARTIAL_STATE_SAVING menjadi true. getFacesContext (). getExternalContext (). getFlash (). put ("buildingId", buildingId).
May Thet