Apakah JSF benar-benar siap untuk memberikan aplikasi web berkinerja tinggi? [Tutup]


16

Saya telah mendengar banyak hal baik tentang JSF tetapi sejauh yang saya tahu orang-orang juga memiliki banyak keluhan serius dengan teknologi ini di masa lalu, tidak menyadari seberapa besar situasinya telah membaik. Kami mempertimbangkan JSF sebagai teknologi yang memungkinkan untuk proyek jaringan sosial. Tetapi kami tidak mengetahui skor kinerja JSF, kami juga tidak dapat menemukan situs web kinerja tinggi mana pun yang telah menggunakan JSF. Orang-orang mengeluh tentang masalah skalabilitas kinerjanya.

Kami masih belum yakin apakah kami melakukan hal yang benar dengan memilih jsf, dan karenanya ingin mendengar dari Anda semua tentang ini dan mempertimbangkan masukan Anda.

Apakah mungkin untuk mengkonfigurasi JSF untuk memenuhi kebutuhan kinerja tinggi dari layanan jejaring sosial? Juga sampai sejauh mana dimungkinkan untuk bertahan dengan masalah saat ini di JSF. Apa sebenarnya masalahnya?


Saya tidak khawatir tentang kompleksitas pengembangan dengan JSF apa yang biasanya dikeluhkan orang lain karena sesuai pengalaman pribadi saya, saya percaya itu sama sekali tidak benar, tetapi saya lebih peduli tentang masalah kinerja dan skalabilitas. Dan tolong jangan hanya menyalahgunakannya pada masalah lama yang ditautkan ke versi sebelumnya. Saya hanya peduli dengan keadaan saat ini, apa pun yang telah berlalu.


7
ptrthomas.wordpress.com/2009/05/15/jsf-sucks Saya tahu bahwa ada respons dari kepala arsitek JSF yang membenarkan setiap keputusan, tetapi bagi saya, seseorang yang mengetahui beberapa teknologi web dan yang menderita, bahkan dengan JSF 2.0, Facelet dan SEAM, ini adalah ejekan. Bahkan James Gosling sais: "Saya benci JSF dengan penuh semangat." Saya akan menggunakan Wicket atau Tapestry dan menghindari JSF dan masalahnya sama sekali.
Falcon

12
@ ThorbjørnRavnAndersen Saya tidak setuju dengan Anda dengan lembut. Saya pikir lebih baik memberikan lebih banyak penjelasan daripada hanya mengatakan: "Saya benci JSF"
Chiron

6
@ ThorbjørnRavnAndersen Saya mengerti maksud Anda, tetapi saya benar-benar mendorong orang untuk memberikan info lebih lanjut. Misalnya, suara turun tanpa komentar selalu mengganggu saya.
Chiron

3
@ Chiron, pertanyaannya bukan apakah JSF dapat digunakan atau tidak, tetapi apakah JSF dapat dibuat untuk melakukan. Orang yang memulai dengan meletakkan kerangka kerja, kemungkinan besar tidak dapat menjawab pertanyaan yang sebenarnya. Mempertahankan aplikasi JSF sendiri, saya juga ingin tahu.

3
> Bahkan James Gosling sais: "Saya benci JSF dengan penuh gairah." - Sudah diketahui bahwa ini adalah kesalahan, karena ia bermaksud mengatakan JSP. Dengarkan dengan cermat fragmen yang dimaksud. Ini tentang apa yang dibuat sebagai respons terhadap ASP klasik, dan itu adalah JSP, bukan JSF.
Arjan Tijms

Jawaban:


24

JSF paling pasti mampu memberikan aplikasi web berkinerja tinggi. Aplikasi yang sedang saya kerjakan sepenuhnya dalam JSF dan dari statistik log saya dapat melihat bahwa banyak halaman intensif non-DB memiliki waktu eksekusi minimum 0 ms dan waktu rata-rata kurang dari 10 ms.

