AJAX 模式將傳統「表單提交→頁面跳轉」轉變為「豐富客戶端持續異步交互」。用戶操作(點擊、輸入、懸停)頻繁觸發請求,典型 AJAX 應用容量規劃是傳統 Web 應用的 3-4 倍。每個 HTTP 請求佔用一個執行執行緒,大量短期輪詢請求會衝擊伺服器執行緒池,導致資源耗盡。
WebLogic 自 6.1 版本提供 FutureResponseServlet,允許開發者在獨立執行緒處理回應,主執行緒立即釋放,實現真正的伺服器端異步推送,無需客戶端輪詢、無需持久佔用執行緒。9.x 版本正式公開此類別供開發使用。
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Stack;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import weblogic.servlet.FutureResponseServlet;
import weblogic.servlet.FutureServletResponse;
public class AsynchronousServerResponseServlet extends FutureResponseServlet {
private final Notifier notifier;
public AsynchronousServerResponseServlet() {
this.notifier = new Notifier();
this.notifier.start();
}
@Override
public void service(HttpServletRequest request, FutureServletResponse response)
throws IOException, ServletException {
// 立即註冊客戶端連接到通知器,主執行緒立即返回
notifier.poll(request, response);
}
// 內部通知器執行緒:單執行緒管理所有客戶端連接
class Notifier extends Thread {
private final Stack<Client> clients = new Stack<>();
void poll(HttpServletRequest request, FutureServletResponse response) {
clients.push(new Client(request, response));
}
@Override
public void run() {
while (!clients.empty()) {
Client client = null;
try {
client = clients.pop();
PrintWriter pw = client.response.getWriter();
for (int j = 0; j < 10; j++) {
pw.println("Time is: " + new Date());
pw.flush(); // 關鍵:立即推送到客戶端
}
pw.close();
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
if (client != null) client.response.send(); // 正式提交回應
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
}
// 封裝客戶端請求/回應
static class Client {
final HttpServletRequest request;
final FutureServletResponse response;
Client(HttpServletRequest request, FutureServletResponse response) {
this.request = request;
this.response = response;
}
}
}
| 組件 | 角色 | 關鍵點 |
|---|---|---|
| FutureResponseServlet | 異步 Servlet 基類 | 覆寫 service(HttpServletRequest, FutureServletResponse) |
| FutureServletResponse | 異步回應持有者 | getWriter() 獲取輸出流,send() 正式提交回應 |
| Notifier 執行緒 | 單執行緒事件分發器 | 管理所有客戶端連接,批量推送事件 |
| Client 封裝類 | 請求/回應綁定 | 維持長連接狀態 |
flush() 即時傳輸,send() 結束回應| 場景 | 推薦方案 |
|---|---|
| WebLogic 環境、長輪詢/Comet | FutureResponseServlet(本文方案) |
| Servlet 3.0+ 容器(Tomcat 7+, Jetty 9+) | 標準 AsyncContext / @WebServlet(asyncSupported=true) |
| Spring 生態 | Spring MVC DeferredResult / Callable / WebFlux |
| 高頻即時通訊 | WebSocket (JSR 356 / Spring WebSocket) |
| 跨語言、微服務 | Server-Sent Events (SSE) / gRPC Streaming |
FutureResponseServlet 是處理長時間任務、實現伺服器端異步推送的利器,核心在於「主執行緒快速釋放,業務執行緒異步完成回應」。雖然現代 Servlet 3.0+ 標準化了異步 API,但理解此經典模式有助於掌握異步 Web 架構的本質:執行緒解耦、連接複用、事件驅動。