程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 第十九章 springboot + hystrix(1),springboothystrix

第十九章 springboot + hystrix(1),springboothystrix

編輯:JAVA綜合教程

第十九章 springboot + hystrix(1),springboothystrix


hystrix是微服務中用於做熔斷、降級的工具。

作用:防止因為一個服務的調用失敗、調用延時導致多個請求的阻塞以及多個請求的調用失敗。

1、pom.xml(引入hystrix-core包)

1 <!-- hystrix --> 2 <dependency> 3 <groupId>com.netflix.hystrix</groupId> 4 <artifactId>hystrix-core</artifactId> 5 <version>1.5.2</version> 6 </dependency> View Code

2、application.properties

1 #hystrix 2 hystrix.timeoutInMillions = 3000 View Code

說明:設置hystrix屬性,如上是"服務調用超時時間",其他屬性設置見:https://github.com/Netflix/Hystrix/wiki/Configuration

3、HyStrixProperties

1 package com.xxx.firstboot.hystrix; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 6 import lombok.Getter; 7 import lombok.Setter; 8 9 @Getter @Setter 10 @Component 11 @ConfigurationProperties(prefix = "hystrix") 12 public class HyStrixProperties { 13 private int timeoutInMillions; 14 } View Code

4、MyHyStrixCommand

1 package com.xxx.firstboot.hystrix; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 6 import com.netflix.hystrix.HystrixCommand; 7 import com.squareup.okhttp.OkHttpClient; 8 import com.squareup.okhttp.Request; 9 import com.squareup.okhttp.Response; 10 11 public class MyHystrixCommand extends HystrixCommand<Response> { 12 private static final Logger LOGGER = LoggerFactory.getLogger(MyHystrixCommand.class); 13 private String url; 14 15 public MyHystrixCommand(Setter setter, String url) { 16 super(setter); 17 this.url = url; 18 } 19 20 @Override 21 protected Response run() throws Exception { 22 LOGGER.info("服務正被調用,當前線程:'{}'", Thread.currentThread().getName()); 23 Request request = new Request.Builder().url(url).build(); 24 return new OkHttpClient().newCall(request).execute(); 25 } 26 27 @Override 28 public Response getFallback() { 29 LOGGER.error("服務調用失敗,service:'{}'"); 30 return null; 31 } 32 } View Code

說明:

  • 該類是最關鍵的一個類。
  • 繼承HystrixCommand<T>
  • 添加構造器,注意:無法添加無參構造器,因此該類無法作為spring的bean來進行管理
  • 程序開始時執行run(),當執行發生錯誤或超時時,執行getFallback()

5、HyStrixUtil