Beberapa orang Wicket telah mengatakan hal-hal tentang kinerja JSF, tetapi menurut tolok ukur yang rumit ini JSF benar-benar berkinerja lebih baik daripada Wicket: http://prezi.com/dr3on1qcajzw/www-world-wide-wait-devoxx-edition/

Perhatikan bahwa selama server tidak jenuh, JSF juga berkinerja lebih baik daripada GWT. Perbandingan GWT / JSF sulit, karena sangat penting bahwa server untuk GWT juga melakukan konversi dan validasi data di postback yang dilakukan JSF. Ini adalah sesuatu yang tidak bisa Anda tinggalkan dalam praktik (jangan pernah mempercayai klien). Juga, untuk grafik GWT vs JSF / Wicket, harus diperhitungkan bahwa langkah perenderan browser adalah sepele untuk JSF / Wicket (karena sebagian besar melayani HTML yang siap-render), tetapi klien GWT masih memiliki beberapa pekerjaan untuk dilakukan. lakukan setelah menerima respons server.

Salah satu masalah kinerja / skalabilitas utama yang lama versi JSF (sebelum 2.0) memiliki, menyalahgunakan tabungan dengan menempatkan terlalu banyak data di dalamnya negara. Hal-hal yang benar-benar seharusnya tidak ada di sana dimasukkan ke dalamnya (seperti konstanta seperti 'foo' seperti di <my:tag attribute="foo"/>).

JSF 2.0 memperkenalkan partial state savingmekanisme, yang berarti hanya keadaan delta yang diselamatkan. Dalam praktiknya ini bisa sangat sedikit dan pengurangan dua urutan besarnya dibandingkan dengan JSF 1.x tidak biasa.

Setelah bertahun-tahun menggunakan JSF, saya dapat mengatakan bahwa kecuali untuk menyimpan terlalu banyak status di JSF 1.x, saya tidak pernah mengalami masalah kinerja yang dapat saya kaitkan ke JSF. Setiap masalah kinerja yang pernah kami alami selalu berakar pada DB dan / atau bagaimana kami mengatur layanan back-end, menulis pertanyaan kami, dll.


1
0 ms ... Saya pikir sarana pengukuran Anda perlu melihat.
gbjbaanb

2
@ gbjbaanb Saya tidak berpikir begitu, ini berasal dari statistik yang cukup profesional diatur. Perhatikan bahwa saya sedang berbicara tentang waktu minimum dan tentang halaman-halaman intensif non-DB . Halaman yang dieksekusi dalam waktu seperti itu jelas tidak memiliki 1000 komponen yang tersebar di lebih dari 100 komponen. Kita bicara halaman tentang relatif sederhana di sini, mungkin 10 komponen, 1 master template yang, mungkin 1 meliputi, pada server yang telah berjalan untuk sementara waktu sehingga semuanya panas dan dalam memori. Waktu rata-rata lebih tinggi (10 ms seperti yang saya sebutkan) dan 90% lebih tinggi juga. Max bisa apa saja.
Arjan Tijms

Situasinya adalah bahwa dunia ini hanya mengkritik hal-hal yang mampu menyelesaikan semua masalah. Tapi itu menyelesaikan semua masalah selalu ada harganya dan membutuhkan semangat dan antusiasme yang besar. Apa yang saya lihat di tim adalah mereka mulai berkembang tanpa memahami siklus hidup. Ini melibatkan kurva belajar yang curam tetapi indah dan luar biasa.
Shirgill Farhan

Kemacetan lebih cenderung berada di database / IO dan bandwidth (seluler ...) daripada server itu sendiri. Java sangat cepat bila digunakan dengan baik.
Christophe Roussy

8

Semua teori di dunia dapat mengatakan JSF luar biasa, tetapi lihatlah seperti apa tampilan halaman Anda. Ini menghasilkan tumpukan besar javascript dan omong kosong lain yang akan sangat menghambat kemampuan Anda untuk menambahkan modul seperti jQuery atau membersihkan penggunaan CSS. Bukan mengatakan itu tidak bisa dilakukan, tetapi berapa biayanya.

