介紹
在Spring cloud有兩種服務調用方式,一種是ribbon+restTemplate,另一種是feign,feign註解化更方便使用。 ribbon是一個負載均衡客戶端,可以很好的控制http和tcp的一些行爲。Feign默認集成了ribbon。RestTemplate中 @LoadBalanced表明這個restRemplate開啓負載均衡的功能。
Feign
1,添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency
2,在啓動類上添加註解
@EnableFeignClients
3,寫一個接口,用來聲明調用哪個方法
/**
* @FeignClient(name = "product")是訪問的服務的名稱
* @GetMapping("/msg")這是調用服務的接口
*/
@FeignClient(name = "product")
public interface ProductClient {
@GetMapping("/msg")
String productMsg();
}
4,在controller中調用接口
@Autowired
private ProductClient productClient;
@GetMapping("/getMsg")
public String getMsg(){
String result = productClient.productMsg();
log.info("result={}",result);
return result;
}
這個Feign中用了ribbon負載均衡的組件,所以默認情況下使用輪詢的算法,當然還有這麼多可選擇的算法。
Rest Template
Rest Template的實現方式有三種。
1,直接寫路徑的方式,有多個的話就用,分割,url寫死
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8080/msg",String.class);
2,填寫這個服務的名稱,然後進行調用。
使用loadBalancerClient獲取url,然後進行調用
RestTemplate restTemplate = new RestTemplate();
ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT");
String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort()+"/msg");
String response = restTemplate.getForObject(url,String.class);
3,直接找到接口方法來調用
@Autowired
private RestTemplateConfig config;
String response = config.getForObject("http://PRODUCT/msg",String.class);
return response;
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
追蹤源碼
點擊choose方法
我們可以看到這兒有一個獲取serviceId的方法
public ServiceInstance choose(String serviceId) {
Server server = this.getServer(serviceId);
return server == null ? null : new RibbonLoadBalancerClient.RibbonServer(serviceId,
server, this.isSecure(server, serviceId),
this.serverIntrospector(serviceId).getMetadata(server));
}
用這個ILoadBalancer 來找serviceId,這個就是ribbon內置的組件
protected Server getServer(ILoadBalancer loadBalancer) {
return loadBalancer == null ? null : loadBalancer.chooseServer("default");
}
我們來看一下這個ILoadBalancer的接口
在BaseLoadBalancer中
看一下這個IRule的接口
public interface ILoadBalancer {
void addServers(List<Server> var1);
Server chooseServer(Object var1);
void markServerDown(Server var1);
/** @deprecated */
@Deprecated
List<Server> getServerList(boolean var1);
List<Server> getReachableServers();
List<Server> getAllServers();
}
這個是默認的規則就是輪詢規則
這種底層的負載均衡地基本上全都是用的ribbon的組件,ribbon就是處理負載均衡的。