瘋狂Spring Cloud連載(15)第一個Hystrix程序

本文節選自《瘋狂Spring Cloud微服務架構實戰》html

京東購買地址:https://item.jd.com/12256011.htmljava

噹噹網購買地址:http://product.dangdang.com/25201393.htmlgit

Spring Cloud教學視頻:https://my.oschina.net/JavaLaw/blog/1552993web

Spring Cloud電子書:https://my.oschina.net/JavaLaw/blog/1570383spring

第一個Hystrix程序

        先編寫一個簡單的Hello World程序,展現Hystrix的基本做用。前面的章節會單獨講解Hystrix框架,後面章節纔會整合Spring Cloud一塊兒使用。apache

準備工做

        使用Spring Boot的spring-boot-starter-web項目,創建一個普通的Web項目,發佈兩個測試服務用於測試,控制器的代碼請見代碼清單6-1。網絡

        代碼清單6-1:架構

        codes\06\6.2\first-hystrix-server\src\main\java\org\crazyit\cloud\MyController.javaapp

@RestController
public class MyController {

	@GetMapping("/normalHello")
	public String normalHello(HttpServletRequest request) {
		return "Hello World";
	}
	
	@GetMapping("/errorHello")	
	public String errorHello(HttpServletRequest request) throws Exception {
		// 模擬須要處理10秒
		Thread.sleep(10000);
		return "Error Hello World";
	}
}

        一個正常的服務,另一個服務則須要等待10秒纔有返回。本例的Web項目對應的代碼目錄爲codes\06\6.2\first-hystrix-server,啓動類是ServerApplication。框架

客戶端使用Hystrix

        結合Hystrix來請求Web服務,可能與原來的方式不太同樣。新建項目「first-hystrix-client」,在pom.xml中加入如下依賴:

<dependency>
			<groupId>com.netflix.hystrix</groupId>
			<artifactId>hystrix-core</artifactId>
			<version>1.5.12</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<version>1.7.25</version>
			<artifactId>slf4j-log4j12</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.2</version>
		</dependency>

        本書Spring Cloud所使用的Hystrix版本爲1.5.12,咱們也使用與其一致的版本。客戶端項目除了要使用Hystrix外,還會使用HttpClient模塊訪問Web服務,所以要加入相應的依賴。新建一個命令類,實現請見代碼清單6-2。

        代碼清單6-2:

        codes\06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\HelloCommand.java

public class HelloCommand extends HystrixCommand<String> {

	private String url;
	
	CloseableHttpClient httpclient;
	
	public HelloCommand(String url) {
		// 調用父類的構造器,設置命令組的key,默認用來做爲線程池的key
		super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
		// 建立HttpClient客戶端
		this.httpclient = HttpClients.createDefault();
		this.url = url;
	}
	
	protected String run() throws Exception {
		try {
			// 調用 GET 方法請求服務
			HttpGet httpget = new HttpGet(url);
			// 獲得服務響應
			HttpResponse response = httpclient.execute(httpget);
			// 解析並返回命令執行結果
			return EntityUtils.toString(response.getEntity());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
}

        新建運行類,執行HelloCommand,如代碼清單6-3所示。

        代碼清單6-3:

        codes\06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\HelloMain.java

public class HelloMain {

	public static void main(String[] args) {
		// 請求正常的服務
		String normalUrl = "http://localhost:8080/normalHello";
		HelloCommand command = new HelloCommand(normalUrl);
		String result = command.execute();
		System.out.println("請求正常的服務,結果:" + result);
	}
}

        正常狀況下,直接調用HttpClient的API來請求Web服務,而前面的命令類與運行類,則經過命令來執行調用的工做。在命令類HelloCommand中,實現了父類的run方法,使用HttpClient調用服務的過程,都放到了該方法中。運行HelloMain類,能夠看到,結果與日常調用Web服務無異。接下來,測試使用Hystrix的狀況下調用有問題的服務。

調用錯誤服務

        假設咱們所調用的Hello服務發生故障,致使沒法正常訪問,那麼對於客戶端來講,如何自保呢?本例將調用延時的服務,爲客戶端設置回退方法。修改HelloCommand類,加入回退方法,請見代碼清單6-4。

        代碼清單6-4:

        codes\06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\HelloCommand.java

protected String getFallback() {
		System.out.println("執行 HelloCommand 的回退方法");
		return "error";
	}

        在運行類中,調用發生故障的服務,請見代碼清單6-5。

        代碼清單6-5:

        codes\06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\HelloErrorMain.java

public class HelloErrorMain {

	public static void main(String[] args) {
		// 請求異常的服務
		String normalUrl = "http://localhost:8080/errorHello";
		HelloCommand command = new HelloCommand(normalUrl);
		String result = command.execute();
		System.out.println("請求異常的服務,結果:" + result);
	}
}

        運行HelloErrorMain類,輸出以下:

執行 HelloCommand 的回退方法
請求異常的服務,結果:error

        根據結果可知,回退方法被執行。本例中調用的「errorHello」服務,會阻塞10秒纔有返回。默認狀況下,若是調用的Web服務沒法在1秒內完成,那麼將會觸發回退。

        回退更像是一個備胎,當請求的服務沒法正常返回時,就調用該「備胎」的實現。這樣作,能夠很好的保護客戶端,服務端所提供的服務受網絡等條件的制約,若是有服務真的須要10秒才能返回結果,而客戶端又沒有容錯機制,後果就是,客戶端將一直等待返回,直到網絡超時或者服務有響應,而外界會一直不停地發送請求給客戶端,最終致使的結果就是,客戶端因請求過多而癱瘓。

        本文節選自《瘋狂Spring Cloud微服務架構實戰》

        Spring Cloud教學視頻:https://my.oschina.net/JavaLaw/blog/1552993

Spring Cloud電子書:https://my.oschina.net/JavaLaw/blog/1570383

本書代碼共享地址:https://gitee.com/yangenxiong/SpringCloud

相關文章
相關標籤/搜索