面對「雙十一」級別的流量洪峰,Java 系統如何支撐十萬級 QPS?本文從數據庫分庫分表、HTML 靜態化、緩存架構、負載均衡、存儲分離、圖片服務器、集群方案六大維度,提煉出十大經過生產環境驗證的優化策略,附帶架構圖解與代碼片段,直擊性能瓶頸核心。
鐵律:禁用 auto_increment,ID 由統一發號器 (Snowflake/Leaf) 生成;禁用持久連接,改用連接池 (HikariCP/Druid);建立 MySQL 監控體系 (Prometheus + Grafana),30+ 實例下人工運維不可行。
核心公式:動態請求鏈路 HTTP → Web → Servlet → 業務邏輯 → DB → JSP → 響應 → 靜態化後 HTTP → Web → Servlet → 靜態 HTML → 響應,省去 DB、模板引擎、業務邏輯三大耗時環節。
public class CreateStaticHTMLPage {
public void createStaticHTMLPage(HttpServletRequest request, HttpServletResponse response,
ServletContext servletContext, String fileName, String fileFullPath, String jspPath)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
RequestDispatcher rd = servletContext.getRequestDispatcher(jspPath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ServletOutputStream sos = new ServletOutputStream() {
public void write(byte[] b, int off, int len) { baos.write(b, off, len); }
public void write(int b) { baos.write(b); }
};
PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, "UTF-8"));
HttpServletResponse wrapped = new HttpServletResponseWrapper(response) {
public ServletOutputStream getOutputStream() { return sos; }
public PrintWriter getWriter() { return pw; }
};
rd.include(request, wrapped); // 執行 JSP 渲染,結果寫入 baos
pw.flush();
try (FileOutputStream fos = new FileOutputStream(fileFullPath)) {
baos.writeTo(fos);
}
response.sendRedirect(fileName); // 重定向到靜態文件
}
}
適用場景:內容更新頻率低、訪問量極大的頁面 (商品詳情、新聞詳情、論壇帖子)。更新機制採用「發布時生成」或「定時任務增量生成」。
swapoff -a),防止 GC 時觸發 Swap 導致長尾延遲。架構:LVS → Lighttpd (集群) → Squid (緩存層) → Lighttpd (靜態文件服務器)
Lighttpd + PHP-FPM,性能提升 3-5 倍。| 類型 | 方案 | 核心技術 |
|---|---|---|
| 小文件 (圖片/文檔) | 分布式存儲 | Lighttpd 目錄哈希分佈 / RedHat GFS (應用透明但成本高) / 自研 GFS 風格 (參考 Google GFS 論文) |
| 大文件 (索引/日志/視頻) | 分布式文件系統 | Nutch/Hadoop HDFS (現獨立為 Hadoop 子項目) |
核心難點:文件副本策略 (3 副本)、故障自動恢復、一致性 Hash 避免熱點。
痛點:圖片佔用 80%+ 帶寬與連接數,拖垮應用服務器。
<distributable/>),域名 res1.xxx.com, res2.xxx.com。httpd.conf 配置反向代理 + 負載均衡:<VirtualHost *:80>
ProxyPass /fileupload.html balancer://rescluster/fileupload lbmethod=byrequests stickysession=JSESSIONID
<Proxy balancer://rescluster/>
BalancerMember ajp://res1.xxx.com:8009 route=tomcat1 loadfactor=100
BalancerMember ajp://res2.xxx.com:8009 route=tomcat2 loadfactor=100
</Proxy>
</VirtualHost>
https://res1.xxx.com/upload/2024/xxx.jpg。BalancerMember,零代碼變更。| 框架 | 定位 | 推薦指數 | 備註 |
|---|---|---|---|
| Redis (Lettuce/Redisson) | 分布式緩存/分布式鎖/排行榜 | ⭐⭐⭐⭐⭐ | 事實標準,功能最全 |
| Caffeine | 本地緩存 (近緩存) | ⭐⭐⭐⭐⭐ | Guava Cache 繼任者,性能極致 |
| Ehcache 3.x | Hibernate 二級緩存/堆外內存 | ⭐⭐⭐ | JSR-107 標準實現 |
| Hazelcast / Infinispan | 分布式內存網格/計算 | ⭐⭐⭐⭐ | 支援數據網格、流計算 |
| Memcached | 純 K-V 高併發緩存 | ⭐⭐⭐ | 無持久化、無集群原生支援 |