J2EE應用上線後常面臨響應慢、吞吐低、併發崩潰。本文總結八條經實戰驗證的性能優化鐵律,涵蓋開發期編碼習慣與運行期配置調優,助你構建高性能、高彈性的Servlet/JSP應用。
init()中緩存靜態資源與昂貴對象Servlet生命周期:init() → service() × N → destroy()。init()僅執行一次,適合:
DataSource並緩存實例變量,避免每次SQL請求重複ctx.lookup()(極其昂貴)。public class ControllerServlet extends HttpServlet {
private DataSource dataSource;
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
Context ctx = new InitialContext();
dataSource = (DataSource) ctx.lookup("jdbc/myDS"); // 一次JNDI查找
} catch (NamingException e) { throw new ServletException(e); }
}
public DataSource getDataSource() { return dataSource; } // service()中復用
}
開發期auto-reload便利調試,但運行期會:
LinkageError、ClassCastException等詭異錯誤。生產部署必關:TomcatContext.reloadable="false"、WebLogic<servlet-reload-check-secs>-1</servlet-reload-check-secs>。
Session是雙刃劍,誤用拖垮性能:
<%@ page session="false" %>,避免創建無用Session對象。session.invalidate()。web.xml<session-timeout>15</session-timeout>(分鐘),減少殭屍Session佔用內存。jspc(Mavenjspc-maven-plugin、Antjasperc)預編譯JSP為Servlet類,部署包含*.class,啟動無編譯延遲、避免首訪慢、源碼不泄露。web.xml設置<init-param><param-name>development</param-name><param-value>false</param-value></init-param>關閉JSP調試信息生成。Cache-Control: max-age=31536000, immutable,文件名含Hash指紋。Cache-Control: no-store, must-revalidate或按需ETag/Last-Modified協商緩存。maximumPoolSize匹配CPU核心數×2-4。explain分析、加索引、避免SELECT *、分頁優化(游標/延遲關聯)。pageBuffer設置16kb-64kb(<%@ page buffer="32kb" %>),減少flush()系統調用。server.xml<Connector compression="on" compressableMimeType="text/html,text/xml,text/css,application/javascript" />。request.startAsync()釋放容器線程,異步線程池處理耗時業務(導出、報表、推送),完成後asyncContext.complete()。202 Accepted。| 階段 | 動作 | 工具/配置 |
|---|---|---|
| 開發 | init緩存、禁用自動重載、Session精簡、預編譯JSP | 代碼審查、SonarQube規則 |
| 測試 | 負載測試(JMeter)、Profiling(JProfiler/Async Profiler)、慢SQL分析 | 基準線:P99 < 200ms、錯誤率 < 0.1% |
| 運行 | 連接池監控、GC日誌分析、APM全鏈路追蹤 | Prometheus+Grafana、SkyWalking |
性能優化無銀彈,只有持續測量、找瓶頸、針對性優化、驗證效果的工程閉環。八大鐵律是起點,不是終點。