1. 程式人生 > >Spring Cloud系列文,Feign整合Ribbon和Hysrix

Spring Cloud系列文,Feign整合Ribbon和Hysrix

    在本部落格之前的Spring Cloud系列裡,我們講述了Feign的基本用法,這裡我們將講述下Feign整合Ribbon實現負載均衡以及整合Hystrix實現斷路保護效果的方式。    

1 準備Eureka伺服器以及多個服務提供者

    這裡,我們將重用之前博文裡講過的案例,提供的兩個(即主從)Eureka服務專案以及三個服務提供者的專案。隨後在此基礎上,在服務呼叫者的專案中,通過Feign以負載均衡的方式呼叫三個服務提供者所提供的sayHello方法。    

2 在客戶端引入Ribbon

在FeignDemo-ServiceCaller專案裡開發Fegin整合Ribbon,具體的步驟如下。

 在pom.xml中,引入Ribbon依賴包,關鍵程式碼如下。

1       <dependency>
2          <groupId>org.springframework.cloud</groupId>
3          <artifactId>spring-cloud-ribbon</artifactId>
4       </dependency>

     在ControllerForFeignRibbon.java中,編寫Feign以Ribbon負載均衡的方式呼叫服務的程式碼。

 //省略必要的package和import的程式碼
//這和Ribbon Provider中的applicationname一致
@FeignClient(value = "sayHelloAvoidCopy")
interface FeignClientRibbonTool{
      @RequestMapping(method = RequestMethod.GET, value = "/sayHello/{username}/avoidCopy")
       String sayHelloAsRibbon(@PathVariable("username") String username);
}

@RestController
public class ControllerForFeignRibbon {    
     private FeignClientRibbonTool tool;
     @RequestMapping(value = "/callHelloAsRibbon/{username}", method = RequestMethod.GET)
     public String callHelloAsRibbon(@PathVariable("username") String username) {
        return tool.sayHelloAsRibbon(username);
    }
 }

    在上述程式碼裡,,我們定義了一個名為FeignClientRibbonTool的介面;在第3行中,我們通過@FeignClient註解指定了該Feign介面將會呼叫名為sayHello的服務。請注意,這裡的sayHello命名需要和EurekaRibbonDemo-ServiceProviderOne等專案中application.yml中的相應配置一致。

    在第10行中,我們通過@RestController註解定義了一個名為ControllerForFeignRibbon的控制器類,在其中的第14行的callHelloAsRibbon中,我們是通過Feign介面中的sayHelloAsRibbon方法呼叫服務的。

     在application.yml中,編寫Ribbon的相關配置資訊,關鍵程式碼如下。

1   sayHello:
2     ribbon:
3       listOfServer: http://localhost:1111/,http://localhost:2222/,http://localhost:3333
4       ConnectionsTimeout: 1000
5   ribbon:
6       ConnectionsTimeout: 2000  

    在第1~4行,我們通過配置指定了基於ribbon的多臺伺服器,它們將以負載均衡的方式承擔請求url,而且還指定了連線超時的時間。從第1行我們能看到,這個配置是針對sayHello這個服務例項的。而在第5行和第6行,我們配置了全域性性的ribbon屬性,這裡也配置了連線超時時間。

    完成開發後,啟動定義在表6.2中的兩臺Eureka伺服器、三臺服務提供者和一臺服務呼叫者程式後,在瀏覽器中多次輸入http://localhost:8080/callHelloAsRibbon/Peter以呼叫服務,這時我們能看到有如下輸出。從輸出結果來看,我們以Feign的形式呼叫的請求確實被均衡地轉發到3臺服務提供者的機器上。

    1   Hello Ribbon, there are Server1, my name is:Peter

    2   Hello Ribbon, there are Server2, my name is:Peter

    3   Hello Ribbon, there are Server3, my name is:Peter

    這裡我們來總結一下Feign整合Ribbon的要點。

    第一,多個伺服器提供者的例項名應當一致,比如這裡都是sayHello。

    第二,在Feign的介面中,是通過@FeignClient的註解呼叫服務提供者的方法的。

    第三,這裡我們是在application.yml配置檔案中指定Ribbon的各種引數,也可以通過@Configuration註解在Java檔案中配置Ribbon的引數。

3 在客戶端引入Hystrix(Feigh整合Hystrix)

    在通過Feign呼叫服務時,同樣不能保證服務一定可用,為了提升客戶體驗,這裡可以通過引入Hystrix對訪問請求進行“容錯保護”。

     在FeignDemo-ServiceCaller的pom.xml中,增加Hystrix的依賴包,關鍵程式碼如下。