Pengalaman pribadi dengan proyek yang relatif kecil dan kompleksitas sedang. Sebuah bencana. Itu berantakan berurusan dengan semua panggilan balik dan Anda tidak dapat menggabungkan teknologi lain dengan mudah. Kami memiliki bug besar yang ternyata disebabkan ketika menggunakan JSTL dicampur dengan JSF. Kami tidak pernah dapat menggunakan semua hal jQuery karena fakta bahwa setiap tautan adalah panggilan balik javascript.

Lari dan lari cepat.

Juga ketika Anda mengatakan skala, skala apa yang Anda bicarakan. Jumlah halaman, jumlah pengguna, jumlah permintaan per detik, jumlah fitur. Jawaban untuk ini dapat membantu Anda. Juga ketika seseorang memberi tahu Anda, perlu mengukur untuk menanyakan derajat dan seberapa cepat. Jawabannya akan sangat membantu Anda. Jika Anda berbicara skala google dalam seminggu atau Anda berbicara tentang 1000 pengguna dan 10.000 tampilan halaman per hari dalam setahun.

Hampir semua kerangka kerja, singkatnya Anda mengetik respons real time di latar belakang, akan berskala untuk memenuhi 99,999% dari kasus penggunaan.


3
-1 untuk skala kerangka kerja apa pun. Itu seperti mengatakan "tidak peduli dengan kinerja."
Raynos

3
Dalam dan dari diri mereka sendiri, kerangka kerja web apa pun yang diterbitkan akan berskala termasuk JSF. Mereka semua berkata begitu, itu akan menjadi kerangka kerja yang sangat buruk jika tidak. Yang mengatakan, banyak orang melakukan hal-hal bodoh dengan itu dan di situlah masalah scaling muncul.
Bill Leeper

1
benar, tetapi beberapa kerangka kerja mendorong Anda untuk melakukan hal-hal dengan menghambat penskalaan, baik karena kerangka kerja mendorong atau komunitas mendorongnya. Saya berpendapat bahwa kerangka itu tidak berskala.
Raynos

Bit "bagaimana Anda mengukur skala" mungkin seharusnya menjadi komentar untuk pertanyaan?

4

Penafian: Saya suka JSF. Pokoknya, bahkan dengan terbaru RI (Mojarra 2.2.x) atau MyFaces, bahkan dengan lama ditunggu pelaksanaan stateless kinerja yang sangat buruk. Ini karena siklus hidup JSF dan fakta bahwa setiap Tampilan dibangun (mahal) untuk setiap permintaan.

Untuk mendapatkan petunjuk, ini adalah patokan sederhana terhadap servlet java biasa vs halaman JSF, keduanya hanya mencetak "hello world"

Servlet

glassfish-3.1.2.2$ ab -n 10000 -c 100 http://localhost:8080/mavenproject-web/NewServlet

Server Software:        GlassFish
Server Hostname:        localhost
Server Port:            8080

Document Path:          /mavenproject-web/NewServlet
Document Length:        128 bytes

Concurrency Level:      100
Time taken for tests:   0.970 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      4300000 bytes
HTML transferred:       1280000 bytes
Requests per second:    10307.02 [#/sec] (mean)
Time per request:       9.702 [ms] (mean)
Time per request:       0.097 [ms] (mean, across all concurrent requests)
Transfer rate:          4328.14 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   1.0      1       5
Processing:     1    9   4.6      8      51
Waiting:        1    8   4.4      7      40
Total:          4   10   4.1      8      51

Percentage of the requests served within a certain time (ms)
  50%      8
  66%     10
  75%     11
  80%     11
  90%     12
  95%     14
  98%     29
  99%     33
 100%     51 (longest request)

JSF

glassfish-3.1.2.2$ ab -n 10000 -c 100 http://localhost:8080/mavenproject-web/xhtml/test/jsf.xhtml

Server Software:        GlassFish
Server Hostname:        localhost
Server Port:            8080

Document Path:          /mavenproject-web/xhtml/test/jsfxhtml
Document Length:        100 bytes

Concurrency Level:      100
Time taken for tests:   4.676 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      4250000 bytes
HTML transferred:       1000000 bytes
Requests per second:    2138.60 [#/sec] (mean)
Time per request:       46.759 [ms] (mean)
Time per request:       0.468 [ms] (mean, across all concurrent requests)
Transfer rate:          887.60 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.5      0       6
Processing:     5   46   6.0     46      73
Waiting:        2   45   5.5     45      72
Total:          8   47   5.8     46      73

Percentage of the requests served within a certain time (ms)
  50%     46
  66%     48
  75%     50
  80%     51
  90%     54
  95%     56
  98%     60
  99%     62
 100%     73 (longest request)

1
Saya tidak berpikir halaman helloworld sederhana bisa representatif atau bermakna. Perbandingan yang serius harus memberikan informasi yang diperlukan seperti nomor versi, konfigurasi yang digunakan dan sebagainya. Silakan baca perbandingan antara JSF dan Wicket dalam jawaban sebelumnya.
lu4242

Biarkan saya tidak setuju. Saya menemukan benar-benar bermakna bahwa dalam konteks stateless sederhana JSF adalah 5 kali lebih lambat dari JSP. Sangat mudah untuk memverifikasi bahwa dalam skenario yang lebih kompleks, kinerja JSF menjadi terburuk. Atau saya dapat memberikan lebih banyak tolok ukur untuk yang paling malas :-) implementasi jsf adalah mojarra 2.2 seperti yang disebutkan di atas, dengan glassfish 3
gpilotino

"... jsf lebih lambat 5 kali dari jsp ..." Saya pikir kesalahan di sini adalah tidak memperhitungkan throughput, dan perilaku mendasar dari jsp vs jsf. Terlalu rumit untuk dijelaskan, tetapi dalam kasus ini, waktu respons jelas lebih lambat karena jsf memiliki efek konkurensi yang tidak dimiliki jsp. Tetapi pada akhirnya lebih akurat untuk membandingkan siklus per detik. Juga, Mojarra tidak sama dengan MyFaces, sehingga kedua implementasi memiliki angka yang berbeda dari perspektif kinerja. Perhatikan efek konkurensi dalam kasus ini berlebihan.
lu4242

Bahkan, benar-benar tidak masuk akal untuk membandingkan servlet biasa vs JSF. Satu-satunya perbandingan yang masuk akal adalah "aplikasi" yang dibuat menggunakan JSP / servlets vs "aplikasi" lain yang melakukan persis sama menggunakan JSF. Mengapa? karena JSF menyediakan solusi bawaan untuk rendering / ajax / navigasi / validasi, hal-hal yang perlu dilakukan dari awal atau dengan tangan di JSP. Sekalipun perbandingannya menarik dari perspektif kinerja (tidak ada kerangka kerja yang lebih cepat dari servlet / jsp), JSP tidak cocok untuk JSF, karena JSP tidak cocok dengan apa yang dilakukan JSF untuk Anda.
lu4242

"Benar-benar tidak masuk akal untuk membandingkan servlet biasa vs JSF". tidak, tidak. kedua teknologi seharusnya mengirimkan konten. inilah sebabnya saya mempertimbangkan konteks kewarganegaraan akun, di mana validasi dan hal-hal lain tidak masuk hitungan. "waktu respon jelas lebih lambat karena jsf memiliki efek konkurensi yang tidak dimiliki jsp" bukankah ini masalah skalabilitas itu sendiri? tentang myfaces, afaik mojarra ini adalah implementasi tercepat di sekitar (saya akan menyelidiki ini)
gpilotino

3

Jika Anda ingin memahami lebih jelas bagaimana kinerja JSF (baik Mojarra 2.1.7 dan MyFaces 2.1.7) dan membandingkannya dengan kerangka kerja yang sama seperti Apache Wicket (keduanya 1.4.20 dan 1.5.5), lihat di sini perbandingan mendalam (MEI 2012):

Memahami JSF 2 dan Wicket: Perbandingan Kinerja

Bagian yang baik adalah semuanya tersedia (kode, data eksperimental, instruksi tentang cara mereproduksi tes, laporan lengkap terperinci). Ini akan menyelesaikan semua pertanyaan Anda tentang kinerja JSF, dan Anda akan melihat apa yang dapat dilakukan Apache MyFaces.


3

Artikel yang mungkin membantu sedikit (meskipun tidak benar-benar konklusif) adalah Kerangka Kerja Server Centric Java: Perbandingan Kinerja di DZone Javalobby:

... Artikel ini meninjau seberapa efektif sebagian besar kerangka kerja web Java SPI pada perubahan parsial yang disediakan oleh server. Kami tidak tertarik pada acara tanpa komunikasi server, yaitu, acara tanpa (mungkin) kontrol server.

Bagaimana mereka akan diukur

Kami akan mengukur jumlah kode yang dikirim ke klien terkait dengan perubahan visual yang dilakukan di klien .

Misalnya untuk perubahan visual kecil (beberapa data baru) dalam komponen, kami berharap tidak banyak kode dari server, yaitu, markup baru yang diperlukan sebagai HTML biasa, atau disematkan dalam JavaScript, atau beberapa instruksi tingkat tinggi yang berisi data baru menjadi divisualisasikan. Kalau tidak, ada sesuatu yang tampaknya salah misalnya komponen lengkap atau zona halaman dibangun kembali, menyia-nyiakan bandwidth dan kekuatan klien (dan mungkin daya server).

Karena kami akan menggunakan demo publik, kami tidak akan mendapatkan patokan gandum yang pasti dan bagus . Tetapi Anda akan melihat perbedaan yang sangat kuat antara kerangka kerja.

Teknik pengujiannya sangat mudah dan semua orang bisa melakukannya tanpa infrastruktur khusus, kita hanya perlu FireFox dan FireBug. Dalam tes ini FireFox 3.6.8 dan FireBug 1.5.4 digunakan.

Konsol FireBug saat "Perlihatkan XMLHttpRequests" diaktifkan untuk log setiap permintaan AJAX yang menunjukkan respons server ...

Kerangka diuji

RichFaces , IceFaces , MyFaces / Trinidad , OpenFaces , PrimeFaces , Vaadin , ZK , ItsNat

... tampaknya satu-satunya implementasi JSF yang bebas dari penalti kinerja serius adalah PrimeFaces ...

Saya belum dapat menemukan perbandingan yang tepat (untuk kinerja), jika ada yang menemukan saya ingin melihatnya!


2

Ada masalah dengan Facelets secara umum yang IMHO adalah hal yang cukup nyaman untuk digunakan. Ini empat kali lebih banyak dari yang seharusnya dan membutuhkan terlalu banyak pekerjaan manual begitu Anda membuat satu langkah dari sesuatu yang primitif. HybridJava akan menjadi pengganti yang baik untuk Facelet sebagai mesin presentasi dalam JSF - ini melakukan pekerjaan yang sama (dan bahkan lebih banyak lagi, khususnya - itu membuat semua "binding" dan id untuk Anda) dengan penekanan tombol yang jauh lebih sedikit.


1

Jadi saya ingin melempar tolok ukur serupa. Saya mengambil halaman contoh bootstrap twitter dan mengubahnya menjadi xhtml ketat. Setelah itu, saya mengatur persis satu kacang CDI ApplicationScoped yang mengembalikan Hello, World. Saya menempatkan ekspresi EL di halaman. Untuk versi JSF, saya menggunakan penangan sumber daya JSF, untuk versi JSPX, saya menggunakan css dan js termasuk gaya HTML.

Saya menggunakan bangku apache untuk menguji waktu buka halaman utama. Pengujian dilakukan pada server TomEE + v1.5.2 yang tidak dioptimalkan. Saya menjalankan setiap benchmark 5x, lalu menjalankan GC penuh sebelum melakukan pengukuran. Tes Bost dilakukan dalam instance JVM yang sama tanpa memulai kembali JVM. Saya memiliki April tersedia di libpath, tapi saya tidak yakin itu mempengaruhi tes ini.

JSF lebih lambat, tetapi tidak banyak, karena kita berurusan dengan jumlah yang sangat kecil. Apa yang tidak ditunjukkan adalah ketika halaman menjadi lebih kompleks, apakah skala JSF / JSPX linear atau eksponensial.

Satu hal yang saya perhatikan adalah bahwa JSPX menghasilkan sangat sedikit sampah dibandingkan dengan JSF. Menjalankan patokan pada halaman JSPX menyebabkan tumpukan bekas melompat dari 184mb ke 237mb. Menjalankan patokan dalam JVM yang sama pada halaman JSF menyebabkan tumpukan bekas melompat dari 108mb menjadi setidaknya 404mb, tetapi pengumpulan sampah otomatis muncul pada saat itu. Tampaknya menyetel pengumpul sampah Anda untuk JSF adalah kebutuhan mutlak .

JSF

jonfisher@peanut:~$ /usr/local/bin/ab -n 10000 -c 100 http://localhost:8080/cdi-jsp/index.jsf
This is ApacheBench, Version 2.3 <$Revision: 1373084 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        Apache-Coyote/1.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /cdi-jsp/index.jsf
Document Length:        2904 bytes

Concurrency Level:      100
Time taken for tests:   2.138 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      32160000 bytes
HTML transferred:       29040000 bytes
Requests per second:    4677.27 [#/sec] (mean)
Time per request:       21.380 [ms] (mean)
Time per request:       0.214 [ms] (mean, across all concurrent requests)
Transfer rate:          14689.55 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   1.3      1      21
Processing:     1   20   9.0     18      63
Waiting:        1   19   8.8     17      62
Total:          2   21   8.8     20      64

Percentage of the requests served within a certain time (ms)
  50%     20
  66%     23
  75%     25
  80%     27
  90%     32
  95%     39
  98%     46
  99%     50
 100%     64 (longest request)

JSPX

jonfisher@peanut:~$ /usr/local/bin/ab -n 10000 -c 100 http://localhost:8080/cdi-jsp/page2.jspx
This is ApacheBench, Version 2.3 <$Revision: 1373084 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        Apache-Coyote/1.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /cdi-jsp/page2.jspx
Document Length:        2440 bytes

Concurrency Level:      100
Time taken for tests:   1.273 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      26290000 bytes
HTML transferred:       24400000 bytes
Requests per second:    7856.63 [#/sec] (mean)
Time per request:       12.728 [ms] (mean)
Time per request:       0.127 [ms] (mean, across all concurrent requests)
Transfer rate:          20170.98 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    5   2.3      6      20
Processing:     1    8   4.6      6      40
Waiting:        1    8   4.3      6      40
Total:          2   13   3.8     12      41

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     12
  75%     13
  80%     13
  90%     17
  95%     20
  98%     24
  99%     28
 100%     41 (longest request)

-3

GWT mengubah kode java Anda menjadi skrip java. jadi itu berjalan sebagai skrip java di sisi klien Anda. Dan juga, Anda dapat mengintegrasikan css ke dalam aplikasi gwt Anda. Secara umum, gwt ringan dan dapat berjalan di semua browser tanpa masalah. Saya tidak tahu banyak tentang JSF. Tapi saya pikir dt, JSF tidak sefleksibel GWT.


1
Itu tidak menjawab pertanyaan, yaitu tentang kinerja JSF dan bukan rekomendasi kerangka kerja. Ngomong-ngomong, GWT biasanya disukai oleh orang-orang yang tidak tahu JavaScript ^^
Danubian Sailor
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.