SpringCloud之Hystrix的詳細(xì)使用
1.概念
服務(wù)降級(jí):服務(wù)器繁忙,請(qǐng)稍后再試,不讓客戶端等待,并立即返回一個(gè)友好的提示(一般發(fā)生在 程序異常,超時(shí),服務(wù)熔斷觸發(fā)服務(wù)降級(jí),線程池、信號(hào)量 打滿也會(huì)導(dǎo)致服務(wù)降級(jí))
服務(wù)熔斷 : 達(dá)到最大服務(wù)訪問(wèn)后,直接拒絕訪問(wèn),然后調(diào)用服務(wù)降級(jí)的方法并返回友好提示(如保險(xiǎn)絲一樣)
服務(wù)限流 : 秒殺等高并發(fā)操作,嚴(yán)禁一窩蜂的過(guò)來(lái)?yè)頂D,排隊(duì)進(jìn)入,一秒鐘N個(gè),有序進(jìn)行
***一.服務(wù)降級(jí)***
2.不使用Hystrix的項(xiàng)目
大致的Service和Controller層如下
***************Controller*****************
package com.sky.springcloud.controller;
import com.sky.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@Slf4j
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverport;
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_Ok(@PathVariable("id") Integer id){
String result = paymentService.paymentInfo_ok(id);
log.info("*****"+ result);
return result;
}
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
String result = paymentService.payment_Info_TimeOut(id);
}
*******************Service********************
package com.sky.springcloud.service;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class PaymentServiceImpl implements PaymentService{
@Override
public String paymentInfo_ok(Integer id) {
return "線程池:" + Thread.currentThread().getName() + "paymentInfo_Ok. id:" + id + "\t" + "~~~~~";
public String payment_Info_TimeOut(Integer id) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "線程池:" + Thread.currentThread().getName() + "paymentInfo_TimeOut. id:" + id + "\t" + "~~~~~";在這種情況時(shí),當(dāng)通過(guò)瀏覽器訪問(wèn) TimeOut這個(gè)方法,會(huì)三秒后返回結(jié)果,而當(dāng)訪問(wèn) OK 這個(gè)方法時(shí),會(huì)直接返回結(jié)果(但是這是在訪問(wèn)量很少的時(shí)候,一旦訪問(wèn)量過(guò)多,訪問(wèn)OK時(shí)也會(huì)出現(xiàn)延遲,這里可以使用Jmeter模擬兩萬(wàn)個(gè)訪問(wèn)量,如下)


使用 Jmeter 模擬后,再去訪問(wèn)OK,會(huì)明顯出現(xiàn)加載的效果
3. 使用Hystrix
在主啟動(dòng)類添加注解
@EnableHystrix
package com.sky.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@SpringBootApplication
@EnableEurekaClient //啟用Eureka
@EnableHystrix //啟用Hystrix
public class Payment8001 {
public static void main(String[] args) {
SpringApplication.run(Payment8001.class,args);
}
}在原有的基礎(chǔ)上,在Service層加上如下注解
@HystrixCommand(fallbackMethod = "payment_Info_TimeOutHandler",//當(dāng)服務(wù)降級(jí)時(shí),調(diào)用payment_Info_TimeOutHandler方法
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",
value = "3000")//設(shè)置時(shí)間為3秒,超過(guò)三秒就為時(shí)間超限*****************改后的Service*******************
package com.sky.springcloud.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class PaymentServiceImpl implements PaymentService{
@Override
public String paymentInfo_ok(Integer id) {
return "線程池:" + Thread.currentThread().getName() + "paymentInfo_Ok. id:" + id + "\t" + "~~~~~";
}
@HystrixCommand(fallbackMethod = "payment_Info_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
})
public String payment_Info_TimeOut(Integer id) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
// int a = 10 / 0;
return "線程池:" + Thread.currentThread().getName() + "paymentInfo_TimeOut. id:" + id + "\t" + "~~~~~";
}
public String payment_Info_TimeOutHandler(Integer id){
return "線程超時(shí)或異常 " + Thread.currentThread().getName();
}
}如上Service所示,如果再次訪問(wèn)TimeOut需要等待五秒,但是Hystrix設(shè)置的超時(shí)時(shí)間為三秒,所以當(dāng)三秒后沒(méi)有結(jié)果就會(huì)服務(wù)降級(jí),從而調(diào)用TimeOutHandler這個(gè)指定 的方法來(lái)執(zhí)行(或者有程序出錯(cuò)等情況也會(huì)服務(wù)降級(jí))
4. 全局的Hystrix配置
@DefaultProperties(defaultFallback = “Gloub_Test”)
package com.sky.springcloud.service;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
@Service
@DefaultProperties(defaultFallback = "Gloub_Test")
public class PaymentServiceImpl implements PaymentService{
@Override
@HystrixCommand
public String paymentInfo_ok(Integer id) {
int a = 10 / 0;
return "線程池:" + Thread.currentThread().getName() + "paymentInfo_Ok. id:" + id + "\t" + "~~~~~";
}
@HystrixCommand(fallbackMethod = "payment_Info_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
})
public String payment_Info_TimeOut(Integer id) {
/* try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
return "線程池:" + Thread.currentThread().getName() + "paymentInfo_TimeOut. id:" + id + "\t" + "~~~~~";
public String payment_Info_TimeOutHandler(Integer id){
return "線程超時(shí)或異常 " + Thread.currentThread().getName();
public String Gloub_Test(){
return "走了全局的";
}如上Service所示,加了@HystrixCommand的方法里,
如果沒(méi)指定fallbackMethod 就會(huì)默認(rèn)去找全局的defaultFallback
這里 當(dāng)paymentInfo_ok 方法出錯(cuò)時(shí),會(huì)調(diào)用Gloub_Test方法
當(dāng)payment_Info_TimeOut出錯(cuò)時(shí),會(huì)調(diào)用payment_Info_TimeOutHandler方法
***二.服務(wù)熔斷***
1.熔斷機(jī)制概述
熔斷機(jī)制是應(yīng)對(duì)雪崩效應(yīng)的一種微服務(wù)鏈路保護(hù)機(jī)制,當(dāng)扇出鏈路的某個(gè)微服務(wù)出錯(cuò)不可用或者響應(yīng)時(shí)間太長(zhǎng),會(huì)進(jìn)行服務(wù)的降級(jí),進(jìn)而熔斷該節(jié)點(diǎn)微服務(wù)的調(diào)用,快速返回錯(cuò)誤的相應(yīng)信息.當(dāng)檢測(cè)到該節(jié)點(diǎn)微服務(wù)調(diào)用相應(yīng)正常后,恢復(fù)調(diào)用鏈路.
2.項(xiàng)目中使用
在上面的基礎(chǔ)上,改寫(xiě)Service和Controller(添加以下代碼)
//是否開(kāi)啟服務(wù)熔斷(斷路器)
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
//服務(wù)請(qǐng)求的次數(shù)
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
//時(shí)間的窗口期
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
//當(dāng)失敗率達(dá)到多少后發(fā)生熔斷
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),
******************Service*****************
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",
commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),
})
public String PaymentCircuitBreaker(@PathVariable("id") Integer id){
if(id<0){
throw new RuntimeException("********** id不能為負(fù)");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName() + "\t" + serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
return "id 不能為負(fù):" + id;
************Controller********************
@GetMapping("/payment/circuit/{id}")
String result = paymentService.PaymentCircuitBreaker(id);
log.info(result + "***********");
return result;如上所示,當(dāng)訪問(wèn)paymentCircuitBreaker時(shí),如果id小于零則會(huì)有一個(gè)運(yùn)行錯(cuò)誤,這時(shí)候就會(huì)通過(guò)服務(wù)降級(jí)來(lái)調(diào)用paymentCircuitBreaker_fallback方法,當(dāng)錯(cuò)誤的次數(shù)達(dá)到60%的時(shí)候(自己設(shè)的),就會(huì)出現(xiàn)服務(wù)熔斷,這個(gè)時(shí)候再訪問(wèn)id大于零的情況,也會(huì)發(fā)生服務(wù)降級(jí),因?yàn)殚_(kāi)起了服務(wù)熔斷,需要慢慢的恢復(fù)正常.
到此這篇關(guān)于SpringCloud之Hystrix的詳細(xì)使用的文章就介紹到這了,更多相關(guān)SpringCloud Hystrix使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket
這篇文章主要介紹了Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket的相關(guān)資料,需要的朋友可以參考下2017-05-05
Java二維數(shù)組與動(dòng)態(tài)數(shù)組ArrayList類詳解
這篇文章主要給大家介紹了關(guān)于Java二維數(shù)組與動(dòng)態(tài)數(shù)組ArrayList類的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
SpringBoot Scheduling定時(shí)任務(wù)的示例代碼
springBoot提供了定時(shí)任務(wù)的支持,通過(guò)注解簡(jiǎn)單快捷,對(duì)于日常定時(shí)任務(wù)可以使用。本文詳細(xì)的介紹一下使用,感興趣的可以了解一下2021-08-08
淺談SpringCloud?Alibaba和SpringCloud的區(qū)別
這篇文章主要介紹了淺談SpringCloud?Alibaba和SpringCloud的區(qū)別,Spring?Cloud?Netflix框架也屬于Spring?Cloud,但是Netflix并不是由spring來(lái)進(jìn)行開(kāi)發(fā)的,需要的朋友可以參考下2023-05-05
Java實(shí)現(xiàn)合并兩個(gè)有序序列算法示例
這篇文章主要介紹了Java實(shí)現(xiàn)合并兩個(gè)有序序列算法,簡(jiǎn)單描述了序列合并算法的原理與java合并有序序列的具體操作步驟及相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-09-09
IDEA引MAVEN項(xiàng)目jar包依賴導(dǎo)入問(wèn)題解決方法
這篇文章主要介紹了IDEA引MAVEN項(xiàng)目jar包依賴導(dǎo)入問(wèn)題解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
java實(shí)現(xiàn)簡(jiǎn)單的猜數(shù)字小游戲
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03

