Spring Cloud微服務解決方案③:Ribbon的使用
先來一段介紹:
Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,它基於Netflix Ribbon實現。通過Spring Cloud的封裝,可以讓我們輕鬆地將面向服務的REST模版請求自動轉換成客戶端負載均衡的服務呼叫。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API閘道器那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。因為微服務間的呼叫,API閘道器的請求轉發等內容,實際上都是通過Ribbon來實現的,包括後續我們將要介紹的Feign,它也是基於Ribbon實現的工具。所以,對Spring Cloud Ribbon的理解和使用,對於我們使用Spring Cloud來構建微服務非常重要。
實現Ribbon的客戶端負載其實很簡單,專案地址在我的Spring Cloud微服務解決方案1的檔案裡面的microservice-consumer-movie-ribbon模組。demo下載地址:https://download.csdn.net/download/qq_22075041/10851487
<!--此依賴已經集成了Ribbon,無需額外--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
然後再在restTemplate上面加一個@LoadBalanced註解就可以了
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
但是有時候 我們客戶端負載有很多的方式 比如隨機輪訓等,這時候我們就需要自定義負載的方案,如下
@Configuration public class TestConfiguration { // @Autowired // IClientConfig config; @Bean public IRule ribbonRule() { return new RandomRule();//隨機 } }
//還需要在累上面加一個註解申明一下,下面的microservice-provider-user是註冊到eurake一個服務的虛擬IP
@RibbonClient(name = "microservice-provider-user", configuration = TestConfiguration.class)
這裡有個警告:就是@Configuration註解不能放在@ComponentScan、@SpringBootApplication包以及子包下。破解辦法在下面 我們接著說
microservice-provider-user只是我們一個服務ip,但是我們一個專案可能有很多個服務,但是我又不想讓所有的服務隨機。那麼我們可以這樣自定義配置負載。
package com.itmuch.cloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.itmuch.cloud.entity.User;
@RestController
public class MovieController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;//注意這個地方
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
// http://localhost:7900/simple/
// VIP virtual IP
// HAProxy Heartbeat
return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
}
@GetMapping("/test")
public String test() {
//訪問測試microservice-provider-user是隨機方式
ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
System.out.println("111" + ":" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort());
//訪問測試microservice-provider-user2不是隨機方式
ServiceInstance serviceInstance2 = this.loadBalancerClient.choose("microservice-provider-user2");
System.out.println("222" + ":" + serviceInstance2.getServiceId() + ":" + serviceInstance2.getHost() + ":" + serviceInstance2.getPort());
return "1";
}
}
接上面的警告,我就是要放到這個包下面,那我們可以@ComponentScan忽略這個自定義TestConfiguration類,怎麼
做呢,我們寫一個自定義註解@ExcludeFromComponentScan,加在TestConfiguration類上,然後再啟動類上面加上這一句
@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = ExcludeFromComponentScan.class) })
其實對於這種自定義方式的負載均衡還有支援更方便的方式就是寫入配置檔案當中。、
官方說的優先順序是 配置檔案方式 > 程式碼 > 預設
參考的程式碼模組在microservice-consumer-movie-ribbon-properties-customizing
在配置檔案中加入這一行
microservice-provider-user: #服務名
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 隨機規則,感興趣的可以再在這個包路徑下自己找負載的更多規則
還沒有完,如果我們只要ribbon服務,不要eurake呢?在配置檔案這樣寫(程式碼參考microservice-consumer-movie-ribbon-without-eureka模組):
ribbon:
eureka:
enabled: false #禁用eurake
microservice-provider-user: #服務名
ribbon:
listOfServers: localhost:7900 #服務地址,可以是多個