Article-No.05 大型網站系統與Java中間件實踐

一、阿姆達爾定律:S(N) = 1/(1-P) + P/Njava

P:程序中並行部分的程序在單核上執行時間的佔比web

N:處理器的個數(總核心數)算法

S(N):程序在N個處理器(總核心數)相對於單個處理器(單核)中的速度提高比數據庫

總結:這個公式告訴咱們,在程序中可並行代碼的比例決定你增長處理器所能帶來的速度的提高的上限緩存

二、ConcurrentHashMap:支持併發效率更高的Map安全

    若是隻調用get()方法或者put()方法,ConcurrentHashMap是線程安全的,可是若是你調用get()方法後,又調用put()方法,若是有另一個線程在當前線程調用put()返回以前調用,極可能會把以前的操做覆蓋掉,不少狀況下一個業務會涉及容器的多個操做,即複合操做,併發執行時,線程安全的容器只能保證自身的數據不被破壞,但沒法保證業務的行爲是否正確。服務器

private final Map<String, Long> wordCounts = new ConcurrentHashMap<>();
/**
 *若是多個線程併發調用這個increase()方法,increase()的實現就是錯誤的,由於多個線程用相同的word調用時,極可能會覆蓋相互的結果,形成記錄的次數比實際出現的次數少。
*/
public long increase(String word) {
    Long oldValue = wordCounts.get(word);
    Long newValue = (oldValue == null) ? 1L : oldValue + 1;
    wordCounts.put(word, newValue);
    return newValue;
}

//putIfAbsent方法,若是key/value存在,則返回value,若是不存在返回null;replace若是新值和舊值相同,則返回false,反之則返回true
public long increase(String word) {
    Long oldValue, newValue;
    while (true) {
        oldValue = wordCounts.get(word);
        if (oldValue == null) {
            // Add the word firstly, initial the value as 1
            newValue = 1L;
            if (wordCounts.putIfAbsent(word, newValue) == null) {
                break;
            }
        } else {
            newValue = oldValue + 1;
            if (wordCounts.replace(word, oldValue, newValue)) {
                break;
            }
        }
    }
    return newValue;
}

//改進
public long increase(String word) {
    AtomicLong number = wordCounts.get(word);
    if (number == null) {
        AtomicLong newNumber = new AtomicLong(0);
        number = wordCounts.putIfAbsent(word, newNumber);
        if (number == null) {
            number = newNumber;
        }
    }
    return number.incrementAndGet();
}

三、避免死鎖的方式:原子性的獲取須要的多個鎖或注意調整對多個鎖的獲取順序cookie

四、服務器負載均衡的幾種方式session

    1)硬件負載均衡:中間代理轉發併發

    2)LVS/Nginx軟件負載均衡:中間代理轉發

    3)名稱服務:請求服務先訪問名稱服務器,獲取處理服務器ip或域名列表並返回,請求服務器按照必定的規則進行負載選擇請求的服務器地址

    4)規則服務:請求服務訪問規則服務器,獲取規則算法並返回,請求服務器按照規則計算進行負載

    5)Master-Worker服務器

五、解決應用服務器變爲集羣后的Session問題

    web服務器是咱們天天要去吃飯的飯店,session會話數據是咱們吃飯用的碗筷,目標是保證每次吃飯都用本身的碗筷

    1)Session Sticky:保證同一個會話的請求都在同一個web服務器上處理,須要在負載均衡上作選擇,能夠進行一致性hash實現。把碗筷放在某一家飯店裏,每次都去那家飯店吃飯。

    2)Session Replication(session複製):多臺服務器之間實現session的同步操做。每一家飯店都放了一份本身的碗筷,這樣不管去哪家均可以用本身的碗筷。

    3)Session集中存儲:session數據集中存儲在一個session集羣中,全部對session讀寫操做都在在這個session集羣中處理。將碗筷統一的放在一塊兒,每次吃飯都先去那把碗筷拿着,吃飯了再放回去。

    4)Cookie Based:將session數據保存在cookie中,每次發生請求的時候coookie中都帶有session的數據,能夠對session進行加密處理。每次都把本身的碗筷帶在身上,這樣每次去任何一家飯店吃飯都用本身的碗筷。

六、數據庫瓶頸解決

    1)主從式讀寫分離

    2)站內搜索引擎,至關於一個讀庫

    3)緩存:數據緩存、頁面緩存

    4)分佈式頁面系統、分佈式存儲系統、分佈式數據庫系統

    5)數據庫垂直拆分(專庫專用、按照頁面不一樣表分在不一樣數據庫中),水平拆分(單張表記錄達到臨界值,將一張表拆分紅多張表放在不一樣數據庫中)

七、

相關文章
相關標籤/搜索