---
title: ä¸ç¯æè¶£çè´è½½åè¡¡ç®æ³å®ç°
date: 2020-05-29 07:37:19
url: algorithm/load-balancing
categories:
- Java å¼å
tags:
- è´è½½åè¡¡
---
> æç« å·²ç»æ¶å½å¨ [Github.com/niumoo/JavaNotes](https://github.com/niumoo/JavaNotes) ï¼æ´æ Java ç¨åºåæéè¦ææ¡çæ ¸å¿ç¥è¯ï¼æ¬¢è¿Staråææã
> 欢è¿å
³æ³¨æç[å
¬ä¼å·](https://github.com/niumoo/JavaNotes#%E5%85%AC%E4%BC%97%E5%8F%B7)ï¼æç« æ¯å¨æ´æ°ã
**è´è½½åè¡¡**ï¼Load balancingï¼æ¯ä¸ç§å¨å¤ä¸ªè®¡ç®æºï¼ç½ç»ãCPUãç£çï¼ä¹é´åååé
èµæºï¼ä»¥æé«èµæºå©ç¨çææ¯ã使ç¨è´è½½åè¡¡å¯ä»¥æå¤§åæå¡ååéï¼å¯è½æå°åååºæ¶é´ï¼åæ¶ç±äºä½¿ç¨è´è½½åè¡¡æ¶ï¼ä¼ä½¿ç¨å¤ä¸ªæå¡å¨èç¹ä»£åç¹æå¡ï¼ä¹æé«äºæå¡çå¯ç¨æ§ã
è´è½½åè¡¡çå®ç°å¯ä»¥è½¯ä»¶å¯ä»¥ç¡¬ä»¶ï¼ç¡¬ä»¶å¦å¤§åé¼é¼ç F5 è´è½½å衡设å¤ï¼è½¯ä»¶å¦ NGINX ä¸çè´è½½åè¡¡å®ç°ï¼åå¦ Springcloud Ribbon ç»ä»¶ä¸çè´è½½åè¡¡å®ç°ã
妿çå°è¿éä½ è¿ä¸ç¥éè´è½½åè¡¡æ¯å¹²åçï¼é£ä¹åªè½æ¾ä¸å¼ å¾äºï¼æ¯ç«æ²¡å¾è¯´ä¸ªå¥ã

è´è½½åè¡¡è¦åå°å¨å¤æ¬¡è¯·æ±ä¸ï¼æ¯å°æå¡å¨è¢«è¯·æ±ç次æ°å¤§è´ç¸åã使¯å®é
ç产ä¸ï¼å¯è½æ¯å°æºå¨çæ§è½ä¸åï¼æä»¬ä¼å¸ææ§è½å¥½çæºå¨æ¿æ
çè¯·æ±æ´å¤ä¸äºï¼è¿ä¹æ¯æ£å¸¸éæ±ã
å¦æè¿æ ·è¯´ä¸æ¥ä½ ç䏿ï¼é£æå°±å举个ä¾å好äºï¼ä¸æå¯ç±çå°çï¼æå¡å¨ï¼ç«å¥½ã

è¿æ¶æäººï¼ç¨æ·ï¼è¦è¿æ¥æè¸ï¼è¯·æ±è®¿é®ï¼ã

é£ä¹æä¹æ ·æä»¬æè½è®©è¿æ¯ä¸ä¸ªå¯ç±çå°ç被æç次æ°å¤§è´ç¸åå¢ï¼
åæè
ç 4 æ¯è¾èï¼æå»æè½åæ¯å«äººç两åï¼æä»¬æä¹æé«ç 4 被æç次æ°ä¹æ¯å«äººç两åå¢ï¼
åæè
æ¯æ¬¡åºæçå度ä¸åï¼æéæè½»ï¼æ°å·§ç 4 æ»æ¯æ¿åè¿ç§å¤§å度åªåªæè¸ï¼ç 4 å³å°ä¸ççäºï¼è¿è¦ç»§ç»æå®åï¼
è¿äºé½æ¯å¼çæèçé®é¢ã
**说äºé£ä¹å¤ï¼å£å¹²èç¥ï¼æåæå·²ç»é¥¥æ¸´é¾èäºï¼è¿«ä¸åå¾
çæ³è¦æ¸èµ·ä»£ç äºã**
## 1. éæºè®¿é®
ä¸é¢è¯´äºï¼ä¸ºäºè´è½½åè¡¡ï¼æä»¬å¿
é¡»ä¿è¯å¤æ¬¡åºæåï¼ç 1 å°ç 4 è¢«ææ¬¡æ°åè¡¡ãæ¯å¦ä½¿ç¨éæºè®¿é®æ³ï¼æ ¹æ®æ°å¦ä¸çæ¦ç论ï¼éæºåºææ¬¡æ°è¶å¤ï¼æ¯åªç被æç次æ°å°±ä¼è¶ç¸è¿ã代ç å®ç°ä¹æ¯è¾ç®åï¼ä½¿ç¨ä¸ä¸ªéæºæ°ï¼éæºè®¿é®ä¸ä¸ªå°±å¯ä»¥äºã
```java
/** æå¡å¨å表 */
private static List serverList = new ArrayList<>();
static {
serverList.add("192.168.1.2");
serverList.add("192.168.1.3");
serverList.add("192.168.1.4");
serverList.add("192.168.1.5");
}
/**
* éæºè·¯ç±ç®æ³
*/
public static String random() {
// å¤å¶éåç¨çéåï¼é²æ¢æä½ä¸éåæåæ´
List tempList = new ArrayList<>(serverList.size());
tempList.addAll(serverList);
// éæºæ°éæºè®¿é®
int randomInt = new Random().nextInt(tempList.size());
return tempList.get(randomInt);
}
```
å 为使ç¨äºé线ç¨å®å
¨çéåï¼æä»¥å¨è®¿é®æä½æ¶æä½çæ¯éåçæ·è´ï¼ä¸é¢å ç§è½®è¯¢æ¹å¼ä¸ä¹æ¯è¿ç§ææ³ã
åä¸ä¸ªæ¨¡æè¯·æ±æ¹æ³ï¼è¯·æ±10w次ï¼è®°å½è¯·æ±ç»æã
```java
public static void main(String[] args) {
HashMap serverMap = new HashMap<>();
for (int i = 0; i < 20000; i++) {
String server = random();
Integer count = serverMap.get(server);
if (count == null) {
count = 1;
} else {
count++;
}
// è®°å½
serverMap.put(server, count);
}
// è·¯ç±æ»ä½ç»æ
for (Map.Entry entry : serverMap.entrySet()) {
System.out.println("IP:" + entry.getKey() + "ï¼æ¬¡æ°ï¼" + entry.getValue());
}
}
```
è¿è¡å¾å°è¯·æ±ç»æã
```
IP:192.168.1.3ï¼æ¬¡æ°ï¼24979
IP:192.168.1.2ï¼æ¬¡æ°ï¼24896
IP:192.168.1.5ï¼æ¬¡æ°ï¼25043
IP:192.168.1.4ï¼æ¬¡æ°ï¼25082
```
æ¯å°æå¡å¨è¢«è®¿é®ç次æ°é½è¶è¿äº 2.5wï¼æç¹è´è½½åè¡¡çææã使¯éæºæ¯ç«æ¯éæºï¼æ¯ä¸è½ä¿è¯è®¿é®æ¬¡æ°ç»å¯¹ååçã
## 2. 轮询访é®
轮询访é®å°±ç®åå¤äºï¼æ¿ä¸é¢çç1å°ç4æ¥è¯´ï¼æä»¬ä¸ä¸ªæ¥ä¸ä¸ªçåªåª - æè¸ï¼ç1æå®æç2ï¼ç2æå®æç3ï¼ç4æå®æç1ï¼æç»ä¹æ¯å®ç°äºè¢«æåè¡¡ã使¯ä¿è¯ååæ»æ¯è¦ä»åºä»£ä»·çï¼éæºè®¿é®ä¸éè¦éæºï¼è½®è¯¢è®¿é®ä¸éè¦ä»ä¹æ¥ä¿è¯è½®è¯¢å¢ï¼
```java
/** æå¡å¨å表 */
private static List serverList = new ArrayList<>();
static {
serverList.add("192.168.1.2");
serverList.add("192.168.1.3");
serverList.add("192.168.1.4");
serverList.add("192.168.1.5");
}
private static Integer index = 0;
/**
* éæºè·¯ç±ç®æ³
*/
public static String randomOneByOne() {
// å¤å¶éåç¨çéåï¼é²æ¢æä½ä¸éåæåæ´
List tempList = new ArrayList<>(serverList.size());
tempList.addAll(serverList);
String server = "";
synchronized (index) {
index++;
if (index == tempList.size()) {
index = 0;
}
server = tempList.get(index);;
}
return server;
}
```
ç±ä»£ç éå¯ä»¥çåºæ¥ï¼ä¸ºäºä¿è¯è½®è¯¢ï¼å¿
须记å½ä¸æ¬¡è®¿é®çä½ç½®ï¼ä¸ºäºè®©å¨å¹¶åæ
åµä¸ä¸åºç°é®é¢ï¼è¿å¿
é¡»å¨ä½¿ç¨ä½ç½®è®°å½æ¶è¿è¡å éï¼å¾ææ¾è¿ç§äºæ¥éå¢å äºæ§è½å¼éã
便§ä½¿ç¨ä¸é¢çæµè¯ä»£ç æµè¯10w次请æ±è´è½½æ
åµã
```java
IP:192.168.1.3ï¼æ¬¡æ°ï¼25000
IP:192.168.1.2ï¼æ¬¡æ°ï¼25000
IP:192.168.1.5ï¼æ¬¡æ°ï¼25000
IP:192.168.1.4ï¼æ¬¡æ°ï¼25000
```
## 3. è½®è¯¢å æ
ä¸é¢æ¼ç¤ºäºè½®è¯¢æ¹å¼ï¼è¿è®°çä¸å¼å§æåºçç4æ¯è¾èæå»æè½å强ï¼å¯ä»¥æ¿åå«äºº2åçæ¨ææ¬¡æ°åï¼ä¸é¢ä¸¤ç§æ¹å¼é½æ²¡æä½ç°åºæ¥ç 4 çè¿ä¸ªç¹ç¹ï¼ç 4 çªåï¼ä¸çä¸çã使¯ç 1 å° ç 3 å·²ç»å¨å´©æºçè¾¹ç¼ï¼ä¸è¡ï¼æä»¬å¿
é¡»è¦è®©èç夿ï¼è½è
å¤å³ï¼æé«æ´ä½æ§è½ã
```java
/** æå¡å¨å表 */
private static HashMap serverMap = new HashMap<>();
static {
serverMap.put("192.168.1.2", 2);
serverMap.put("192.168.1.3", 2);
serverMap.put("192.168.1.4", 2);
serverMap.put("192.168.1.5", 4);
}
private static Integer index = 0;
/**
* å æè·¯ç±ç®æ³
*/
public static String oneByOneWithWeight() {
List tempList = new ArrayList();
HashMap tempMap = new HashMap<>();
tempMap.putAll(serverMap);
for (String key : serverMap.keySet()) {
for (int i = 0; i < serverMap.get(key); i++) {
tempList.add(key);
}
}
synchronized (index) {
index++;
if (index == tempList.size()) {
index = 0;
}
return tempList.get(index);
}
}
```
è¿æ¬¡è®°å½ä¸äºæ¯å°æå¡å¨çæ´ä½æ§è½ï¼ç»åºä¸ä¸ªæ°å¼ï¼æ°å¼è¶å¤§ï¼æ§è½è¶å¥½ãå¯ä»¥æ¿åç请æ±ä¹å°±è¶å¤ï¼å¯ä»¥çå°æå¡å¨ `192.168.1.5` çæ§è½ä¸º 4ï¼æ¯å
¶ä»æå¡å¨ç两åï¼ä¾æ§ 10 w è¯·æ±æµè¯ã
```java
IP:192.168.1.3ï¼æ¬¡æ°ï¼20000
IP:192.168.1.2ï¼æ¬¡æ°ï¼20000
IP:192.168.1.5ï¼æ¬¡æ°ï¼40000
IP:192.168.1.4ï¼æ¬¡æ°ï¼20000
```
`192.168.1.5` æ¿æ
äº 2 åç请æ±ã
## 4. éæºå æ
éæºå æçæ¹å¼åè½®è¯¢å æçæ¹å¼å¤§è´ç¸åï¼åªæ¯æä½¿ç¨äºæ¥éè½®è¯¢çæ¹å¼æ¢æäºéæºè®¿é®ï¼æç
§æ¦ç论æ¥è¯´ï¼è®¿é®éå¢å¤æ¶ï¼æå¡è®¿é®ä¹ä¼è¾¾å°è´è½½åè¡¡ã
```java
/** æå¡å¨å表 */
private static HashMap serverMap = new HashMap<>();
static {
serverMap.put("192.168.1.2", 2);
serverMap.put("192.168.1.3", 2);
serverMap.put("192.168.1.4", 2);
serverMap.put("192.168.1.5", 4);
}
/**
* å æè·¯ç±ç®æ³
*/
public static String randomWithWeight() {
List tempList = new ArrayList();
HashMap tempMap = new HashMap<>();
tempMap.putAll(serverMap);
for (String key : serverMap.keySet()) {
for (int i = 0; i < serverMap.get(key); i++) {
tempList.add(key);
}
}
int randomInt = new Random().nextInt(tempList.size());
return tempList.get(randomInt);
}
```
便§ 10 w è¯·æ±æµè¯ï¼`192.168.1.5` çæéæ¯å
¶ä»æå¡å¨çè¿ä¼¼ä¸¤åï¼
```log
IP:192.168.1.3ï¼æ¬¡æ°ï¼19934
IP:192.168.1.2ï¼æ¬¡æ°ï¼20033
IP:192.168.1.5ï¼æ¬¡æ°ï¼39900
IP:192.168.1.4ï¼æ¬¡æ°ï¼20133
```
## 5. IP-Hash
ä¸é¢çå ç§æ¹å¼è¦ä¹ä½¿ç¨éæºæ°ï¼è¦ä¹ä½¿ç¨è½®è¯¢ï¼æç»é½è¾¾å°äºè¯·æ±çè´è½½åè¡¡ã使¯ä¹æä¸ä¸ªå¾ææ¾ç缺ç¹ï¼å°±æ¯åä¸ä¸ªç¨æ·ç夿¬¡è¯·æ±å¾æå¯è½ä¸æ¯åä¸ä¸ªæå¡è¿è¡å¤ççï¼è¿æ¶é®é¢æ¥äºï¼å¦æä½ çæå¡ä¾èµäº session ï¼é£ä¹å 为æå¡ä¸åï¼ session ä¹ä¼ä¸¢å¤±ï¼ä¸æ¯æä»¬æ³è¦çï¼æä»¥åºç°äºä¸ç§æ ¹æ®è¯·æ±ç«¯ç ip è¿è¡åå¸è®¡ç®æ¥å³å®è¯·æ±å°åªä¸å°æå¡å¨çæ¹å¼ãè¿ç§æ¹å¼å¯ä»¥ä¿è¯åä¸ä¸ªç¨æ·ç请æ±è½å¨åä¸ä¸ªæå¡ä¸ã
```java
private static List serverList = new ArrayList<>();
static {
serverList.add("192.168.1.2");
serverList.add("192.168.1.3");
serverList.add("192.168.1.4");
serverList.add("192.168.1.5");
}
/**
* ip hash è·¯ç±ç®æ³
*/
public static String ipHash(String ip) {
// å¤å¶éåç¨çéåï¼é²æ¢æä½ä¸éåæåæ´
List tempList = new ArrayList<>(serverList.size());
tempList.addAll(serverList);
// åå¸è®¡ç®è¯·æ±çæå¡å¨
int index = ip.hashCode() % serverList.size();
return tempList.get(Math.abs(index));
}
```
## 6. æ»ç»
ä¸é¢çåç§æ¹å¼çä¼¼ä¸éï¼é£ä¹è¿æ ·æä½ä¸æ¥ççä½ç°äºä¸å¼å§è¯´çè´è½½åè¡¡åï¼çæ¡æ¯ä¸ä¸å®çãå°±åä¸é¢çæåä¸ä¸ªæé®ã
> åæè
æ¯æ¬¡åºæçå度ä¸åï¼æéæè½»ï¼æ°å·§ç 4 æ»æ¯æ¿åè¿ç§å¤§å度åªåªæè¸ï¼ç 4 å³å°ä¸ççäºï¼è¿è¦ç»§ç»æå®åï¼
æå¡å¨ä¹æ¯è¿ä¸ªéçï¼æ¯æ¬¡è¯·æ±è¿è¡çæä½å¯¹èµæºçæ¶èå¯è½æ¯ä¸åçãæ¯å¦è¯´æäºæä½å®å¯¹ CPU ç使ç¨å°±æ¯æ¯è¾é«ï¼ä¹å¾æ£å¸¸ã**æä»¥è´è½½åè¡¡ææ¶ä¸è½ç®åçéè¿è¯·æ±çè´è½½æ¥ä½ä¸ºè´è½½åè¡¡çå¯ä¸ä¾æ®**ãè¿å¯ä»¥ç»åæå¡çå½åè¿æ¥æ°éãæè¿ååºæ¶é´ç维度è¿è¡æ»ä½åè¡¡ï¼æ»èè¨ä¹ï¼å°±æ¯ä¸ºäºè¾¾å°èµæºä½¿ç¨çè´è½½åè¡¡ã
**æåçè¯**
>æç« å·²ç»æ¶å½å¨ [Github.com/niumoo/JavaNotes](https://github.com/niumoo/JavaNotes) ï¼æ¬¢è¿Staråææãæ´æä¸çº¿å¤§åé¢è¯ç¹ï¼Javaç¨åºåéè¦ææ¡çæ ¸å¿ç¥è¯çæç« ï¼ä¹æ´çäºå¾å¤æçæåï¼æ¬¢è¿ **Star** åå®åï¼å¸ææä»¬ä¸èµ·åå¾ä¼ç§ã
æç« æå¸®å©å¯ä»¥ç¹ä¸ªã**èµ**ãæã**å享**ãï¼é½æ¯æ¯æï¼æé½å欢ï¼
æç« æ¯å¨æç»æ´æ°ï¼è¦å®æ¶å
³æ³¨ææ´æ°çæç« 以åå享ç干货ï¼å¯ä»¥å
³æ³¨ã **æªè¯»ä»£ç ** ãå
¬ä¼å·æè
[æçå客](https://www.wdbyte.com/)ã
