วิธีที่ 1: ข้อมูลแคชในวิธีการ init() ของเซิร์ฟเล็ต
หลังจากที่แอปพลิเคชันเซิร์ฟเวอร์เตรียมใช้งานอินสแตนซ์เซิร์ฟเล็ตและก่อนให้บริการตามคำขอของไคลเอ็นต์ แอปพลิเคชันจะเรียกเมธอด init() ของเซิร์ฟเล็ต ในวงจรชีวิตของเซิร์ฟเล็ต เมธอด init() จะถูกเรียกเพียงครั้งเดียวเท่านั้น ด้วยการแคชข้อมูลคงที่บางส่วนในเมธอด init() หรือดำเนินการบางอย่างที่ใช้เวลานานซึ่งต้องทำเพียงครั้งเดียว จะทำให้ประสิทธิภาพของระบบดีขึ้นอย่างมาก
ตัวอย่างเช่น การสร้างพูลการเชื่อมต่อ JDBC ในเมธอด init() เป็นตัวอย่างที่ดีที่สุด สมมติว่าเราใช้อินเทอร์เฟซ DataSource ของ jdbc2.0 เพื่อรับการเชื่อมต่อฐานข้อมูล ภายใต้สถานการณ์ปกติ เราจำเป็นต้องได้รับข้อมูลเฉพาะผ่าน JNDI เราสามารถจินตนาการได้ว่าในแอปพลิเคชันเฉพาะ หากมีการดำเนินการแบบสอบถาม JNDI สำหรับทุกคำขอ SQL ประสิทธิภาพของระบบจะลดลงอย่างรวดเร็ว วิธีแก้ไขคือโค้ดต่อไปนี้ ซึ่งจะแคชแหล่งข้อมูลเพื่อให้สามารถใช้งานได้ต่อไปในระหว่างการเรียก SQL ครั้งถัดไป:
ControllerServlet ระดับสาธารณะขยาย HttpServlet
-
javax.sql.DataSource ส่วนตัว testDS = null;
โมฆะสาธารณะ init (การกำหนดค่า ServletConfig) พ่น ServletException
-
super.init(กำหนดค่า);
บริบท ctx = null;
พยายาม
-
ctx = InitialContext ใหม่ ();
testDS = (javax.sql.DataSource)ctx.lookup("jdbc/testDS";
-
จับ (การตั้งชื่อข้อยกเว้น NE)
-
ne.printStackTrace();
-
จับ (ยกเว้น e)
-
e.printStackTrace();
-
}
สาธารณะ javax.sql.DataSource getTestDS()
-
กลับ testDS;
-
-
-
}
วิธีที่ 2: ปิดใช้งานเซิร์ฟเล็ตและการโหลดซ้ำอัตโนมัติของ JSP (การโหลดซ้ำอัตโนมัติ)
Servlet/JSP มอบเทคโนโลยีที่ใช้งานได้จริง กล่าวคือ เทคโนโลยีการโหลดซ้ำอัตโนมัติ ซึ่งช่วยให้นักพัฒนามีสภาพแวดล้อมการพัฒนาที่ดีโดยไม่ต้องรีสตาร์ทเซิร์ฟเวอร์แอปพลิเคชันเมื่อคุณเปลี่ยนเซิร์ฟเล็ตและเพจ JSP อย่างไรก็ตาม เทคโนโลยีนี้เป็นการสูญเสียทรัพยากรระบบอย่างมากในระหว่างขั้นตอนการรันผลิตภัณฑ์ เนื่องจากจะนำภาระมหาศาลมาสู่คลาสโหลดเดอร์ของเอ็นจิ้น JSP ดังนั้นการปิดฟังก์ชันโหลดซ้ำอัตโนมัติจึงช่วยปรับปรุงประสิทธิภาพของระบบได้มาก
วิธีที่ 3: อย่าใช้ HttpSession ในทางที่ผิด
ในแอปพลิเคชันจำนวนมาก โปรแกรมของเราจำเป็นต้องรักษาสถานะของไคลเอ็นต์เพื่อให้เพจต่างๆ สามารถสื่อสารระหว่างกันได้ แต่น่าเสียดาย เนื่องจาก HTTP ไม่มีสถานะโดยธรรมชาติ จึงไม่สามารถบันทึกสถานะของไคลเอ็นต์ได้ ดังนั้นแอปพลิเคชันเซิร์ฟเวอร์ทั่วไปจึงมีเซสชันเพื่อบันทึกสถานะของไคลเอ็นต์ ในแอปพลิเคชันเซิร์ฟเวอร์ JSP ฟังก์ชันเซสชันจะถูกนำไปใช้ผ่านออบเจ็กต์ HttpSession แต่ถึงแม้จะสะดวก แต่ก็นำภาระมาสู่ระบบเช่นกัน เนื่องจากทุกครั้งที่คุณได้รับหรืออัปเดตเซสชัน ผู้ควบคุมระบบจะต้องดำเนินการซีเรียลไลซ์เซสชันที่ใช้เวลานาน คุณสามารถปรับปรุงประสิทธิภาพของระบบได้โดยจัดการ HttpSession ด้วยวิธีต่อไปนี้:
หากไม่จำเป็น คุณควรปิดการตั้งค่าเริ่มต้นของ HttpSession ในเพจ JSP: หากคุณไม่ได้ระบุอย่างชัดเจน แต่ละเพจ JSP จะสร้าง HttpSession ตามค่าเริ่มต้น หากคุณไม่ต้องการใช้เซสชันใน JSP ของคุณ คุณสามารถปิดใช้งานได้โดยใช้ตัวบ่งชี้เพจ JSP ต่อไปนี้:
<%@ เซสชั่นเพจ = "false"%>
อย่าเก็บออบเจ็กต์ข้อมูลขนาดใหญ่ไว้ใน HttpSession: หากคุณเก็บออบเจ็กต์ข้อมูลขนาดใหญ่ไว้ใน HttpSession แอปพลิเคชันเซิร์ฟเวอร์จะทำให้เป็นอนุกรมทุกครั้งที่อ่านหรือเขียน ซึ่งจะเพิ่มภาระให้กับระบบ ยิ่งวัตถุข้อมูลที่คุณจัดเก็บไว้ใน HttpSession มีขนาดใหญ่เท่าใด ประสิทธิภาพของระบบจะลดลงเร็วขึ้นเท่านั้น
เมื่อคุณไม่ต้องการ HttpSession อีกต่อไป ให้ปล่อยโดยเร็วที่สุด: เมื่อคุณไม่ต้องการเซสชันอีกต่อไป คุณสามารถปล่อยได้โดยการเรียกเมธอด HttpSession.invalidate()
พยายามตั้งค่าการหมดเวลาเซสชันให้สั้นที่สุด: ในแอปพลิเคชันเซิร์ฟเวอร์ JSP มีการหมดเวลาเซสชันเริ่มต้น เมื่อลูกค้าไม่ดำเนินการใดๆ หลังจากเวลานี้ ระบบจะปล่อยเซสชันที่เกี่ยวข้องออกจากหน่วยความจำโดยอัตโนมัติ ยิ่งตั้งค่าการหมดเวลาไว้มากเท่าใด ประสิทธิภาพของระบบก็จะยิ่งต่ำลง ดังนั้นวิธีที่ดีที่สุดคือพยายามรักษาค่าให้ต่ำที่สุดเท่าที่จะเป็นไปได้
วิธีที่ 4: บีบอัดเอาต์พุตเพจ
การบีบอัดเป็นวิธีที่ดีในการแก้ปัญหาความซ้ำซ้อนของข้อมูล โดยเฉพาะอย่างยิ่งในปัจจุบันที่แบนด์วิธเครือข่ายยังไม่ได้รับการพัฒนาเพียงพอ เบราว์เซอร์บางตัวรองรับ gzip (GNU zip) เพื่อบีบอัดไฟล์ HTML วิธีนี้สามารถลดเวลาในการดาวน์โหลดไฟล์ HTML ได้อย่างมาก ดังนั้น หากคุณบีบอัดเพจ HTML ที่สร้างโดยเซิร์ฟเล็ตหรือเพจ JSP ผู้ใช้จะรู้สึกว่าความเร็วในการเรียกดูเพจจะเร็วมาก ขออภัย ไม่ใช่ทุกเบราว์เซอร์ที่รองรับการบีบอัด gzip แต่คุณสามารถตรวจสอบในโปรแกรมของคุณได้ว่าเบราว์เซอร์ของลูกค้ารองรับหรือไม่ นี่คือข้อมูลโค้ดเกี่ยวกับวิธีการนำวิธีนี้ไปใช้:
โมฆะสาธารณะ doGet (คำขอ HttpServletRequest, การตอบสนอง HttpServletResponse)
พ่น IOException, ServletException
-
OutputStream ออก = null
การเข้ารหัสสตริง = request.getHeader("Accept-Encoding";
ถ้า (การเข้ารหัส != null && encoding.indexOf("gzip" != -1)
-
request.setHeader("การเข้ารหัสเนื้อหา" , "gzip";
ออก = GZIPOutputStream ใหม่ (request.getOutputStream());
-
อย่างอื่นถ้า (การเข้ารหัส != null && encoding.indexOf("comdivss" != -1)
-
request.setHeader("การเข้ารหัสเนื้อหา" , "comdivss";
ออก = ZIPOutputStream ใหม่ (request.getOutputStream());
-
อื่น
-
ออก = request.getOutputStream();
-
-
-
}
วิธีที่ 5: ใช้เธรดพูล
แอปพลิเคชันเซิร์ฟเวอร์สร้างเธรดสำหรับการประมวลผลคำขอไคลเอนต์ที่แตกต่างกันตามค่าเริ่มต้น และกำหนดเมธอด service() ให้กับเธรดเหล่านั้น เมื่อการเรียกใช้เมธอด service() เสร็จสิ้น เธรดที่เกี่ยวข้องก็จะยกเลิกไปด้วย . เนื่องจากการสร้างและการทำลายเธรดต้องใช้ทรัพยากรระบบบางอย่าง โหมดเริ่มต้นนี้จะลดประสิทธิภาพของระบบ แต่โชคดีที่เราสามารถเปลี่ยนสถานการณ์นี้ได้โดยการสร้างกลุ่มเธรด นอกจากนี้ เรายังจำเป็นต้องตั้งค่าจำนวนเธรดขั้นต่ำและจำนวนเธรดสูงสุดสำหรับกลุ่มเธรดนี้ เมื่อแอปพลิเคชันเซิร์ฟเวอร์เริ่มต้น จะสร้างเธรดพูลด้วยจำนวนเท่ากับจำนวนเธรดขั้นต่ำ เมื่อลูกค้ามีคำขอ เธรดจะถูกนำออกจากพูลเพื่อการประมวลผล เมื่อการประมวลผลเสร็จสิ้น เธรดจะถูก นำกลับลงสระตรงกลาง หากมีเธรดในพูลไม่เพียงพอ ระบบจะเพิ่มจำนวนเธรดในพูลโดยอัตโนมัติ แต่จำนวนทั้งหมดต้องไม่เกินจำนวนเธรดสูงสุด ด้วยการใช้เธรดพูล เมื่อคำขอของไคลเอ็นต์เพิ่มขึ้นอย่างรวดเร็ว โหลดของระบบจะแสดงเส้นโค้งขึ้นอย่างราบรื่น ซึ่งจะช่วยปรับปรุงความสามารถในการปรับขนาดของระบบ
วิธีที่ 6: เลือกกลไกการรวมหน้าที่ถูกต้อง
มีสองวิธีในการรวมเพจอื่นใน JSP: 1. ใช้ตัวบ่งชี้การรวม (<%@ includee file="test.jsp" %>) 2. ใช้ตัวบ่งชี้ jsp (
วิธีที่ 7: กำหนดวงจรชีวิตของ javabeans อย่างถูกต้อง
หนึ่งในคุณสมบัติอันทรงพลังของ JSP คือการรองรับ javabeans โดยการใช้แท็ก
<jsp:useBean id="name" scope="page|request|session|application" class=
"package.className" type="typeName">
</jsp:useBean>
แอ็ตทริบิวต์ขอบเขตบ่งชี้วงจรชีวิตของ bean นี้ วงจรชีวิตเริ่มต้นคือเพจ หากคุณเลือกวงจรชีวิตของ bean ไม่ถูกต้อง จะส่งผลต่อประสิทธิภาพของระบบ
ตัวอย่างเช่น หากคุณต้องการใช้ bean บางตัวในคำขอเดียว แต่คุณตั้งค่าวงจรชีวิตของ bean ให้เป็นเซสชัน เมื่อคำขอสิ้นสุดลง bean จะยังคงอยู่ในหน่วยความจำ เว้นแต่เซสชันหมดเวลาหรือผู้ใช้จะปิดเบราว์เซอร์ ซึ่งจะใช้หน่วยความจำจำนวนหนึ่งและเพิ่มเวิร์กโหลดของตัวรวบรวมขยะ JVM โดยไม่จำเป็น ดังนั้น การตั้งค่าวงจรชีวิตที่ถูกต้องสำหรับ bean และการทำความสะอาดโดยเร็วที่สุดหลังจากภารกิจสิ้นสุดลง จะช่วยปรับปรุงประสิทธิภาพของระบบ
วิธีการอื่นๆ
พยายามอย่าใช้ตัวดำเนินการ "+" ในการดำเนินการต่อสตริง: ในการเขียนโปรแกรม Java เรามักจะใช้ตัวดำเนินการ "+" เพื่อเชื่อมต่อหลายสตริง แต่คุณอาจไม่เคยคิดเลยว่ามันจะส่งผลต่อประสิทธิภาพของระบบจริง ๆ มีผลกระทบหรือไม่ เนื่องจากสตริงเป็นค่าคงที่ JVM จะสร้างอ็อบเจ็กต์ชั่วคราวบางส่วน ยิ่งคุณใช้ "+" มากเท่าไร ออบเจ็กต์ชั่วคราวก็จะถูกสร้างขึ้นมากขึ้นเท่านั้น ซึ่งจะมีผลกระทบต่อประสิทธิภาพของระบบด้วย วิธีแก้ไขคือใช้วัตถุ StringBuffer แทนตัวดำเนินการ "+"
หลีกเลี่ยงการใช้เมธอด System.out.println() เนื่องจาก System.out.println() เป็นการเรียกแบบซิงโครนัส กล่าวคือ เมื่อทำการเรียก การดำเนินการ I/O ของดิสก์ต้องรอจนเสร็จสิ้น ดังนั้น เราควรพยายามหลีกเลี่ยง ใช้มันโทร แต่เป็นเครื่องมือที่ขาดไม่ได้และสะดวกสบายเมื่อเราดีบักโปรแกรม เพื่อแก้ไขข้อขัดแย้งนี้ ฉันขอแนะนำให้คุณใช้เครื่องมือ Log4j ซึ่งสามารถอำนวยความสะดวกในการดีบักโดยไม่ต้องสร้างเมธอด System.out.println()
การแลกเปลี่ยนระหว่าง ServletOutputStream และ PrintWriter: การใช้ PrintWriter อาจมีค่าใช้จ่ายเล็กน้อย เนื่องจากจะแปลงเอาต์พุตดิบทั้งหมดเป็นสตรีมอักขระสำหรับเอาต์พุต ดังนั้นหากใช้เป็นเอาต์พุตเพจ ระบบจะต้องรับกระบวนการแปลง ไม่มีปัญหาหากคุณใช้ ServletOutputStream เป็นเอาต์พุตเพจ แต่เป็นเอาต์พุตในรูปแบบไบนารี ดังนั้นจึงต้องชั่งน้ำหนักข้อดีข้อเสียของทั้งสองอย่างในการใช้งานจริง
สรุป
วัตถุประสงค์ของบทความนี้คือเพื่อปรับปรุงประสิทธิภาพของแอปพลิเคชันของคุณอย่างมากผ่านเทคนิคการปรับแต่งบางอย่างสำหรับเซิร์ฟเล็ตและ JSP และปรับปรุงประสิทธิภาพของแอปพลิเคชัน J2EE ทั้งหมด ด้วยเทคนิคการปรับแต่งเหล่านี้ คุณจะพบว่าไม่ใช่แพลตฟอร์มทางเทคนิคบางอย่าง (เช่น ข้อพิพาทระหว่าง J2EE และ .NET) ที่กำหนดประสิทธิภาพของแอปพลิเคชันของคุณ สิ่งสำคัญคือคุณต้องมีความเข้าใจอย่างลึกซึ้งเกี่ยวกับแพลตฟอร์มนี้ เมื่อนั้นคุณจะสามารถเพิ่มประสิทธิภาพแอปพลิเคชันของคุณโดยพื้นฐานได้!