Web 應用效能直接影響用戶體驗與系統吞吐。本文提煉八大 Servlet/JSP 效能優化核心技術,涵蓋初始化快取、會話管理、壓縮傳輸、執行緒模型、靜態包含、作用域選擇、字符串處理、I/O 流選型,並補充現代框架層面優化建議。
init(ServletConfig) 僅執行一次,適合初始化:
DataSource、ConnectionFactory
public class ControllerServlet extends HttpServlet {
private DataSource dataSource;
private TemplateEngine templateEngine;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
Context ctx = new InitialContext();
dataSource = (DataSource) ctx.lookup("jdbc/appDS");
templateEngine = new TemplateEngine(config.getServletContext());
} catch (NamingException e) {
throw new ServletException("資源初始化失敗", e);
}
}
// 業務方法直接復用
protected DataSource getDataSource() { return dataSource; }
}
web.xml `jspServlet 參數 `modificationTestInterval=0`| 策略 | 實現 | 效能收益 |
|---|---|---|
| JSP 頁面不自動建立 Session | `<%@ page session="false" %>` | 避免大量匿名訪問產生無效 Session |
| 不存放大對象圖 | 僅存 ID/Token,詳情查 Redis/DB | 減少序列化開銷、Session 體積、複寫流量 |
| 及時銷毀 | `session.invalidate()` 登出/超時 | 釋放記憶體、減少 GC 壓力 |
| 設定合理超時 | `web.xml` ` | 平衡用戶體驗與資源佔用 |
| 無狀態化趨勢 | JWT Token + Redis 分散式 Session | 支援水平擴展、消除 Session 親和性 |
// Servlet 過濾器統一處理 (推薦)
public class GzipFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String acceptEncoding = request.getHeader("Accept-Encoding");
if (acceptEncoding != null && acceptEncoding.contains("gzip")) {
response.setHeader("Content-Encoding", "gzip");
try (GZIPResponseWrapper wrapper = new GZIPResponseWrapper(response)) {
chain.doFilter(request, wrapper);
wrapper.finish(); // 關閉流觸發壓縮
}
} else {
chain.doFilter(request, response);
}
}
}
// 響應包裝器
class GZIPResponseWrapper extends HttpServletResponseWrapper {
private GZIPOutputStream gzipOut;
// 重寫 getOutputStream()/getWriter() 返回壓縮流
}
現代做法:Nginx/Apache 反向代理層開啟 `gzip on;`、Spring Boot `server.compression.enabled=true`、CDN 邊緣壓縮。
ThreadLocal、Atomic*、ConcurrentHashMap)| 機制 | 語法 | 階段 | 適用場景 |
|---|---|---|---|
| 靜態包含 (指令) | `<%@ include file="header.jsp" %>` | 編譯期合併為單一 Servlet | 極少變動的佈局片段 (header/footer) |
| 動態包含 (動作) | ` | 請求期獨立編譯、合併輸出 | 頻繁變動、條件化、參數化片段 |
效能:靜態包含零運行期開銷;動態包含每請求額外 `include()` 呼叫開銷。
// 請求級,最常用
// 用戶級,購物車等
// 全域單例
// 頁面級,極少用
原則:最小作用域原則。請求級數據用 `request`,避免 `session` 佔用記憶體導致 GC 壓力與叢集複寫開銷。
{}` 避免字符串拼接,`isDebugEnabled()` 守衛,異步 Appender (Log4j2 Async/Logback Async)Servlet/JSP 優化核心在於:減少物件創建、降低鎖競爭、壓縮網路傳輸、精準控制生命週期、遷移至現代架構。傳統優化手段在 Spring Boot/Spring Cloud/微服務體系下仍具指導意義,但更應關注:分散式追蹤、熔斷限流、自動擴縮容、可觀測性三大支柱 (Metrics/Logs/Traces)。