1       <dependency>
2          <groupId>org.springframework.cloud</groupId> 
3          <artifactId>spring-cloud-hystrix</artifactId>
4       </dependency>

 還是在FeignDemo-ServiceCaller專案的application.yml配置檔案中,通過如下配置項啟動Hystrix模式,關鍵程式碼如下。

1   feign:
2       hystrix:
3           enabled: true   

 

    此外,還可以通過如下程式碼配置針對sayHelloServiceProvider服務的hystrix引數。其中,第3行指定了hystrix所作用的服務名,第7行指定了請求時間一旦超過1000毫秒(也就是1秒),就會啟動熔斷模式,呼叫定義在回退方法中的業務動作。

1   hystrix:
2       command:
3           sayHelloServiceProvider:
4               execution:
5                  isolations:
6                      threads:
7                         timeoutInMilliseconds: 1000   

     在啟動類ServiceCallerApp.java中,增加啟動hystrix斷路器的註解,如第5行所示,這個類的關鍵程式碼如下。    

1   //省略必要的package和import方法
2   EnableFeignClients
3   @EnableDiscoveryClient
4   @SpringBootApplication
5   @EnableCircuitBreakers
6   public class ServiceCallerApp
7   {
8       //省略其他程式碼
9   }

 新建一個名為ControllerForFeignHystrix.java的控制器類,程式碼如下。

1   //省略必要的package和import程式碼
2   @FeignClient(value = "sayHelloServiceProvider",fallback=FeignClientHystrixToolFallback.class)
3   interface FeignClientHystrixTool{
4       @RequestMapping(method = RequestMethod.GET, value = "/hello/{name}")
5       String sayHelloInClient(@RequestParam("name") String name);
6   }

 

在第3行中,我們定義了一個名為FeignClientHystrixTool的介面;在第2行的註解中,我們定義了它將以Feign的形式呼叫sayHelloServiceProvider中的服務,並且通過fallback配置指定一旦出現呼叫異常,將呼叫FeignClientHystrixToolFallback類中的回退方法。

7   @Component
8   class FeignClientHystrixToolFallback implements FeignClientHystrixTool{
9       public String sayHelloInClient(String name)
10      { return "In Fallback Function.";    }  
11  }

    在第8行的FeignClientHystrixToolFallback類中,我們將定義針對FeignClientHystrixTool介面的回退方法。

    注意該類必須和第2行中fallback指定的類同名,而且,該類需要實現(implements)FeignClientHystrixTool介面,在其中的sayHelloInClient方法中定義了回退動作,這裡的動作是列印一段話。

12  @RestController
13  public class ControllerForFeignHystrix {       
14      @Autowired
15      private FeignClientHystrixTool tool;   
16      @RequestMapping(value = "/callHelloAsHystrix/{username}", method = RequestMethod.GET)
17      public String callHelloAsHystrix(@PathVariable("username") String username)
18      { return tool.sayHelloInClient(username);}  
19  }

    在第13行中,我們定義了一個包含@RestController註解的控制器類ControllerForFeignHystrix,在其中第17行的callHelloAsHystrix方法中,我們是以Feign的形式呼叫sayHelloInClient方法的。

    至此,完成程式碼的編寫工作。我們依次啟動FeignDemo-Server、FeignDemo-ServiceProvider和FeignDemo-ServiceCaller專案,隨後在瀏覽器中輸入http://localhost:8080/callHelloAsHystrix/Peter,此時能看到“hello Peter”的輸出,這個是正常的呼叫流程。

    如果我們關閉FeignDemo-ServiceProvider專案,也就是說sayHelloServiceProvider服務不可用了,如果再次在瀏覽器中輸入http://localhost:8080/callHelloAsHystrix/Peter,此時就會走熔斷保護的流程,觸發FeignClientHystrixToolFallback 類中的sayHelloInClient方法,在瀏覽器中輸出“In Fallback Function“的字樣。

 

本文謝絕轉載,如果要程式碼,請和作者聯絡。Spring Cloud相關博文如下:

Spring Cloud微服務系列文,服務呼叫框架Feign    Spring Cloud微服務系列文,Hystrix與Eureka的整合    架構師系列文:通過Spring Cloud元件Hystrix合併請求   架構師入門:Spring Cloud系列,Hystrix與Eureka的整合   Hystrix針對不可用服務的保護機制以及引入快取   通過案例瞭解Hystrix的各種基本使用方式   Ribbon整合Eureka元件,以實現負載均衡   Spring Clould負載均衡重要元件:Ribbon中重要類的用法   架構師入門:搭建雙註冊中心的高可用Eureka架構(基於專案實戰)   架構師入門:搭建基本的Eureka架構(從專案裡抽取)   藉助Maven入手Spring Boot第一個程式