1扒腕、 什么是熔斷
一般是某個服務(wù)故障或者是異常引起的擂达,類似現(xiàn)實世界中的‘保險絲’土铺,當(dāng)某個異常條件被觸發(fā),直接熔斷整個服務(wù)板鬓,而不是一直等到此服務(wù)超時悲敷,為了防止防止整個系統(tǒng)的故障,而采用了一些保護措施俭令。過載保護后德。
比如A服務(wù)的X功能依賴B服務(wù)的某個接口,當(dāng)B服務(wù)接口響應(yīng)很慢時唤蔗,A服務(wù)X功能的響應(yīng)也會被拖慢探遵,進一步導(dǎo)致了A服務(wù)的線程都卡在了X功能上,A服務(wù)的其它功能也會卡主或拖慢妓柜。此時就需要熔斷機制箱季,即A服務(wù)不在請求B這個接口,而可以直接進行降級處理棍掐。
2藏雏、 什么是降級
服務(wù)器當(dāng)壓力劇增的時候,根據(jù)當(dāng)前業(yè)務(wù)情況及流量作煌,對一些服務(wù)和頁面進行有策略的降級掘殴。以此緩解服務(wù)器資源的的壓力,以保證核心業(yè)務(wù)的正常運行粟誓,同時也保持了客戶和大部分客戶的得到正確的相應(yīng)奏寨。
3、熔斷和降級異同
相同點:
1.從可用性和可靠性觸發(fā)鹰服,為了防止系統(tǒng)崩潰
2.最終讓用戶體驗到的是某些功能暫時不能用
不同點:
1.服務(wù)熔斷一般是下游服務(wù)故障導(dǎo)致的病瞳,而服務(wù)降級一般是從整體系統(tǒng)負荷考慮,由調(diào)用方控制悲酷。
4套菜、Netflix開源組件斷路器Hystrix
文檔地址:
https://github.com/Netflix/Hystrix
為什么用Hystrix
在一個分布式系統(tǒng)里,一個服務(wù)依賴多個服務(wù)设易,可能存在某個服務(wù)調(diào)用失敗逗柴,比如超時、異常等顿肺,如何能夠保證在一個依賴出問題的情況下戏溺,不會導(dǎo)致整體服務(wù)失敗渣蜗,通過Hystrix就可以解決。
Hystrix是如何實現(xiàn)它的目標(biāo)的
(1)通過HystrixCommand或者HystrixObservableCommand來封裝對外部依賴的訪問請求于购,這個訪問請求一般會運行在獨立的線程中钓试,資源隔離
(2)對于超出我們設(shè)定閾值的服務(wù)調(diào)用芽卿,直接進行超時,不允許其耗費過長時間阻塞住鞠抑。這個超時時間默認是99.5%的訪問時間控淡,但是一般我們可以自己設(shè)置一下
(3)為每一個依賴服務(wù)維護一個獨立的線程池嫌吠,或者是semaphore,當(dāng)線程池已滿時掺炭,直接拒絕對這個服務(wù)的調(diào)用
(4)對依賴服務(wù)的調(diào)用的成功次數(shù)辫诅,失敗次數(shù),拒絕次數(shù)涧狮,超時次數(shù)炕矮,進行統(tǒng)計
(5)如果對一個依賴服務(wù)的調(diào)用失敗次數(shù)超過了一定的閾值,自動進行熔斷者冤,在一定時間內(nèi)對該服務(wù)的調(diào)用直接降級肤视,一段時間后再自動嘗試恢復(fù)
(6)當(dāng)一個服務(wù)調(diào)用出現(xiàn)失敗,被拒絕涉枫,超時邢滑,短路等異常情況時,自動調(diào)用fallback降級機制
(7)對屬性和配置的修改提供近實時的支持
5愿汰、Hystrix實戰(zhàn)
使用到的組件包括:Eureka困后、Feign包括以下三個項目:
(1)Eureka-server: 注冊中心
(2)product-service :商品微服務(wù)
(3)order-service: 訂單微服務(wù)
前面文章已經(jīng)搭建過 這里不做贅述 這里只寫order-service微服務(wù)
pom.xml 添加依賴
<!--hystrix依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
application.yml
server:
port: 8781
#指定注冊中心地址
eureka:
client:
serviceUrl:
defaultZone: http://localhost:7001/eureka/
#服務(wù)的名稱
spring:
application:
name: order-service
#開啟feign支持hystrix (注意,一定要開啟衬廷,舊版本默認支持摇予,新版本默認關(guān)閉)
# #修改調(diào)用超時時間(默認是1秒就算超時)
feign:
hystrix:
enabled: true
client:
config:
default:
connectTimeout: 2000
readTimeout: 2000
#hystrix超時時間調(diào)整(默認是一秒)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000
SpringBoot啟動類
@SpringBootApplication
@EnableFeignClients
//添加熔斷降級注解
@EnableCircuitBreaker
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
ProductClient
/**
* 商品服務(wù)客戶端
* name = "product-service"是你調(diào)用服務(wù)端名稱
* fallback = ProductClientFallback.class,后面是你自定義的降級處理類吗跋,降級類一定要實現(xiàn)ProductClient
*/
@FeignClient(name = "product-service",fallback = ProductClientFallback.class)
public interface ProductClient {
//這樣組合就相當(dāng)于http://product-service/api/v1/product/find
@GetMapping("/api/v1/product/find")
String findById(@RequestParam(value = "id") int id);
}
ProductClientFallback降級處理類
/**
* 針對商品服務(wù)侧戴,錯降級處理
*/
@Component
public class ProductClientFallback implements ProductClient {
@Override
public String findById(int id) {
System.out.println("ProductClientFallback中的降級方法");
//這對gai該接口進行一些邏輯降級處理........
return null;
}
}
OrderController類
注意:fallbackMethod = "saveOrderFail"中的saveOrderFail方法中的參數(shù)類型,個數(shù)小腊,順序要和save一模一樣救鲤,否則會報找不到saveOrderFail方法。
@RestController
@RequestMapping("api/v1/order")
public class OrderController {
@Autowired
private ProductOrderService productOrderService;
@RequestMapping("save")
//當(dāng)調(diào)用微服務(wù)出現(xiàn)異常會降級到saveOrderFail方法中
@HystrixCommand(fallbackMethod = "saveOrderFail")
public Object save(@RequestParam("user_id")int userId, @RequestParam("product_id") int productId){
return productOrderService.save(userId, productId);
}
//注意秩冈,方法簽名一定要要和api方法一致
private Object saveOrderFail(int userId, int productId){
System.out.println("controller中的降級方法");
Map<String, Object> msg = new HashMap<>();
msg.put("code", -1);
msg.put("msg", "搶購人數(shù)太多本缠,您被擠出來了,稍等重試");
return msg;
}
}
測試
異常情況
6楣黍、結(jié)合redis模擬熔斷降級服務(wù)異常報警通知實戰(zhàn)
主要是完善服務(wù)熔斷處理匾灶,報警機制完善結(jié)合redis進行模擬短信通知用戶下單失敗。
pom.xml
<!--springboot整合redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.yml
#redis
spring:
application:
name: order-service
redis:
database: 0
host: 127.0.0.1
port: 6379
timeout: 2000
OrderController類
主要看降級方法的不同
@RestController
@RequestMapping("api/v1/order")
public class OrderController {
@Autowired
private ProductOrderService productOrderService;
//添加bean
@Autowired
private StringRedisTemplate redisTemplate;
@RequestMapping("save")
//當(dāng)調(diào)用微服務(wù)出現(xiàn)異常會降級到saveOrderFail方法中
@HystrixCommand(fallbackMethod = "saveOrderFail")
public Object save(@RequestParam("user_id")int userId, @RequestParam("product_id") int productId,HttpServletRequest request){
return productOrderService.save(userId, productId);
}
//注意租漂,方法簽名一定要要和api方法一致
private Object saveOrderFail(int userId, int productId, HttpServletRequest request){
//監(jiān)控報警
String saveOrderKye = "save-order";
//有數(shù)據(jù)代表20秒內(nèi)已經(jīng)發(fā)過
String sendValue = redisTemplate.opsForValue().get(saveOrderKye);
final String ip = request.getRemoteAddr();
//新啟動一個線程進行業(yè)務(wù)邏輯處理
new Thread( ()->{
if (StringUtils.isBlank(sendValue)) {
System.out.println("緊急短信阶女,用戶下單失敗,請離開查找原因,ip地址是="+ip);
//發(fā)送一個http請求哩治,調(diào)用短信服務(wù) TODO
redisTemplate.opsForValue().set(saveOrderKye, "save-order-fail", 20, TimeUnit.SECONDS);
}else{
System.out.println("已經(jīng)發(fā)送過短信秃踩,20秒內(nèi)不重復(fù)發(fā)送");
}
}).start();
Map<String, Object> msg = new HashMap<>();
msg.put("code", -1);
msg.put("msg", "搶購人數(shù)太多,您被擠出來了业筏,稍等重試");
return msg;
}
}
測試
7、 Dashboard儀表盤監(jiān)控
1蒜胖、加入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2消别、啟動類增加注解
@EnableHystrixDashboard
3、配置文件增加endpoint
#新版本默認不暴露端點 改成暴露全部端點
management:
endpoints:
web:
exposure:
include: "*"
4台谢、訪問入口
http://localhost:8781/hystrix
Hystrix Dashboard輸入: http://localhost:8781/actuator/hystrix.stream