```
public class IpMap
{
// 待路由的Ip列表,Key代表Ip,Value代表該Ip的權重
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);
// 權重為4
serverWeightMap.put("192.168.1.102", 4);
serverWeightMap.put("192.168.1.103", 1);
serverWeightMap.put("192.168.1.104", 1);
// 權重為3
serverWeightMap.put("192.168.1.105", 3);
serverWeightMap.put("192.168.1.106", 1);
// 權重為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);
}
}
```
#### 輪詢法
> `優點`試圖做到請求轉移的絕對均衡
> `缺點`需要引入重量級的悲觀鎖,降低吞吐量 (因為要記錄上一次請求的pos)
```
public class RoundRobin
{
private static Integer pos = 0;
public static String getServer()
{
// 重建一個Map,避免服務器的上下線導致的并發問題
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;
}
}
```
#### 隨機法
> 基于概率的計算出請求的轉移節點
```
public class Random
{
public static String getServer()
{
// 重建一個Map,避免服務器的上下線導致的并發問題
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);
}
}
```
#### hash法
> 保證了相同客戶端IP地址將會被哈希到同一臺后端服務器,直到后端服務器列表變更。根據此特性可以在服務消費者與服務提供者之間建立有狀態的session會話
> 除非集群中服務器的非常穩定,基本不會上下線,否則一旦有服務器上線、下線,那么通過源地址哈希算法路由到的服務器是服務器上線、下線前路由到的服務器的概率非常低,如果是session則取不到session,如果是緩存則可能引發"雪崩"
```
public class Hash
{
public static String getServer()
{
// 重建一個Map,避免服務器的上下線導致的并發問題
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應用中可通過HttpServlet的getRemoteIp方法獲取
String remoteIp = "127.0.0.1";
int hashCode = remoteIp.hashCode();
int serverListSize = keyList.size();
int serverPos = hashCode % serverListSize;
return keyList.get(serverPos);
}
}
```
#### 加權輪詢法
> 權重越大的節點獲得請求數越多
```
public class WeightRoundRobin
{
private static Integer pos;
public static String getServer()
{
// 重建一個Map,避免服務器的上下線導致的并發問題
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;
}
}
```
#### 加權隨機法
> 加權隨機法也是根據后端服務器不同的配置和負載情況來配置不同的權重
```
public class WeightRandom
{
public static String getServer()
{
// 重建一個Map,避免服務器的上下線導致的并發問題
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);
}
}
```
#### 最小連接數(Least Connections)法
> 以 后端服務器的視角來觀察系統的負載,而非請求發起方來觀察
- 虛擬機
- JVM內存結構
- JVM調優手段
- java對象生命周期
- 垃圾回收判斷對象死亡
- 垃圾回收算法
- 垃圾收集器
- JAVA基礎知識
- java事件機制
- java反射機制
- jvm創建對象
- java異常
- finally語句一定會執行嗎?
- 集合類介紹
- ArrayList
- LinkedList
- HashMap
- ConcurrentHashMap
- 多線程
- 為什么要使用線程池
- 線程死鎖
- 死鎖檢測和解除
- jstack
- jconsole
- 死鎖預防
- 常見線程池
- 線程池參數
- 工作隊列介紹
- 拒絕策略
- ThreadLocal
- CAS
- ReentrantLock
- AQS
- CountDownLatch
- Spring
- spring中bean的作用域
- REDIS
- redis數據結構
- redis hash實現
- redis rehash與hashmap擴容的區別
- Redis使用場景
- Redis為何這么快
- redis連接數不足導致錯誤
- 分布式
- 分布式事務
- ACID
- CAP
- BASE
- 事務隔離性
- 一致性哈希算法
- 負載均衡算法
- Hystrix 信號量和線程池隔離的差異
- Spring Cloud
- eureka
- MYSQL
- mysql優化經驗
- undo redo binlog
- web
- http協議
- http和https區別
- Cookie和session
- TCP三次握手、4次揮手
- TCP的time_wait和close_wait
- 算法問題
- 編輯距離算法
- MQ
- RabbitMq
- Kafka
- 安裝教程
- Win ELK安裝