1 package com.xxx.firstboot.hystrix; 2 3 import java.util.concurrent.ExecutionException; 4 import java.util.concurrent.Future; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Component; 8 9 import com.netflix.hystrix.HystrixCommand.Setter; 10 import com.netflix.hystrix.HystrixCommandGroupKey; 11 import com.netflix.hystrix.HystrixCommandKey; 12 import com.netflix.hystrix.HystrixCommandProperties; 13 import com.squareup.okhttp.Response; 14 15 @Component 16 public class HystrixUtil { 17 18 @Autowired 19 private HyStrixProperties hp; 20 21 public Response execute(String hotelServiceName, 22 String hotelServiceMethodGetHotelInfo, 23 String url) throws InterruptedException, ExecutionException { 24 Setter setter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(hotelServiceName));//被調用服務 25 setter.andCommandKey(HystrixCommandKey.Factory.asKey(hotelServiceMethodGetHotelInfo));//被調用服務的一個被調用方法 26 setter.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(hp.getTimeoutInMillions())); 27 return new MyHystrixCommand(setter, url).execute();//同步執行 28 // Future<Response> future = new MyHystrixCommand(setter, url).queue();//異步執行 29 // return future.get();//需要時獲取 30 } 31 32 } View Code

說明:

  • hystrix的執行方式
    • 同步執行:超時時間起作用
    • 異步執行:超時時間不起作用(1.4.0之前的版本,在調用get()的時候開始計時起作用)
  • hystrix的隔離級別
    • HystrixCommandGroupKey:這個的名稱設置為一個被調用的服務,eg.hotelService,所有這個服務下的方法都用同一個線程池(前提是沒有配置ThreadPoolKey)
    • HystrixCommandKey:這個名稱通常是被調用服務的一個方法的名字(實際上就是被調用服務某一個controller中的一個對外方法),eg.getHotelInfo()
    • ThreadPoolKey:這個用的很少,除非一個被調用服務中的有些被調用方法快、有的被調用方法慢,這樣的話,就需要分別使用一個ThreadPoolKey,為每一個方法單獨分配線程池

6、application.properties

1 service.hotel.name = hotelService 2 service.hotel.method.getHotelInfo = getHotelInfo View Code

說明:定義被調用服務的服務名和被調用方法名,當然服務名也可以使用被調用服務的controller的簡單類名。

7、HystrixController

1 package com.xxx.firstboot.web; 2 3 import java.io.IOException; 4 import java.util.concurrent.ExecutionException; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Value; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestMethod; 10 import org.springframework.web.bind.annotation.RequestParam; 11 import org.springframework.web.bind.annotation.RestController; 12 13 import com.squareup.okhttp.Response; 14 import com.xxx.firstboot.hystrix.HystrixUtil; 15 16 @RestController 17 @RequestMapping("/hystrix") 18 public class HystrixController { 19 20 @Value("${service.hotel.url}") 21 private String HOTEL_URL; 22 23 @Value("${service.hotel.name}") 24 private String hotelServiceName; 25 26 @Value("${service.hotel.method.getHotelInfo}") 27 private String hotelServiceMethodGetHotelInfo; 28 29 @Autowired 30 private HystrixUtil hystrixUtil; 31 32 @RequestMapping(value = "/firstHystrix", method = RequestMethod.GET) 33 public String getHotelInfo(@RequestParam("id") int id, @RequestParam("name") String name) { 34 String url = String.format(HOTEL_URL, id, name); 35 Response response = null; 36 try { 37 response = hystrixUtil.execute(hotelServiceName, hotelServiceMethodGetHotelInfo, url); 38 if (response != null) { 39 return response.body().string(); 40 } 41 } catch (IOException e) { 42 e.printStackTrace(); 43 } catch (InterruptedException e) { 44 e.printStackTrace(); 45 } catch (ExecutionException e) { 46 e.printStackTrace(); 47 } finally { 48 if (response != null && response.body() != null) { 49 try { 50 response.body().close();// 資源關閉 51 } catch (IOException e) { 52 e.printStackTrace(); 53 } 54 } 55 } 56 return "獲取酒店信息失敗"; 57 } 58 59 } View Code

說明:

  • 使用@value做屬性注入,假設我們是在consul上配置了application.properties內容,當修改了屬性文件的內容後,該服務也必須重啟,因為@value只讀一次(沒測過,同事說的)
  • 使用spring的Environment進行注入,當修改了屬性文件的內容後,服務不需要重啟,會每五分鐘重新刷一次(沒測過,同事說的)
  • 使用boot構建一個屬性收集類,如上邊的HyStrixProperties類,不知道是否需要重啟(沒測過)

有測過的朋友和我講一下,我有時間也會測一下。

下邊是被調用服務的代碼:

8、HotelController

1 @RestController 2 @RequestMapping("/hotel") 3 @Api("HotelController相關api") 4 public class HotelController { 5 @ApiOperation("獲取酒店Hotel信息:getHotelInfo") 6 @RequestMapping(value="/getHotelInfo",method=RequestMethod.GET) 7 public Hotel getHotelInfo(@RequestParam("id") int id, @RequestParam("name") String name) { 8 // try { 9 // TimeUnit.MILLISECONDS.sleep(2000);//用於測試超時 10 // } catch (InterruptedException e) { 11 // e.printStackTrace(); 12 // } 13 return new Hotel(id, name); 14 } 15 } View Code

測試:啟動被調用服務-->啟動調用服務

 

參考:

http://blog.csdn.net/xiaoyu411502/article/details/50601687 官方的中文總結

https://stonetingxin.gitbooks.io/hystrix/content/ 基本上是官方的中文翻譯

https://github.com/Netflix/Hystrix/wiki/Configuration hystrix配置介紹

http://blog.vicoder.com/hystrix-configuration/ 配置介紹

http://www.insaneprogramming.be/blog/2014/08/19/hystrix-spring-boot/ boot集成hystrix

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved