一、Semaphore(詳見JDK-API)
一個計數信號量。從概念上講,信號量維護了一個許可集。如有必要,在許可可用前會阻塞每一個 acquire(),然後再獲取該許可。每個 release() 添加一個許可,從而可能釋放一個正在阻塞的獲取者。但是,不使用實際的許可對象,Semaphore 只對可用許可的號碼進行計數,並採取相應的行動。
二、應用場景
在semamphore信號量非常適合高併發訪問,在新系統上線之前,要對系統的訪問量進行評估。當然這個值肯定不是隨隨便便就想出來的,是經過以往的經驗,數據,歷年的訪問量,已經推廣力度進行一個合理的評估,當然評估標準不能太大也不能太小,太大的話,投入的資源達不到實際的效果,純粹浪費資源,太小的話,某個時間點一個高峯值的訪問量上來可以直接壓垮系統。
PV(page view)網站的總訪問量。頁面的瀏覽量或者點擊量,用戶每刷新一一次,或者點擊一次,就會被記錄。
UV(unique visitor)獨立訪客。訪問網站的一臺電腦客戶端爲一個訪客,一般來講,時間從00到24點之內相同的ip客戶端只記錄一次。
UV(query per second)即每秒查詢數。 qps很大程度上代表了系統業務上的繁忙程度,每次請求的背後,可能應對着多次磁盤I/O , 多次網絡請求,多個CPU時間片等。我們通過qps非常客觀的瞭解當前業務情況。一旦當前的qps超過了所設定的預警閥值,可以考慮增加機器對集羣擴容,以免壓力過大導致宕機,可以根據前期的壓力測試得到估值,在結合後期的綜合運維的情況,估算出閥值。
RT(response time)請求的響應時間。 這個指標非常的關鍵,直接說明前端用戶的體驗,因此任何系統設計師都想降低RT時間
當然還涉及cpu,內存,網絡,磁盤等情況,如select,delete,update等數據庫層面的東西
容量評估。一般來說通過開發,運維,測試,以及業務相關人等。綜合出系統的一系列閥值,然後我們根據相關閥值如qps,rt等,對系統進行有效的變更。
一般來講,進行多次壓力測試後,可以對系統進行峯值進行評估,採用所謂80/20原則,即80%的訪問請求,將在20%的訪問時間內達到,這樣我們可以根據系統對應的pv計算出峯值qps
峯值qps=(總pv * 80%)/ ( 60 * 60 * 24 * 20% )
然後再將總的峯值qps除以單臺機器所能承受的最高的qps值,就是所需要機器的數量.機器數量=總的峯值qps / 壓測得出的單機極限qps
當然不排除系統在上線前進行大規模的促銷活動,或者雙十一,雙十二熱點事件,遭受到DDos攻擊等情況。系統的開發和運維人員急需要了解當前系統的運行狀態和負載情況,一般都會有後臺系統去維護。
semaphore可以控制系統的流:拿到信號量的線程可以進入,否則就等待。通過acquire()和release()獲得或者釋放許可
public class UseSemaphore {
public static void main(String[] args) {
// 線程池
ExecutorService exec = Executors.newCachedThreadPool();
// 只能5個線程同時訪問
final Semaphore semp = new Semaphore(5);
// 模擬20個客戶端訪問
for (int index = 0; index < 20; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 獲取許可
semp.acquire();
System.out.println("Accessing: " + NO);
//模擬實際業務邏輯
Thread.sleep((long) (Math.random() * 10000));
// 訪問完後,釋放
semp.release();
} catch (InterruptedException e) {
}
}
};
exec.execute(run);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println(semp.getQueueLength());
// 退出線程池
exec.shutdown();
}
}