Spring Cloud體系裏應用比較廣泛的服務調用方式有兩種:
- 使用RestTemplate進行服務調用,使用Ribbon做負載均衡
- 使用Feign將服務聲明,聲明之後的服務可以像調用本地方法一樣調用,Feign集成了Ribbon作爲負載均衡
RestTemplate + Ribbon調用模式
RestTemplate介紹
RestTemplate是Spring Resources中一個訪問第三方RESTful API接口的網絡請求框架。
RestTemplate是用來消費REST服務的,所以RestTemplate的主要方法都與REST的Http協議的一些方法緊密相連,例如HEAD、GET、POST、PUT、DELETE和OPTIONS等方法,這些方法在RestTemplate類對應的方法爲headForHeaders()、getForObject()、postForObject()、put()和delete()等。
Ribbon與負載均衡
負載均衡(Load Balance),即利用特定方式將流量分攤到多個操作單元上的一種手段,它對系統吞吐量與系統處理能力有着質的提升。
Ribbon不同於Nginx這種服務端負載均衡器,是一個通過在實例庫中選取實例進行流量導入,它賦予了應用一些支配HTTP與TCP行爲的能力,屬於客戶端(後端)負載均衡;通過Ribbon的使用可以使服務橫向擴展,這在雲服務中很便利,後端忙時直接添加provider註冊到註冊中心就可一緩解服務壓力,在閒時直接去掉多餘的provider,使服務更具伸縮性;現在各種雲平臺都提供可伸縮性的服務器,就是對應這種服務
Ribbon有很多子模塊,但很多模塊沒有用於生產環境,目前Netflix公司用於生產環境的Ribbon子模塊如下:
- ribbon-loadbalancer:可以獨立使用或與其他模塊一起使用的負載均衡器API。
- ribbon-eureka:Ribbon結合Eureka客戶端的API,爲負載均衡器提供動態服務註冊列表信息。
- ribbon-core:Ribbon的核心API。
RestTemplate + Ribbon使用
具體使用的例子之前文章後半部分作爲演示consul功能有提到:Spring Cloud: 註冊中心Consul使用
@RestController
public class CallHelloController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@RequestMapping("call")
public String call () {
// 通過 LoadBalancerClient 進行輪詢獲取指定服務
ServiceInstance serviceInstance = loadBalancerClient.choose("consul-provider");
return new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello?name=ubiquitin", String.class);
}
}
代碼中LoadBalancerClient
爲Ribbon默認的負載均衡API,使用的輪詢策略:
loadBalancerClient.choose("consul-provider");
使用Ribbon的負載均衡API獲取註冊中心中名字爲consul-provider
服務,在通過getUri()
獲取服務的地址- 通過
RestTemplate()
和獲取到的地址運城調用服務RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello?name=ubiquitin", String.class);
Ribbon負載均衡策略
在啓動類中注入RestTemplate
, 添加@LoadBalanced
做負載
@Bean
@LoadBalanced
public RestTemplate restTemplate () {
return new RestTemplate();
}
這時可以將上面控制類改寫如下:
@RestController
public class CallHelloController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("call")
public String call () {
return restTemplate.getForObject("http://consul-provider/hello", String.class);
}
// @RequestMapping("call")
// public String call () {
// // 通過 LoadBalancerClient 進行輪詢獲取指定服務
// ServiceInstance serviceInstance = loadBalancerClient.choose("consul-provider");
// return new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello?name=ubiquitin", String.class);
// }
}
這裏直接通過http://consul-provider/hello
進行服務的訪問,其中consul-provider
就是使用的服務名稱,因服務而異
Ribbon更改策略配置
在配置文件中添加:
consul-provider:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
consul-provider
是需要更改策略的服務的名稱com.netflix.loadbalancer.RandomRule
爲策略類型,這裏換成了random隨機獲取
Feign + Ribbon 聲明式調用
Feign介紹
Feign是一個聲明式的Web Service客戶端。它的出現使開發Web Service客戶端變得很簡單。使用Feign只需要創建一個接口加上對應的註解,比如:FeignClient註解。它具備可插拔的註解支持,包括Feign註解、JAX-RS註解。它也支持可插拔的編碼器和解碼器。
在Spring Cloud中使用Feign,可以做到使用HTTP請求訪問遠程服務,就像調用本地方法一樣的。
Feign 使用
1. 添加依賴:
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:2.2.2.RELEASE'
2. 啓動類中添加@EnableFeignClients註解,激活Feign客戶端
3. 創建服務
通過Feign將遠程服務配置到本地
@FeignClient(name = "consul-provider")
public interface ProviderService {
@RequestMapping("hello")
public String hello();
}
- 通過
@FeignClient(name = "consul-provider")
關聯到服務 - 通過
@RequestMapping("hello")
關聯服務上的路由並開放服務接口
4. 創建控制
@RestController
public class feignHelloController {
@Autowired
private ProviderService providerService;
@RequestMapping("feign")
public String call() {
return providerService.hello();
}
}
重啓之後,訪問網址,調用成功。
Feign是整合了Ribbon,Ribbon的負載均衡策略配置方式跟上面提到的一樣。