@[toc]
Spring cloud 使用 Ribbon 來實現客戶端負載均衡
前言
在Spring cloud 中當統一類型多個服務開始註冊到服務註冊中心中,次數服務即是集羣 消費端(客戶端)消費的時候需要進行選擇調用服務。
服務註冊 點擊
Spring cloud 中默認調用是依賴eureka 的 ribbon 來實現客戶端負載均衡策略
我們先來註冊兩個服務
然後採用 ribbon 來實現負載均衡策略
ribbon依賴
ribbon 依賴eureka進行實現負載均衡,所以我們不需要導入包,默認在eureka 依賴中存在
實現負載均衡
僅僅需要在 上面增加 @LoadBalanced註解即可
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaclientApplication {
//開啓負載均衡
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(EurekaclientApplication.class, args);
}
}
消費調用
@RestController
public class GetUserController {
@Autowired
RestTemplate restTemplate;
//服務發現對象
@Autowired
DiscoveryClient discoveryClient;
@RequestMapping("get")
public User getUser(int id){
//user微服務的名字 用來想此服務發送請求
String servceId = "user-server";
String url = "http://" + servceId + "/getUser?id=" + id;
System.out.println(url + " = " + url);
User forObject = restTemplate.getForObject(url, User.class);
}
測試
打印每次調用的 url 和 端口
@Autowired
LoadBalancerClient loadBalancerClient;
for (int i = 0; i < 100; i++) {
ServiceInstance choose = loadBalancerClient.choose("user-server");
System.out.println("第 " + (i+1) + "次 執行 " + choose.getPort() + choose.getUri());
}
return forObject;
}
結果如下
我們可以看到每次是輪訓調用,一個接着一個循環調用請求(總共2個服務)。
默認策略
ribbon自動配置中沒有指定配置策略默認實現輪訓策略
設置隨機策略
設置負載均衡爲隨機策略
serviceId.ribbon.NFLoadBalancerRuleClassName=自定義的負載均衡策略類
在配置文件裏面配置
user-server: # 這個配置是請求的服務名
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
或者通過硬編碼方式
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule() {
// 負載均衡規則,改爲隨機
return new RandomRule();
}
默認情況下 配置文件大於硬編碼方式
測試結果
每次請求隨機訪問
自定義策略
ribbon 默認通過 IRule 接口來實現負載均衡策略,默認實現通過ZoneAvoidanceRule 輪訓負載
- 結構圖
另外自帶的負載均衡策略
不依賴eureka實現Ribbon負載均衡
ribbon可以脫離eureka實現負載均衡如下
#取消Ribbon使用Eureka
ribbon.eureka.enabled=false
#配置Ribbon能訪問 的微服務節點,多個節點用逗號隔開
user-server.ribbon.listOfServers=localhost:6869,localhost:6870
最後可能會遇到的問題
可能會報錯
springcloud ribbon實現負載均衡的時候,提示Request URI does not contain a valid hostname: http://PRODUCT_SERVICE/
原因是因爲服務名不能 有 下劃線
代碼地址 傳送門