Ribbon 負載均衡機制(自定義負載均衡規則)
Ribbon 負載均衡機制
在上一章的 "Ribbon 框架簡介及搭建(沒有與SpringCloud整合,獨立使用)" 中介紹了Ribbon框架及搭建使用,那麼在這一章會講一講Ribbon的負載均衡的機制,以下的規則 筆者將會以通俗易懂的介紹給大家講解。
Ribbon內建的負載均衡規則
1. RoundRobinRule
通過簡單的輪詢服務列表,來選擇一個伺服器2. AvailabilityFilteringRule 對以下兩種伺服器忽略掉,就不會選擇它們了。 2.2 在預設情況下連線失敗3次,這個伺服器就會被置為"短路"狀態,這個狀態將持續30秒。如果再連不上,那麼這個狀態的持續時間將會持續增加。
會為每一個伺服器賦予一個權重值,伺服器響應時間越長,這個伺服器的權重值就越少,權重有可能會決定伺服器的選擇(存在隨機)4. ZoneAvoidanceRule
以區域,可用的伺服器為基礎進行伺服器的選擇,使用Zone對伺服器進行分類5. BastAvailableRule
忽略那些短路的伺服器,並選擇併發數較低的伺服器6. RandomRule
隨機選擇一個可用的伺服器7. RetryRule
它是一個含有重試機制的選擇邏輯
其他配置NFLoadBalancerPingClassName:檢查伺服器是否存活NFLoadBalanceClassName:指定負載均衡器的實現類,可以使用該配置自定義負載均衡器
這裡我就不給大家一一貼配置了,感興趣的可以到官網的wiki去看:https://github.com/Netflix/ribbon
首先需要建立一個Ribbon伺服器,即使在上一章中寫過,但是不免有一些懶懶的小夥伴(偷偷的告訴大家,筆者也是其中之一,恨不得直接複製貼上(*^_^*))。
1:建立Ribbon伺服器(一個單純的SpringBoot程式)
pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.7.RELEASE</version> </dependency> </dependencies>
為了方便Ribbon客戶端測試,在這裡建一個實體類:Person.java
public class Person { private String url;// 處理請求的伺服器url private String message;// 提示資訊 public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
PersonController.java
@RestController public class PersonController { @RequestMapping(value="/getPerson", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE) public Person getPerson(HttpServletRequest request){ Person p = new Person(); p.setMessage("請求成功"); p.setUrl(request.getRequestURL().toString()); return p; } }
啟動類:Application.java(因為要測試負載均衡,所有這裡需要啟動多個服務,以下配置以手動輸入埠號方式啟動)
@SpringBootApplication public class Application { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String port = scan.nextLine(); new SpringApplicationBuilder(Application.class).properties("server.port="+port).run(args); } }
本次啟動以埠:8080、8081分別啟動,稍後我們配置完客戶端 統一測試(配置後,將服務啟動)
2:建立Ribbon客戶端
pom.xml 中只需要引入核心及客戶端的依賴即可
<dependency> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-core</artifactId> <version>2.2.5</version> </dependency> <dependency> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-httpclient</artifactId> <version>2.2.5</version> </dependency>
上面的配置與上一章的內容完全一樣,那麼接下來的內容大家就要注意了,也是本次講解的重點。(本次的事例有輪詢 + 自定義負載均衡器 + 訪問服務)
使用預設的輪詢規則
public static void main(String[] args) throws Exception { // 建立負載均衡器物件 ILoadBalancer lb = new BaseLoadBalancer(); // 設定伺服器列表 List<Server> servers = new ArrayList<Server>(); servers.add(new Server("localhost", 8080)); servers.add(new Server("localhost", 8081)); // 向負載均衡器中新增服務列表 lb.addServers(servers); // 預設規則:輪詢 for(int i=0; i<10; i++){ Server s = lb.chooseServer(null); System.out.println(s); } } |
使用自定義負載均衡器
/*** * 自定義負載均衡器,這裡需要實現“IRule”介面 * 比如埠為8081的伺服器是新買的,不想讓它處理太多的任務,那麼可以用隨機數去控制它的訪問量 * @author lpx * */ public class MyRule implements IRule{ private ILoadBalancer lb;// 宣告負載均衡器介面 @Override public Server choose(Object key) { // 獲取伺服器列表 List<Server> servers = lb.getAllServers(); // 生產隨機數 Random r = new Random(); int rand = r.nextInt(10); if(rand > 7){ return getServerByPort(servers, 8081); }else{ return getServerByPort(servers, 8080); } } /** * 根據傳入的埠號,返回服務物件 * @param servers * @param port * @return */ private Server getServerByPort(List<Server> servers, int port){ for(Server s : servers){ if(s.getPort() == port){ return s; } } return null; } @Override public void setLoadBalancer(ILoadBalancer lb) { this.lb = lb; } @Override public ILoadBalancer getLoadBalancer() { return this.lb; } }
public static void main(String[] args) throws Exception { // 建立負載均衡器 BaseLoadBalancer blb = new BaseLoadBalancer(); // 建立自定義負載均衡器 MyRule myRule = new MyRule(); // 設定負載均衡器 myRule.setLoadBalancer(blb); // 設定負載均衡器規則 blb.setRule(myRule); // 設定伺服器列表 List<Server> servers = new ArrayList<Server>(); servers.add(new Server("localhost", 8080)); servers.add(new Server("localhost", 8081)); blb.setServersList(servers); for(int i=0; i<10; i++){ Server s = blb.chooseServer(null); System.out.println(s); } } |
使用自定義負載均衡器訪問服務
public static void main(String[] args) throws Exception { // 寫入服務列表 ConfigurationManager.getConfigInstance().setProperty("my-client.ribbon.listOfServers", "localhost:8080,localhost:8081"); // 配置規則類 ConfigurationManager.getConfigInstance().setProperty("my-client.ribbon.NFLoadBalancerRuleClassName", MyRule.class.getName()); // 輸出服務列表 System.out.println("服務列表:" + ConfigurationManager.getConfigInstance().getProperty("my-client.ribbon.listOfServers")); // 建立客戶端 RestClient client = (RestClient) ClientFactory.getNamedClient("my-client"); // 建立request物件 HttpRequest request = HttpRequest.newBuilder().uri(new URI("/getPerson")).build(); // 多次訪問測試 for (int i = 0; i < 10; i++) { // 建立response物件 HttpResponse response = client.executeWithLoadBalancer(request); // 接收請求結果 String json = response.getEntity(String.class); // 列印結果 System.out.println(json); } } |
OK,以上就是本文的全部內容(負載均衡規則的機制 + 自定義負載均衡規則 + 訪問服務),如果筆者有寫的不對的地方還望大家提出,蟹蟹!!!