文章目錄
Nacos+Feign+Ribbon聲明式Rest調用及客戶端側負載均衡
- 運行示例代碼時需要先安裝Lombok插件,或去除使用Lombok的相關代碼再運行
在Nacos上註冊服務提供者集羣
在服務提供者的示例代碼中將bootstrap.yml
另外複製兩份,分別命名爲bootstrap-cluster1.yml
和bootstrap-cluster2.yml
。如下圖所示:
分別對應的端口爲8080
、8081
、8082
,其他參數如Nacos等可參考代碼。可在idea配置啓動如下
分別啓動服務提供者,啓動成功後可以在Nacos管理頁面上看到服務提供者已經註冊到Nacos上。
服務消費者集成Feign+Ribbon
介紹
- Feign介紹:
Feign是Netflix公司開源的輕量級rest客戶端,使用Feign可以非常方便的實現Http 客戶端。Spring Cloud引入Feign並且集成了Ribbon實現客戶端負載均衡調用。
通俗一點講:可以像調用本地方法一樣的調用遠程服務的方法。
在Spring Cloud Alibaba中使用Feign+Ribbon
爲了便於使用,NacosServerList 實現了 com.netflix.loadbalancer.ServerList 接口,並在 @ConditionOnMissingBean 的條件下進行自動注入。如果您有定製化的需求,可以自己實現自己的 ServerList。
Nacos Discovery Starter 默認集成了 Ribbon ,所以對於使用了 Ribbon 做負載均衡的組件,可以直接使用 Nacos 的服務發現。
使用 RestTemplate 和 FeignClient
這部分將分別使用
RestTemplate
結合Ribbon實現客戶端側的負載均衡,以及使用FeignClient(默認集成了Ribbon)實現負載均衡。
使用RestTmplate+Ribbon
- 添加 @LoadBlanced 註解,使得 RestTemplate 接入 Ribbon
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
- 編寫Controller
RestController
@Slf4j
public class SayHiConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/hello-rest/{user}")
public String rest(@PathVariable("user") String user) {
return restTemplate.getForObject("http://nacos-provider-demo-xuda/sayHi/" + user,
String.class);
}
}
使用Postman發送多次請求 http://10.0.90.30:8900/hello-rest/xuda
,每次的響應分別如下:
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
實現了RestTemplate的負載均衡功能。從響應結果來看,默認使用的是基於輪詢算法
的負載均衡方式。其他配置方式可參考Ribbon 負載均衡策略配置. 下面演示基於隨機算法
的負載均衡策略
- 負載均衡
隨機策略
配置文件中新增下面內容
### 針對單個服務的 Ribbon 配置
nacos-provider-demo-xuda:
ribbon:
# 基於配置文件形式的 針對單個服務的 Ribbon 負載均衡策略
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置規則 隨機
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置規則 輪詢
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置規則 重試
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置規則 響應時間權重
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置規則 隨機
ConnectTimeout: 500 #請求連接超時時間
ReadTimeout: 1000 #請求處理的超時時間
OkToRetryOnAllOperations: true #對所有請求都進行重試
MaxAutoRetriesNextServer: 2 #切換實例的重試次數
MaxAutoRetries: 1 #對當前實例的重試次數
重新啓動消費者服務,使用postman發送請求,多次請求的結果如下:
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
實現了基於隨機策略的負載均衡
使用FeignTemplate
- 編寫EchoService接口,代碼如下
@FeignClient(name = "nacos-provider-demo-xuda")
public interface EchoService {
@GetMapping("/sayHi/{user}")
String sayHi(@PathVariable("user") String user);
}
其中@FeignClient
註解的name
屬性是在Nacos上註冊的服務提供者的名稱。Controller如下
@RestController
@Slf4j
public class SayHiConsumerController {
@Autowired
private EchoService echoService;
@GetMapping("/hello/{user}")
public String sayHi(@PathVariable("user") String user) {
return echoService.sayHi(user);
}
}
啓動項目,使用postman發送請求http://10.0.90.30:8900/hello/xuda
,結果如下:
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8081
實現了使用FeignClient的客戶端側的負載均衡。因爲使用的負載均衡策略與上一步相同,所以結果也呈現出隨機算法的負載均衡策略。
Feign的Fallback機制
在網絡請求時,可能會出現異常請求,如果還想再異常情況下使系統可用,那麼就需要容錯處理,比如:網絡請求超時時給用戶提示“稍後重試”或使用本地快照數據等等。
在服務提供者一方增加一個Contrller,拋出異常,模擬服務端不可用的情況
@GetMapping("/sayHiError/{user}")
public String sayHiError(@PathVariable("user") String user) {
throw new RuntimeException("模擬服務調用失敗");
}
在服務調用者一方的EchoService.java
中修改如下:
@FeignClient(name = "nacos-provider-demo-xuda", fallback = EchoServiceFallback.class,
configuration = FeignConfiguration.class)
public interface EchoService {
@GetMapping("/sayHi/{user}")
String sayHi(@PathVariable("user") String user);
@GetMapping("/sayHiError/{user}")
String sayHiError(@PathVariable("user") String user);
}
新增一個fallback實現類
public class EchoServiceFallback implements EchoService {
@Override
public String sayHi(@PathVariable("user") String user) {
return "fallback";
}
@Override
public String sayHiError(@PathVariable("user")String user) {
return "服務器發生異常";
}
}
要使用Feign的fallback機制,需要開啓Feign的Hystrix的功能,新增配置如下:
feign:
hystrix:
enabled: true
使用postman發送請求http://10.0.90.30:8900/helloError/xuda
,所得結果如下:
如果不使用fallback機制,則會直接報錯: