首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

高併發下 JSP 文章點擊計數器:記憶體緩存 + 定時批次寫入資料庫

     編輯:關於JSP

設計思路

  • 每次點擊不直接更新資料庫,避免高併發下連線風暴。
  • 計數請求寫入記憶體緩存 (LinkedList),極低延遲。
  • 獨立執行緒/定時任務批次寫入資料庫(每 60 秒或累積 N 筆)。

核心類別

CountBean.java (資料載體)

package com.tot.count;
public class CountBean {
    private String countType; private int countId;
    // getter/setter 略
}

CountCache.java (記憶體緩存)

package com.tot.count;
import java.util.LinkedList;
public class CountCache {
    public static LinkedList list = new LinkedList<>();
    public static void add(CountBean cb) { if (cb!=null) list.add(cb); }
}

CountControl.java (定時批次寫入)

package com.tot.count;
import java.sql.*;
public class CountControl {
    private static long lastExecuteTime = 0;
    private static long executeSep = 60000; // 60秒

    public synchronized void executeUpdate() {
        Connection conn = null; PreparedStatement ps = null;
        try {
            conn = DBUtils.getConnection(); // 需自行實作連線池
            conn.setAutoCommit(false);
            ps = conn.prepareStatement("UPDATE t_news SET hits=hits+1 WHERE id=?");
            while (!CountCache.list.isEmpty()) {
                CountBean cb = CountCache.list.removeFirst();
                ps.setInt(1, cb.getCountId());
                ps.addBatch(); // 批次處理
            }
            ps.executeBatch();
            conn.commit();
        } catch (Exception e) { e.printStackTrace(); }
        finally { /* 關閉資源 */ }
    }

    public void run() {
        if (System.currentTimeMillis() - lastExecuteTime > executeSep) {
            lastExecuteTime = System.currentTimeMillis();
            executeUpdate();
        }
    }
}

JSP 調用範例

<%
CountBean cb = new CountBean();
cb.setCountId(Integer.parseInt(request.getParameter("cid")));
CountCache.add(cb);
new CountControl().run(); // 每次請求檢查是否到批次時間
%>

優化與生產化建議

  • 批次大小觸發:結合時間與筆數雙重條件(如 60 秒或 1000 筆)。
  • ScheduledExecutorService:替代 JSP 呼叫 run(),由容器啟動定時任務。
  • 持久化緩存:防止重啟丟失,可定期序列化至磁碟或使用 Redis。
  • 分庫分表:計數表獨立庫,減少主業務鎖爭用。
  • 原子操作:資料庫層面 hits=hits+1 已是原子,無需應用層鎖。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved