負(fù)載均衡

話不多說前言

負(fù)載均衡 簡單來說就像分班考試,入學(xué)人數(shù)太多,部分同學(xué)去重點(diǎn)班A,部分去奧數(shù)班B,部分去少年班C,作者本人去的是普通基礎(chǔ)班,其實(shí)更適合終極一班

ELB

Elastic Load Balancing(ELB)以亞馬遜提供的ELB為例,
主要提供三種負(fù)載均衡器:應(yīng)用負(fù)載均衡(ALB),網(wǎng)絡(luò)負(fù)載均衡,經(jīng)典負(fù)載均衡。

幾種負(fù)載均衡器比較

  • 經(jīng)典負(fù)載均衡器

    • 請求級別和連接級別
    • 可在多個 Amazon EC2 實(shí)例之間提供基本的負(fù)載均衡。Classic Load Balancer 適用于在 EC2-Classic 網(wǎng)絡(luò)內(nèi)構(gòu)建的應(yīng)用程序
  • 網(wǎng)絡(luò)負(fù)載均衡

    • 網(wǎng)絡(luò)負(fù)載均衡器運(yùn)行于連接級別(第 4 層),
    • 可將流量路由至 Amazon Virtual Private Cloud (Amazon VPC) 內(nèi)的不同目標(biāo),每秒能夠處理數(shù)百萬請求,同時能保持超低延遲。
    • 網(wǎng)絡(luò)負(fù)載均衡器還針對處理突發(fā)和不穩(wěn)定的流量模式進(jìn)行了優(yōu)化。
  • 應(yīng)用負(fù)載均衡器件

    • 最適合 HTTP 和 HTTPS 流量的負(fù)載均衡,
    • 面向交付包括微服務(wù)和容器在內(nèi)的現(xiàn)代應(yīng)用程序架構(gòu),提供高級請求路由功能。

負(fù)載均衡算法和實(shí)現(xiàn)

  • 輪詢法
    • 所有請求按照順序分發(fā),不常用,比如分班,按報名順序分班
// 加鎖,保證線程安全
  public String robin() {
    synchronized (serverIndex) {
      if (serverIndex >= serverList.size()) {
        serverIndex = -1;
      }
      return serverList.get(++serverIndex);
    }
  }
  • 加權(quán)輪詢

    • 輪詢基礎(chǔ)上加權(quán)重,好一點(diǎn)的機(jī)器權(quán)重大,也不常用了,以分班為例,教師大的分過去學(xué)生多
  • 隨機(jī)/加權(quán)隨機(jī)

    • 隨機(jī)分配,次數(shù)多的時候接近于輪詢,以分班為例,就是抽簽分班。
public String random() {
    int randomIndex = new Random().nextInt(serverList.size());
    return serverList.get(randomIndex);
  }
  • 最小連接

    • 那個服務(wù)器連接少,就分流到那個機(jī)器,在機(jī)器性能不是均等的時候,這個方法容易把請求分到性能很差的機(jī)器上,也不好
    • 以分班為例,就是報名人數(shù)少的班級,優(yōu)先調(diào)劑。
  • 源頭地址hash

    • 教材案例
  public String hash(String remoteIp) {
    Integer hashCode = remoteIp.hashCode();
    serverIndex = hashCode % serverList.size();
    return serverList.get(serverIndex);
  }

  • 一致性hash
    • 便于擴(kuò)展不影響大部分原有節(jié)點(diǎn)
    • 為了均衡加上了虛擬節(jié)點(diǎn)
public class ConsistHash {

  private String[] servers;

  // 真實(shí)結(jié)點(diǎn)列表
  private static List<String> realNodes = new LinkedList<>();

  // 虛擬節(jié)點(diǎn),key表示虛擬節(jié)點(diǎn)的hash值,value表示虛擬節(jié)點(diǎn)的名稱
  private static SortedMap<Integer, String> virtualNodes =
      new TreeMap<>();

  
  // 虛擬節(jié)點(diǎn)數(shù)目
  private static final int VIRTUAL_NODES = 150;

