Nacos+Feign+Ribbon聲明式Rest調用及客戶端側負載均衡

Nacos+Feign+Ribbon聲明式Rest調用及客戶端側負載均衡

  • 運行示例代碼時需要先安裝Lombok插件,或去除使用Lombok的相關代碼再運行

在Nacos上註冊服務提供者集羣

在服務提供者的示例代碼中將bootstrap.yml另外複製兩份,分別命名爲bootstrap-cluster1.ymlbootstrap-cluster2.yml。如下圖所示:
在這裏插入圖片描述
分別對應的端口爲808080818082,其他參數如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機制,則會直接報錯:
在這裏插入圖片描述

Github倉庫地址

倉庫鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章