Apakah aplikasi J2EE Anda berjalan lambat? Bisakah mereka menahan lalu lintas yang meningkat? Artikel ini menjelaskan teknologi pengoptimalan kinerja untuk mengembangkan halaman JSP dan Servlet yang berkinerja tinggi dan sangat elastis. Idenya adalah untuk membangun secepat mungkin dan beradaptasi dengan pertumbuhan jumlah pengguna dan permintaan mereka. Pada artikel ini, saya akan mengarahkan Anda untuk mempelajari teknik penyetelan kinerja yang praktis dan terbukti yang akan sangat meningkatkan kinerja halaman servlet dan jsp Anda, sehingga meningkatkan kinerja J2EE. Beberapa dari teknologi ini digunakan dalam fase pengembangan, seperti fase desain dan pengkodean. Bagian lain dari teknologi ini terkait dengan konfigurasi.
Teknik 1: Menyimpan data dalam cache dalam metode HttpServletinit()
Server memanggil metode init() servlet setelah membuat instance servlet dan sebelum servlet menangani permintaan apa pun. Metode ini hanya dipanggil sekali dalam siklus hidup servlet. Untuk meningkatkan kinerja, simpan data statis dalam cache init() atau lakukan operasi mahal yang harus dilakukan selama inisialisasi. Misalnya, salah satu praktik terbaik adalah menggunakan kumpulan koneksi JDBC yang mengimplementasikan antarmuka javax.sql.DataSource.
DataSource diperoleh dari pohon JNDI. Menggunakan JNDI untuk menemukan DataSource setiap kali SQL dipanggil sangat mahal, dan ini sangat memengaruhi kinerja aplikasi. Metode init() Servlet dapat digunakan untuk mendapatkan DataSource dan menyimpannya dalam cache untuk digunakan kembali nanti:
publicclassControllerServletextendsHttpServlet
{
privatejavax.sql.DataSourcetestDS=null;
publicvoidinit(ServletConfigconfig)throwsServletException
{
super.init(konfigurasi);
Konteksctx=null;
mencoba
{
ctx=newInitialContext();
testDS=(javax.sql.DataSource)ctx.lookup("jdbc/testDS");
}
tangkapan(PenamaanPengecualian)
{
ne.printStackTrace();
}
menangkap (Pengecualian)
{
e.printStackTrace();
}
}
publicjavax.sql.DataSourcegetTestDS()
{
kembali tesDS;
}
...
...
}
Teknik 2: Nonaktifkan fungsi pemuatan otomatis servlet dan JSP
. Anda harus me-restart server setiap kali Anda memodifikasi Servlet/JSP. Karena fitur autoloading mengurangi waktu pengembangan, fitur ini dianggap sangat berguna selama tahap pengembangan. Namun, biayanya sangat mahal pada fase runtime; servlet/JSP menyebabkan kinerja buruk karena pemuatan yang tidak perlu dan peningkatan beban pada class loader. Sekali lagi, hal ini dapat menyebabkan aplikasi Anda mengalami konflik yang aneh karena kelas yang telah dimuat oleh pemuat kelas tertentu tidak dapat bekerja sama dengan kelas yang dimuat oleh pemuat kelas saat ini. Oleh karena itu, untuk mendapatkan kinerja yang lebih baik di lingkungan yang sedang berjalan, matikan fungsi pemuatan otomatis servlet/JSP.
Teknik 3: Kontrol HttpSession
Banyak aplikasi yang memerlukan serangkaian permintaan klien agar dapat dihubungkan satu sama lain. Karena protokol HTTP tidak memiliki kewarganegaraan, aplikasi berbasis web harus bertanggung jawab untuk mempertahankan keadaan yang disebut sesi. Untuk mendukung aplikasi yang harus mempertahankan status, teknologi Javaservlet menyediakan API yang mengelola sesi dan memungkinkan banyak mekanisme untuk mengimplementasikan sesi. Objek HttpSession bertindak sebagai sesi, namun ada biaya untuk menggunakannya. Setiap kali HttpSession digunakan dan ditimpa, itu dibaca oleh servlet. Anda dapat meningkatkan kinerja dengan menggunakan teknik berikut:
lJangan membuat HttpSession default di halaman JSP: Secara default, halaman JSP membuat HttpSession. Jika Anda tidak menggunakan HttpSession di halaman JSP Anda, untuk menghemat overhead kinerja, gunakan instruksi halaman berikut untuk menghindari pembuatan objek HttpSession secara otomatis:
< %@pagesession="false"% >
1) Jangan menyimpan grafik objek besar di HttpSession: Jika Anda menyimpan data di HttpSession sebagai grafik objek besar, server aplikasi harus memproses seluruh objek HttpSession setiap kali. Ini akan memaksa serialisasi Java dan meningkatkan overhead komputasi. Karena overhead serialisasi, throughput sistem akan berkurang seiring dengan bertambahnya objek data yang disimpan di objek HttpSession.
2) Lepaskan HttpSession setelah digunakan: Ketika HttpSession tidak lagi digunakan, gunakan metode HttpSession.invalidate() untuk membatalkan sesi.
3) Tetapkan nilai batas waktu: Mesin servlet memiliki nilai batas waktu default. Jika Anda tidak menghapus sesi tersebut atau tetap menggunakan sesi tersebut hingga waktunya habis, mesin servlet akan menghapus sesi tersebut dari memori. Karena overhead dalam memori dan pengumpulan sampah, semakin besar nilai batas waktu sesi, semakin besar dampaknya terhadap ketahanan dan kinerja sistem. Cobalah untuk mengatur nilai batas waktu sesi serendah mungkin.
Teknik 4: Gunakan kompresi gzip
Kompresi adalah praktik menghilangkan informasi yang berlebihan dan mendeskripsikan informasi Anda dalam ruang sekecil mungkin. Menggunakan gzip (GNUzip) untuk mengompresi dokumen dapat secara efektif mengurangi waktu pengunduhan file HTML. Semakin kecil pesan Anda, semakin cepat pesan tersebut terkirim. Oleh karena itu, jika Anda mengompresi konten yang dihasilkan oleh aplikasi web Anda, semakin cepat konten tersebut sampai ke pengguna dan ditampilkan di layar pengguna. Tidak semua browser mendukung kompresi gzip, namun mudah untuk memeriksa apakah browser mendukungnya dan mengirim konten yang dikompresi gzip ke browser. Cuplikan kode di bawah mengilustrasikan cara mengirim konten terkompresi.
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsIOException,ServletException
{
OutputStreamout=null
//Periksa header-Encoding-Encoding dari Permintaan HTTP.
//Jika header berisi gzip, pilih GZIP.
//Jika header menyertakan kompres, pilih ZIP.
//Jika tidak, pilih tidak ada kompresi.
Stringencoding=request.getHeader("Terima-Encoding");
if(encoding!=null&&encoding.indexOf("gzip")!=-1)
{
respon.setHeader("Pengkodean Konten","gzip");
keluar=newGZIPOutputStream(response.getOutputStream());
}
elseif(pengkodean!=null&&encoding.indexOf("kompres")!=-1)
{
respon.setHeader("Pengkodean Konten","kompres");
keluar=newZIPOutputStream(response.getOutputStream());
}
kalau tidak
{
keluar=respons.getOutputStream();
}
...
...
}
Teknik 5: Jangan gunakan SingleThreadModel
SingleThreadModel menjamin bahwa servlet hanya menangani satu permintaan dalam satu waktu. Jika servlet mengimplementasikan antarmuka ini, mesin servlet akan membuat instance servlet terpisah untuk setiap permintaan baru, yang akan menyebabkan banyak overhead sistem. Jika Anda perlu menyelesaikan masalah keamanan thread, silakan gunakan metode lain selain antarmuka ini. Penggunaan SingleThreadModel tidak lagi disarankan di Servlet2.4.
Teknik 6: Gunakan
mesin servlet kumpulan thread untuk membuat thread terpisah untuk setiap permintaan, tetapkan thread ke metode service(), lalu hapus thread setelah metode service() dijalankan. Secara default, mesin servlet dapat membuat thread baru untuk setiap permintaan. Karena membuat dan menghapus thread itu mahal, perilaku default ini mengurangi kinerja sistem. Kita dapat menggunakan kumpulan thread untuk meningkatkan kinerja. Sesuai dengan jumlah pengguna bersamaan yang diharapkan, konfigurasikan kumpulan thread dan tetapkan jumlah minimum dan maksimum thread di kumpulan thread serta nilai pertumbuhan minimum dan maksimum. Awalnya, mesin servlet membuat kumpulan thread dengan jumlah thread yang sama dengan jumlah minimum thread dalam konfigurasi. Mesin servlet kemudian menugaskan thread dari pool ke permintaan alih-alih membuat thread baru setiap kali menyelesaikan operasi, mesin servlet mengembalikan thread ke dalam thread pool. Dengan menggunakan kumpulan thread, kinerja dapat ditingkatkan secara signifikan. Jika diperlukan, lebih banyak thread dapat dibuat berdasarkan jumlah maksimum thread dan jumlah pertumbuhan.
Teknik 7: Pilih mekanisme penyertaan yang benar
Di halaman JSP, ada dua cara untuk memasukkan file: menyertakan instruksi (< %@includefile="test.jsp"% >) dan menyertakan tindakan (<jsp:includepage="test.jsp " siram="benar"/>). Direktif include menyertakan konten file tertentu selama tahap kompilasi; misalnya, saat halaman dikompilasi ke dalam servlet. Tindakan penyertaan melibatkan penyertaan konten file selama fase permintaan; misalnya, saat pengguna meminta halaman. Menyertakan instruksi lebih cepat daripada menyertakan tindakan. Oleh karena itu, kecuali file yang disertakan sering berubah, Anda akan mendapatkan performa yang lebih baik dengan menggunakan direktif include.
Teknik 8: Gunakan cakupan yang sesuai dalam tindakan useBean
Salah satu cara paling ampuh untuk menggunakan halaman JSP adalah bekerja dengan komponen JavaBean. JavaBeans dapat disematkan ke halaman JSP menggunakan tag <jsp:useBean>. Sintaksnya adalah sebagai berikut:
<jsp:useBeanid="name"scope="page|request|session|application"class=
"paket.className"type="typeName">
</jsp:useBean>
Atribut scope mendeskripsikan cakupan bean yang terlihat. Nilai default atribut scope adalah halaman. Anda harus memilih rentang yang benar berdasarkan kebutuhan aplikasi Anda, jika tidak maka akan mempengaruhi kinerja aplikasi Anda.
Misalnya, jika Anda memerlukan objek khusus untuk beberapa permintaan, tetapi Anda menetapkan cakupannya ke sesi, objek tersebut akan tetap berada di memori setelah permintaan berakhir. Itu akan tetap ada di memori kecuali Anda secara eksplisit menghapusnya dari memori, membatalkan sesi, atau waktu sesi habis. Jika Anda tidak memilih atribut cakupan yang benar, kinerja akan terpengaruh karena overhead memori dan pengumpulan sampah. Jadi tetapkan cakupan yang sesuai untuk objek dan hapus objek tersebut segera setelah Anda selesai menggunakannya.
Teknik lain-lain
1) Hindari penggabungan string: Karena objek String adalah objek yang tidak dapat diubah, penggunaan operator "+" akan menghasilkan pembuatan objek zero-time dalam jumlah besar. Semakin banyak "+" yang Anda gunakan, semakin banyak objek zero-time yang dihasilkan, yang akan memengaruhi kinerja. Saat Anda perlu menggabungkan string, gunakan StringBuffer alih-alih operasi "+".
2) Hindari penggunaan System.out.println: System.out.println memproses input/output disk secara sinkron, yang sangat mengurangi throughput sistem. Hindari menggunakan System.out.println bila memungkinkan. Meskipun ada banyak alat debugging matang yang tersedia, terkadang System.out.println masih berguna untuk tujuan penelusuran atau debugging. Anda harus mengonfigurasi System.out.println agar hanya membukanya selama fase kesalahan dan debugging. Menggunakan variabel finalBoolean, ketika dikonfigurasi ke false, pemeriksaan optimasi dan keluaran jejak eksekusi diselesaikan selama fase kompilasi.
3) Perbandingan ServletOutputStream dan PrintWriter: Karena aliran keluaran karakter dan pengkodean data ke dalam byte, penggunaan PrintWriter menimbulkan overhead kinerja yang kecil. Oleh karena itu, PrintWriter harus digunakan setelah semua konversi kumpulan karakter telah dilakukan dengan benar. Di sisi lain, ketika Anda mengetahui bahwa servlet Anda hanya akan mengembalikan data biner, gunakan ServletOutputStream karena wadah servlet tidak mengkodekan data biner, sehingga Anda menghilangkan overhead konversi kumpulan karakter.
Ringkasan
Tujuan artikel ini adalah untuk menunjukkan kepada Anda beberapa teknik optimasi kinerja yang praktis dan terbukti untuk meningkatkan kinerja servlet dan JSP, yang akan meningkatkan kinerja aplikasi J2EE Anda secara keseluruhan. Langkah selanjutnya adalah mengamati penyesuaian kinerja teknologi terkait lainnya, seperti EJB, JMS, dan JDBC.