乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      多種負(fù)載均衡算法及其 Java 代碼實(shí)現(xiàn)

       LZS2851 2017-02-13


      首先給大家介紹下什么是負(fù)載均衡(來(lái)自百科)

      負(fù)載均衡建立在現(xiàn)有網(wǎng)絡(luò)結(jié)構(gòu)之上,它提供了一種廉價(jià)有效透明的方法擴(kuò)展 網(wǎng)絡(luò)設(shè)備和 服務(wù)器的帶寬、增加 吞吐量、加強(qiáng)網(wǎng)絡(luò)數(shù)據(jù)處理能力、提高網(wǎng)絡(luò)的靈活性和可用性。

      負(fù)載均衡,英文名稱為L(zhǎng)oad Balance,其意思就是分?jǐn)偟蕉鄠€(gè)操作單元上進(jìn)行執(zhí)行,例如Web 服務(wù)器、 FTP服務(wù)器、 企業(yè)關(guān)鍵應(yīng)用服務(wù)器和其它關(guān)鍵任務(wù)服務(wù)器等,從而共同完成工作任務(wù)。

      本文講述的是"將外部發(fā)送來(lái)的請(qǐng)求均勻分配到對(duì)稱結(jié)構(gòu)中的某一臺(tái)服務(wù)器上"的各種算法,并以Java代碼演示每種算法的具體實(shí)現(xiàn),OK,下面進(jìn)入正題,在進(jìn)入正題前,先寫(xiě)一個(gè)類來(lái)模擬Ip列表:

      import java.util.HashMap;/**
       * @author ashang.peng@aliyun.com
       * @date 二月 07, 2017
       */public class IpMap   {
          // 待路由的Ip列表,Key代表Ip,Value代表該Ip的權(quán)重    public static HashMap<String, Integer> serverWeightMap =
                  new HashMap<String, Integer>();
      
          static    {
              serverWeightMap.put("192.168.1.100", 1);
              serverWeightMap.put("192.168.1.101", 1);
              // 權(quán)重為4        serverWeightMap.put("192.168.1.102", 4);
              serverWeightMap.put("192.168.1.103", 1);
              serverWeightMap.put("192.168.1.104", 1);
              // 權(quán)重為3        serverWeightMap.put("192.168.1.105", 3);
              serverWeightMap.put("192.168.1.106", 1);
              // 權(quán)重為2        serverWeightMap.put("192.168.1.107", 2);
              serverWeightMap.put("192.168.1.108", 1);
              serverWeightMap.put("192.168.1.109", 1);
              serverWeightMap.put("192.168.1.110", 1);
          }
      }

      輪詢(Round Robin)法

      輪詢調(diào)度算法的原理是每一次把來(lái)自用戶的請(qǐng)求輪流分配給內(nèi)部中的服務(wù)器,從1開(kāi)始,直到N(內(nèi)部服務(wù)器個(gè)數(shù)),然后重新開(kāi)始循環(huán)。算法的優(yōu)點(diǎn)是其簡(jiǎn)潔性,它無(wú)需記錄當(dāng)前所有連接的狀態(tài),所以它是一種無(wú)狀態(tài)調(diào)度。

      其代碼實(shí)現(xiàn)大致如下:

      import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Set;/**
       * @author ashang.peng@aliyun.com
       * @date 二月 07, 2017
       */class RoundRobin   {
          private static Integer pos = 0;
      
          public static String getServer()    {
              // 重建一個(gè)Map,避免服務(wù)器的上下線導(dǎo)致的并發(fā)問(wèn)題        Map<String, Integer> serverMap =
                      new HashMap<String, Integer>();
              serverMap.putAll(IpMap.serverWeightMap);
      
              // 取得Ip地址List        Set<String> keySet = serverMap.keySet();
              ArrayList<String> keyList = new ArrayList<String>();
              keyList.addAll(keySet);
      
              String server = null;
              synchronized (pos)
              {
                  if (pos > keySet.size())
                      pos = 0;
                  server = keyList.get(pos);
                  pos ++;
              }
      
              return server;
          }
      }

      由于serverWeightMap中的地址列表是動(dòng)態(tài)的,隨時(shí)可能有機(jī)器上線、下線或者宕機(jī),因此為了避免可能出現(xiàn)的并發(fā)問(wèn)題,方法內(nèi)部要新建局部變量serverMap,現(xiàn)將serverMap中的內(nèi)容復(fù)制到線程本地,以避免被多個(gè)線程修改。這樣可能會(huì)引入新的問(wèn)題,復(fù)制以后serverWeightMap的修改無(wú)法反映給serverMap,也就是說(shuō)這一輪選擇服務(wù)器的過(guò)程中,新增服務(wù)器或者下線服務(wù)器,負(fù)載均衡算法將無(wú)法獲知。新增無(wú)所謂,如果有服務(wù)器下線或者宕機(jī),那么可能會(huì)訪問(wèn)到不存在的地址。因此,服務(wù)調(diào)用端需要有相應(yīng)的容錯(cuò)處理,比如重新發(fā)起一次server選擇并調(diào)用。

      對(duì)于當(dāng)前輪詢的位置變量pos,為了保證服務(wù)器選擇的順序性,需要在操作時(shí)對(duì)其加鎖,使得同一時(shí)刻只能有一個(gè)線程可以修改pos的值,否則當(dāng)pos變量被并發(fā)修改,則無(wú)法保證服務(wù)器選擇的順序性,甚至有可能導(dǎo)致keyList數(shù)組越界。

      輪詢法的優(yōu)點(diǎn)在于:試圖做到請(qǐng)求轉(zhuǎn)移的絕對(duì)均衡。

      輪詢法的缺點(diǎn)在于:為了做到請(qǐng)求轉(zhuǎn)移的絕對(duì)均衡,必須付出相當(dāng)大的代價(jià),因?yàn)闉榱吮WCpos變量修改的互斥性,需要引入重量級(jí)的悲觀鎖synchronized,這將會(huì)導(dǎo)致該段輪詢代碼的并發(fā)吞吐量發(fā)生明顯的下降

      隨機(jī)(Random)法

      通過(guò)系統(tǒng)的隨機(jī)算法,根據(jù)后端服務(wù)器的列表大小值來(lái)隨機(jī)選取其中的一臺(tái)服務(wù)器進(jìn)行訪問(wèn)。由概率統(tǒng)計(jì)理論可以得知,隨著客戶端調(diào)用服務(wù)端的次數(shù)增多。

      其實(shí)際效果越來(lái)越接近于平均分配調(diào)用量到后端的每一臺(tái)服務(wù)器,也就是輪詢的結(jié)果。

      隨機(jī)法的代碼實(shí)現(xiàn)大致如下:

      import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Set;/**
       * @author ashang.peng@aliyun.com
       * @date 二月 07, 2017
       */ class Random   {
          public static String getServer()    {
              // 重建一個(gè)Map,避免服務(wù)器的上下線導(dǎo)致的并發(fā)問(wèn)題           Map<String, Integer> serverMap =
                      new HashMap<String, Integer>();
              serverMap.putAll(IpMap.serverWeightMap);
      
              // 取得Ip地址List           Set<String> keySet = serverMap.keySet();
              ArrayList<String> keyList = new ArrayList<String>();
              keyList.addAll(keySet);
      
              java.util.Random random = new java.util.Random();
              int randomPos = random.nextInt(keyList.size());
      
              return keyList.get(randomPos);
          }
      }

      整體代碼思路和輪詢法一致,先重建serverMap,再獲取到server列表。在選取server的時(shí)候,通過(guò)Random的nextInt方法取0~keyList.size()區(qū)間的一個(gè)隨機(jī)值,從而從服務(wù)器列表中隨機(jī)獲取到一臺(tái)服務(wù)器地址進(jìn)行返回?;诟怕式y(tǒng)計(jì)的理論,吞吐量越大,隨機(jī)算法的效果越接近于輪詢算法的效果。

      源地址哈希(Hash)法

      源地址哈希的思想是根據(jù)獲取客戶端的IP地址,通過(guò)哈希函數(shù)計(jì)算得到的一個(gè)數(shù)值,用該數(shù)值對(duì)服務(wù)器列表的大小進(jìn)行取模運(yùn)算,得到的結(jié)果便是客服端要訪問(wèn)服務(wù)器的序號(hào)。采用源地址哈希法進(jìn)行負(fù)載均衡,同一IP地址的客戶端,當(dāng)后端服務(wù)器列表不變時(shí),它每次都會(huì)映射到同一臺(tái)后端服務(wù)器進(jìn)行訪問(wèn)。、

      源地址哈希算法的代碼實(shí)現(xiàn)大致如下:

      import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Set;/**
       * @author ashang.peng@aliyun.com
       * @date 二月 07, 2017
       */ class Hash      {
          public static String getServer()    {
              // 重建一個(gè)Map,避免服務(wù)器的上下線導(dǎo)致的并發(fā)問(wèn)題        Map<String, Integer> serverMap =
                      new HashMap<String, Integer>();
              serverMap.putAll(IpMap.serverWeightMap);
      
              // 取得Ip地址List        Set<String> keySet = serverMap.keySet();
              ArrayList<String> keyList = new ArrayList<String>();
              keyList.addAll(keySet);
      
              // 在Web應(yīng)用中可通過(guò)HttpServlet的getRemoteIp方法獲取        String remoteIp = "127.0.0.1";
              int hashCode = remoteIp.hashCode();
              int serverListSize = keyList.size();
              int serverPos = hashCode % serverListSize;
      
              return keyList.get(serverPos);
          }
      }

      前兩部分和輪詢法、隨機(jī)法一樣就不說(shuō)了,差別在于路由選擇部分。通過(guò)客戶端的ip也就是remoteIp,取得它的Hash值,對(duì)服務(wù)器列表的大小取模,結(jié)果便是選用的服務(wù)器在服務(wù)器列表中的索引值。

      源地址哈希法的優(yōu)點(diǎn)在于:保證了相同客戶端IP地址將會(huì)被哈希到同一臺(tái)后端服務(wù)器,直到后端服務(wù)器列表變更。根據(jù)此特性可以在服務(wù)消費(fèi)者與服務(wù)提供者之間建立有狀態(tài)的session會(huì)話。

      源地址哈希算法的缺點(diǎn)在于:除非集群中服務(wù)器的非常穩(wěn)定,基本不會(huì)上下線,否則一旦有服務(wù)器上線、下線,那么通過(guò)源地址哈希算法路由到的服務(wù)器是服務(wù)器上線、下線前路由到的服務(wù)器的概率非常低,如果是session則取不到session,如果是緩存則可能引發(fā)"雪崩"。如果這么解釋不適合明白,可以看我之前的一篇文章MemCache超詳細(xì)解讀,一致性Hash算法部分。

      加權(quán)輪詢(Weight Round Robin)法

      不同的后端服務(wù)器可能機(jī)器的配置和當(dāng)前系統(tǒng)的負(fù)載并不相同,因此它們的抗壓能力也不相同。給配置高、負(fù)載低的機(jī)器配置更高的權(quán)重,讓其處理更多的請(qǐng);而配置低、負(fù)載高的機(jī)器,給其分配較低的權(quán)重,降低其系統(tǒng)負(fù)載,加權(quán)輪詢能很好地處理這一問(wèn)題,并將請(qǐng)求順序且按照權(quán)重分配到后端。加權(quán)輪詢法的代碼實(shí)現(xiàn)大致如下:

      import java.util.*;/**
       * @author ashang.peng@aliyun.com
       * @date 二月 07, 2017
       */class WeightRoundRobin   {
          private static Integer pos;
      
          public static String getServer()    {
              // 重建一個(gè)Map,避免服務(wù)器的上下線導(dǎo)致的并發(fā)問(wèn)題        Map<String, Integer> serverMap =
                      new HashMap<String, Integer>();
              serverMap.putAll(IpMap.serverWeightMap);
      
              // 取得Ip地址List        Set<String> keySet = serverMap.keySet();
              Iterator<String> iterator = keySet.iterator();
      
              List<String> serverList = new ArrayList<String>();
              while (iterator.hasNext())
              {
                  String server = iterator.next();
                  int weight = serverMap.get(server);
                  for (int i = 0; i < weight; i++)
                      serverList.add(server);
              }
      
              String server = null;
              synchronized (pos)
              {
                  if (pos > keySet.size())
                      pos = 0;
                  server = serverList.get(pos);
                  pos ++;
              }
      
              return server;
          }
      }

      與輪詢法類似,只是在獲取服務(wù)器地址之前增加了一段權(quán)重計(jì)算的代碼,根據(jù)權(quán)重的大小,將地址重復(fù)地增加到服務(wù)器地址列表中,權(quán)重越大,該服務(wù)器每輪所獲得的請(qǐng)求數(shù)量越多。

      加權(quán)隨機(jī)(Weight Random)法

      與加權(quán)輪詢法一樣,加權(quán)隨機(jī)法也根據(jù)后端機(jī)器的配置,系統(tǒng)的負(fù)載分配不同的權(quán)重。不同的是,它是按照權(quán)重隨機(jī)請(qǐng)求后端服務(wù)器,而非順序。

      import java.util.*;/**
       * @author ashang.peng@aliyun.com
       * @date 二月 07, 2017
       */ class WeightRandom   {
          public static String getServer()    {
              // 重建一個(gè)Map,避免服務(wù)器的上下線導(dǎo)致的并發(fā)問(wèn)題        Map<String, Integer> serverMap =
                      new HashMap<String, Integer>();
              serverMap.putAll(IpMap.serverWeightMap);
      
              // 取得Ip地址List        Set<String> keySet = serverMap.keySet();
              Iterator<String> iterator = keySet.iterator();
      
              List<String> serverList = new ArrayList<String>();
              while (iterator.hasNext())
              {
                  String server = iterator.next();
                  int weight = serverMap.get(server);
                  for (int i = 0; i < weight; i++)
                      serverList.add(server);
              }
      
              java.util.Random random = new java.util.Random();
              int randomPos = random.nextInt(serverList.size());
      
              return serverList.get(randomPos);
          }
      }

      這段代碼相當(dāng)于是隨機(jī)法和加權(quán)輪詢法的結(jié)合,比較好理解,就不解釋了。

      最小連接數(shù)(Least Connections)法

      最小連接數(shù)算法比較靈活和智能,由于后端服務(wù)器的配置不盡相同,對(duì)于請(qǐng)求的處理有快有慢,它是根據(jù)后端服務(wù)器當(dāng)前的連接情況,動(dòng)態(tài)地選取其中當(dāng)前

      積壓連接數(shù)最少的一臺(tái)服務(wù)器來(lái)處理當(dāng)前的請(qǐng)求,盡可能地提高后端服務(wù)的利用效率,將負(fù)責(zé)合理地分流到每一臺(tái)服務(wù)器。

      前面幾種方法費(fèi)盡心思來(lái)實(shí)現(xiàn)服務(wù)消費(fèi)者請(qǐng)求次數(shù)分配的均衡,當(dāng)然這么做是沒(méi)錯(cuò)的,可以為后端的多臺(tái)服務(wù)器平均分配工作量,最大程度地提高服務(wù)器的利用率,但是實(shí)際情況是否真的如此?實(shí)際情況中,請(qǐng)求次數(shù)的均衡真的能代表負(fù)載的均衡嗎?這是一個(gè)值得思考的問(wèn)題。

      上面的問(wèn)題,再換一個(gè)角度來(lái)說(shuō)就是:以后端服務(wù)器的視角來(lái)觀察系統(tǒng)的負(fù)載,而非請(qǐng)求發(fā)起方來(lái)觀察。最小連接數(shù)法便屬于此類。

      最小連接數(shù)算法比較靈活和智能,由于后端服務(wù)器的配置不盡相同,對(duì)于請(qǐng)求的處理有快有慢,它正是根據(jù)后端服務(wù)器當(dāng)前的連接情況,動(dòng)態(tài)地選取其中當(dāng)前積壓連接數(shù)最少的一臺(tái)服務(wù)器來(lái)處理當(dāng)前請(qǐng)求,盡可能地提高后端服務(wù)器的利用效率,將負(fù)載合理地分流到每一臺(tái)機(jī)器。由于最小連接數(shù)設(shè)計(jì)服務(wù)器連接數(shù)的匯總和感知,設(shè)計(jì)與實(shí)現(xiàn)較為繁瑣,此處就不說(shuō)它的實(shí)現(xiàn)了。

      附了一個(gè)說(shuō)明“NGINX的實(shí)現(xiàn)原因,大家可以看看":

      blog.csdn.net

      來(lái)自:DUZHI

      相關(guān)鏈接


        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多