本文章是在網(wǎng)易云課堂的課程學(xué)習(xí)中編寫,部分圖片從網(wǎng)易云課堂ppt引用
一、微服務(wù)請求情況
1、請求處理情況
【請求處理】一個請求可能有多個微服務(wù)協(xié)同處理(相互依賴)
【服務(wù)超時】服務(wù)可能超時、網(wǎng)絡(luò)不通,導(dǎo)致調(diào)用者出現(xiàn)阻塞
【系統(tǒng)雪崩】請求一旦大量阻塞,會占用大量資源,可能導(dǎo)致整個系統(tǒng)雪崩
2、構(gòu)建彈性應(yīng)用
【服務(wù)限流】服務(wù)消費(fèi)者限制自身對某一服務(wù)能發(fā)起的并發(fā)請求數(shù)量,超過數(shù)量則不調(diào)用或等一段時間后再調(diào)用
【服務(wù)熔斷】熔斷狀態(tài)下,服務(wù)消費(fèi)者不會發(fā)起對某一服務(wù)的調(diào)用
【服務(wù)降級】請求異常情況下,程序執(zhí)行指定的降級策略(可類比try-catch)
3、spring cloud提供的hystrix
若服務(wù)出現(xiàn)超時或其他錯誤,可以使用【hystrix】來處理
二、集成Hystrix
在《分布式系統(tǒng)開發(fā)技術(shù) | Eureka》中代碼的基礎(chǔ)上,對 【服務(wù)消費(fèi)者】進(jìn)行改造
1. maven引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2. 代碼示例
創(chuàng)建一個類CustomerCommand,繼承HystrixCommand,重寫fallback方法
import com.netflix.hystrix.*;
import org.springframework.web.client.RestTemplate;
/**
* 繼承HystrixCommand,重寫fallback方法
*/
public class CustomerCommand extends HystrixCommand<Object> {
private RestTemplate restTemplate;
/**
* 重寫構(gòu)造方法,傳入我們需要的參數(shù)
* @param restTemplate
*/
public CustomerCommand(RestTemplate restTemplate) {
super(
Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("study-hystrix")) //設(shè)置命令分組名
.andCommandKey(HystrixCommandKey.Factory.asKey("CustomerController")) //設(shè)置命令名,誰發(fā)起請求的設(shè)置成誰
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("studyThreadPool")) //設(shè)置線程池名
//設(shè)置熔斷的參數(shù)
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(100) //超時時間:100毫秒
.withCircuitBreakerSleepWindowInMilliseconds(5000)) //熔斷時長:5秒
//設(shè)置線程池參數(shù)
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
.withCoreSize(1) //線程池大小
.withMaxQueueSize(2)) //線程池倉庫大小
);
this.restTemplate = restTemplate;
}
/**
* 實現(xiàn)run方法
* @return
* @throws Exception
*/
@Override
protected Object run() throws Exception {
//核心實現(xiàn),調(diào)用我們期望調(diào)用的方法
System.out.println("當(dāng)前線程是: "+Thread.currentThread().getName());
Object result = restTemplate.getForObject("http://helloserver",String.class,"");
return result;
}
/**
* 降級方法
* @return
*/
@Override
protected Object getFallback() {
//核心方法,降級之后會實現(xiàn)這個
System.out.println("降級啦。。。");
return "降級了,返回降級";
}
}
改造CustomerController類中的發(fā)送請求方法,通過CustomerCommand類去代理相關(guān)請求
@RestController
public class CustomerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
LoadBalancerClient loadBalancerClient;
@GetMapping("index")
public Object getIndex(){
return new CustomerCommand(restTemplate).execute();
}
}
這里可以看到,這種請求方式也可以收到應(yīng)答
我們來嘗試讓某個服務(wù)提供者模擬宕機(jī)情況:
@SpringBootApplication
@EnableEurekaClient
@RestController
public class HelloDemoPeer1Application {
public static void main(String[] args) {
SpringApplication.run(HelloDemoPeer1Application.class, args);
}
@GetMapping("")
public Object index() throws InterruptedException {
Random random = new Random();
int timeOut = random.nextInt(150);
System.out.println("當(dāng)前線程休眠時間是:"+timeOut);
Thread.sleep(timeOut);
String str = "這是服務(wù)端1返回的應(yīng)答";
return new String(str);
}
}
hystrix設(shè)置的超時時間是100毫秒,若休眠時間大于100毫秒,則執(zhí)行fallback