  public ConsistHash(String[] servers) {
    this.servers = servers;
  }

  private void getNode() {
    // 原始的服務(wù)器添加到真實(shí)結(jié)點(diǎn)列表中
    Collections.addAll(realNodes, servers);

    // 添加虛擬節(jié)點(diǎn)
    for (String str : realNodes) {
      for (int i = 0; i < VIRTUAL_NODES; i++) {
        String virtualNodeName = str + "&&VN" + String.valueOf(i);
        int hash = getHash(virtualNodeName);
        virtualNodes.put(hash, virtualNodeName);
      }
    }
  }

  // 使用FNV1_32_HASH算法計(jì)算服務(wù)器的Hash值,這里不使用重寫hashCode的方法,最終效果沒區(qū)別
  private static int getHash(String str) {
    final int p = 16777619;
    int hash = (int) 2166136261L;
    for (int i = 0; i < str.length(); i++) {
      hash = (hash ^ str.charAt(i)) * p;
    }
    hash += hash << 13;
    hash ^= hash >> 7;
    hash += hash << 3;
    hash ^= hash >> 17;
    hash += hash << 5;
    
    if (hash < 0) {
      hash = Math.abs(hash);
    }
    return hash;
  }

  // 得到應(yīng)當(dāng)路由到的結(jié)點(diǎn)
  public static String getServer(String node) {
    // 得到帶路由的結(jié)點(diǎn)的Hash值
    int hash = getHash(node);
    // 得到大于該Hash值的所有Map
    SortedMap<Integer, String> subMap =
        virtualNodes.tailMap(hash);
    // 第一個Key就是順時針過去離node最近的那個結(jié)點(diǎn)
    Integer i = subMap.firstKey();
    // 返回對應(yīng)的虛擬節(jié)點(diǎn)名稱,這里字符串稍微截取一下
    String virtualNode = subMap.get(i);
    return virtualNode.substring(0, virtualNode.indexOf("&&"));
  }
}

負(fù)載均衡系統(tǒng)設(shè)計(jì)需要考慮的其他因素

  • 實(shí)例健康檢查(這個通常配合注冊中心實(shí)現(xiàn))
  • 機(jī)器自動擴(kuò)展(用一致性負(fù)載均衡在擴(kuò)容時影響機(jī)器少)
  • 監(jiān)控服務(wù),根據(jù)cpu使用量大小和流量大小,處理時長自動完成添加或者縮減實(shí)例服務(wù)
  • 應(yīng)用負(fù)載均衡可以按照功能分發(fā)到對應(yīng)的集群,比如登錄給登錄集群,支付給支付集群

這一篇就到這里了,
源碼github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 摘要:面對大量用戶訪問、高并發(fā)請求,海量數(shù)據(jù),可以使用高性能的服務(wù)器、大型數(shù)據(jù)庫,存儲設(shè)備,高性能Web服務(wù)器,采...
    layjoy閱讀 14,025評論 3 93
  • 《老男孩Linux運(yùn)維》Nginx Documentation 集群簡介 集群就是指一組(若干)相互獨(dú)立的計(jì)算機(jī),...
    Zhang21閱讀 3,514評論 0 51
  • “他們倆陪著我長大,現(xiàn)在,我陪著他倆變老。” 生長在一個普通的家庭里,所幸父母皆是懂得生活之人,但凡有出行的時間和...
    力小妞閱讀 451評論 0 1
  • 一顆頑強(qiáng)的生命,需要生長,希望被全世界的看見,那些看見生命力的關(guān)系,親情、愛情,都在默默滋潤著著生命,沒有看見這股...
    海水冰山閱讀 310評論 0 0
  • 很多家長都會有這樣的煩惱:孩子的欲望不能被滿足的時候,他就會用哭鬧來要挾家長。而且,這一哭,就能哭上半天,撕心裂肺...
    艾米本人閱讀 385評論 0 5

友情鏈接更多精彩內(nèi)容